@atlasent/sdk 2.12.0 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/dist/hono.cjs +42 -0
- package/dist/hono.cjs.map +1 -1
- package/dist/hono.d.cts +2 -2
- package/dist/hono.d.ts +2 -2
- package/dist/hono.js +42 -0
- package/dist/hono.js.map +1 -1
- package/dist/index.cjs +42 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -3
- package/dist/index.d.ts +36 -3
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -1
- package/dist/{protect-B6w-WQMB.d.cts → protect-Bk9q12ia.d.cts} +75 -1
- package/dist/{protect-B6w-WQMB.d.ts → protect-Bk9q12ia.d.ts} +75 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/trustRoot.ts","../src/types.ts","../src/compat.ts","../src/retry.ts","../src/scim.ts","../src/evidence-bundle.ts","../src/auth.ts","../src/sso.ts","../src/access-governance-log.ts","../src/client.ts","../src/auditBundle.ts","../src/evidenceEngine.ts","../src/protect.ts","../src/requirePermit.ts","../src/withPermit.ts","../src/approvalRuntime.ts","../src/actionContext.ts","../src/verticals/deployGate.ts","../src/verticals/closeGovernance.ts","../src/verticals/paymentRelease.ts","../src/verticals/dataExport.ts","../src/shadow.ts","../src/verticals/agentTools.ts","../src/verticals/gxpActions.ts","../src/verticals/paymentOperations.ts","../src/verticals/deploymentActions.ts","../src/verticals/behaviorEvents.ts","../src/verticals/infraActions.ts","../src/verticals/hrActions.ts","../src/verticals/modelGovernance.ts","../src/verticals/dataDelete.ts","../src/verticals/contractActions.ts","../src/verticals/pricingActions.ts","../src/verticals/securityActions.ts","../src/verticals/accessCert.ts","../src/verticals/financialClose.ts","../src/verticals/databaseActions.ts","../src/replay.ts","../src/hitl.ts","../src/sandboxDiff.ts","../src/delegationPropagation.ts","../src/contextEnvelope.ts","../src/trust.ts","../src/financialAction.ts","../src/liabilityAttribution.ts","../src/economicRisk.ts","../src/financialQuorum.ts","../src/budgetaryGovernance.ts","../src/autonomousFinancial.ts","../src/incentiveAlignment.ts","../src/economicEvidence.ts","../src/disputeReversal.ts","../src/financialDashboard.ts","../src/governanceEnforcement.ts","../src/governanceWebhooks.ts","../src/complianceEvidence.ts","../src/policySync.ts","../src/webhook.ts","../src/crossOrgPermission.ts","../src/anomalyResponse.ts","../src/budgetExceptions.ts","../src/regulatoryEscalation.ts","../src/incentiveSignalFeedback.ts","../src/crossOrgImpersonation.ts","../src/v2.ts","../src/runtime_v2.ts","../src/controlSurface.ts","../src/claimLineage.ts","../src/bccae.ts","../src/governanceAgents.ts","../src/vqp.ts"],"sourcesContent":["/**\n * @atlasent/sdk — execution-time authorization for AI agents.\n *\n * The canonical execution-boundary surface is two forms of the same\n * contract. Both mint and verify a Permit end-to-end; both fail closed.\n * Pick the form that fits the call site.\n *\n * `protect` — the primitive. Returns the verified {@link Permit} so\n * the caller can pass it across a boundary, persist it alongside\n * their own record, or interleave it with non-trivial control flow:\n *\n * ```ts\n * import atlasent from \"@atlasent/sdk\";\n *\n * const permit = await atlasent.protect({\n * agent: \"deploy-bot\",\n * action: \"production.deploy\",\n * context: { commit, approver },\n * });\n * // permit is verified end-to-end. Execute the action.\n * ```\n *\n * `withPermit` — the lexically-scoped form. Binds the action body to\n * the permit's lifetime via a callback so the call site reads as\n * \"execute this body under a permit\":\n *\n * ```ts\n * const result = await atlasent.withPermit(\n * { agent: \"deploy-bot\", action: \"production.deploy\",\n * context: { commit, approver } },\n * async (permit) => runDeploy(commit, { permitId: permit.permitId }),\n * );\n * ```\n *\n * `requirePermit` — descriptor form for dangerous operations carrying\n * `resource_id` + `environment`. The executor only runs when AtlaSent\n * authorizes it end-to-end:\n *\n * ```ts\n * await atlasent.requirePermit(\n * { action_type: \"database.table.drop\", actor_id: \"agent:code-agent\",\n * resource_id: \"prod-db.users\", environment: \"production\",\n * context: { reversibility: \"irreversible\" } },\n * async () => { await db.raw(\"DROP TABLE users\"); },\n * );\n * ```\n *\n * Named exports remain available for the lower-level\n * {@link AtlaSentClient} and the error taxonomy.\n */\n\nimport { AtlaSentClient } from \"./client.js\";\nimport { verifyBundle } from \"./auditBundle.js\";\nimport { AtlaSentDeniedError, AtlaSentError } from \"./errors.js\";\nimport { configure, deployGate, protect } from \"./protect.js\";\nimport { requirePermit, classifyCommand } from \"./requirePermit.js\";\nimport { withPermit } from \"./withPermit.js\";\nimport {\n DEPLOYMENT_PRODUCTION_ACTION,\n PRODUCTION_DEPLOY_ACTION,\n} from \"./types.js\";\nimport {\n protectPaymentRelease,\n protectDataExport,\n protectReconciliationCertify,\n protectToolCall,\n protectGxpAction,\n protectBatchRecordRelease,\n protectPaymentOperation,\n protectDeploymentV2,\n protectBehaviorEvent,\n protectInfraAction,\n protectHrOffboard,\n protectModelPromotion,\n protectCustomerDataDelete,\n protectContractExecution,\n protectPricingRule,\n protectSecurityIncidentEscalate,\n protectSecurityAccessQuarantine,\n protectAccessCertRevoke,\n protectPeriodCloseCertify,\n protectDatabaseMigration,\n protectDatabaseSchemaDrop,\n protectDatabaseTableDelete,\n} from \"./verticals/index.js\";\n\nexport { AtlaSentClient } from \"./client.js\";\nexport {\n DEPLOY_GATE_CODES,\n DEPLOYMENT_PRODUCTION_ACTION,\n PRODUCTION_DEPLOY_ACTION,\n} from \"./types.js\";\nexport {\n AtlaSentDeniedError,\n AtlaSentEscalateError,\n AtlaSentError,\n BundleVerificationError,\n PermitRevoked,\n StreamParseError,\n StreamTimeoutError,\n normalizePermitOutcome,\n type AtlaSentDecision,\n type AtlaSentDeniedErrorInit,\n type AtlaSentEscalateErrorInit,\n type AtlaSentErrorCode,\n type AtlaSentErrorInit,\n type PermitOutcome,\n} from \"./errors.js\";\nexport {\n configure,\n deployGate,\n protect,\n type ConfigureOptions,\n type Permit,\n type PermitWithEvidence,\n type ProtectRequest,\n type ProtectWithEvidenceOptions,\n protectWithEvidence,\n} from \"./protect.js\";\nexport {\n requirePermit,\n classifyCommand,\n CanonicalProtectedActionType,\n type ProtectedAction,\n} from \"./requirePermit.js\";\nexport { withPermit } from \"./withPermit.js\";\nexport type {\n ApiKeySelfResponse,\n AtlaSentClientOptions,\n BvsSnapshot,\n ConsentClassProjection,\n AuditEventsResult,\n AuditExportRequest,\n AuditExportResult,\n ConstraintTrace,\n ConstraintTracePolicy,\n ConstraintTraceStage,\n Decision,\n DecisionCanonical,\n DeployGateContext,\n DeployGateDenyCode,\n DeployGateEvidence,\n DeployGateRequest,\n DeployGateResponse,\n DeployOverrideClaim,\n DeployPermitClaim,\n BatchEvalItem,\n BatchEvalResponse,\n DecisionStreamEvent,\n EvaluateBatchResultItem,\n EvaluatePreflightResponse,\n SubscribeDecisionsOptions,\n CompletionProof,\n EvaluateRequest,\n EvaluateResponse,\n EvaluateResponsePermit,\n EvaluateRiskEnvelope,\n EvaluateRiskEnvelopeFactor,\n GetPermitResponse,\n ListPermitsRequest,\n ListPermitsResponse,\n PermitRecord,\n PermitStatus,\n PermitValidResponse,\n RateLimitState,\n RevokePermitByIdInput,\n RevokePermitByIdResponse,\n RevokePermitRequest,\n RevokePermitResponse,\n VerifyPermitByIdResponse,\n StreamDecisionEvent,\n StreamEvent,\n StreamOptions,\n StreamProgressEvent,\n VerifyPermitRequest,\n VerifyPermitResponse,\n} from \"./types.js\";\nexport {\n canonicalJSON,\n signedBytesFor,\n verifyAuditBundle,\n verifyBundle,\n type AuditBundle,\n type BundleVerificationResult,\n type VerifyBundleOptions,\n type VerifyKey,\n} from \"./auditBundle.js\";\nexport type {\n AuditDecision,\n AuditEvent,\n AuditEventsPage,\n AuditEventsQuery,\n AuditExport,\n AuditExportSignatureStatus,\n} from \"./audit.js\";\nexport type {\n EngineVersionKind,\n EnvelopeDriftDetail,\n EnvelopeVerification,\n ReplayDecisionResponse,\n ReplayDecisionValue,\n ReplayRequest,\n ReplayResponse,\n ReplayVarianceKind,\n EvidenceBundleVerifyResult,\n OfflineEvidenceBundleData,\n} from \"./replay.js\";\nexport {\n verifyEvidenceBundle,\n _computeEvidenceRootHash,\n} from \"./replay.js\";\nexport {\n DEFAULT_RETRY_POLICY,\n computeBackoffMs,\n hasAttemptsLeft,\n isRetryable,\n mergePolicy,\n type RetryPolicy,\n} from \"./retry.js\";\nexport {\n normalizeEvaluateRequest,\n normalizeEvaluateResponse,\n type LegacyEvaluateRequest,\n type LegacyEvaluateResponse,\n type V2EvaluateRequest,\n type V2EvaluateResponse,\n} from \"./compat.js\";\nexport {\n hitlRequiredApproverCount,\n type HitlAiUnavailableFallback,\n type HitlApprovalRecord,\n type HitlApproveRequest,\n type HitlApproverPoolEntry,\n type HitlApproverType,\n type HitlChainHop,\n type HitlCreateRequest,\n type HitlDetailResponse,\n type HitlEscalation,\n type HitlFallbackDecision,\n type HitlHeterogeneousQuorumExtension,\n type HitlHeterogeneousQuorumTally,\n type HitlListResponse,\n type HitlQuorumProgress,\n type HitlQuorumTier,\n type HitlRejectRequest,\n type HitlRespondRequest,\n type HitlStatus,\n type ListHitlEscalationsRequest,\n type ListHitlEscalationsResponse,\n} from \"./hitl.js\";\nexport {\n isSandboxDiffPopulated,\n type SandboxDiff,\n type SandboxDiffEmpty,\n type SandboxDiffPerTable,\n type SandboxDiffResponse,\n type SandboxRunMode,\n type SandboxRunStatus,\n type SandboxRunWrite,\n type SandboxWriteOp,\n} from \"./sandboxDiff.js\";\nexport {\n delegationPropagationHadEffect,\n type DelegationPropagationSummary,\n} from \"./delegationPropagation.js\";\nexport type {\n ApprovalArtifactV1,\n ApprovalIssuer,\n ApprovalReference,\n ApprovalReviewer,\n PrincipalKind,\n} from \"./approvalArtifact.js\";\nexport type {\n IdentityAssertionBinding,\n IdentityAssertionV1,\n IdentityIssuer,\n IdentityIssuerKey,\n IdentitySubject,\n IdentityTrustedIssuersConfig,\n} from \"./identityAssertion.js\";\nexport type {\n ApprovalQuorumV1,\n QuorumIndependence,\n QuorumPolicy,\n QuorumProof,\n QuorumRoleRequirement,\n} from \"./approvalQuorum.js\";\n\n// ── Evidence engine ──────────────────────────────────────────────────────────────────────────────────────\nexport type {\n WhyStage,\n WhyPolicyEvaluation,\n WhyTrace,\n DecisionReceiptAlgorithm,\n DecisionReceiptPayload,\n DecisionReceipt,\n ComplianceControlCoverage,\n ActionEvidenceBundle,\n} from \"./evidenceEngine.js\";\nexport {\n buildWhyTrace,\n computeContextHash,\n buildDecisionReceiptPayload,\n signDecisionReceiptHmac,\n verifyDecisionReceiptHmac,\n computeBundleHash,\n soc2ControlCoverageForDecision,\n} from \"./evidenceEngine.js\";\n\n// ── Context Envelope ──────────────────────────────────────────────────────────────────────────────────────\nexport {\n CONTEXT_NAMESPACES,\n} from \"./contextEnvelope.js\";\nexport type {\n ContextEnvelope,\n ContextNamespaceEntry,\n ContextNamespaceKey,\n ContextSignal,\n RecordContextEnvelopeInput,\n} from \"./contextEnvelope.js\";\n\n// ── V1 Proof bundle ──────────────────────────────────────────────────────────────────────────────────────\nexport type {\n GovernanceEvent,\n PermitV1,\n} from \"./v1Types.js\";\nexport type {\n ProofEvaluationSummary,\n ProofPayload,\n ProofResponse,\n} from \"./proof.js\";\n\n// ── V1 Override types ────────────────────────────────────────────────────────────────────────────────────\nexport type {\n CreateOverrideRequest,\n OverrideEvent,\n OverrideEventsResponse,\n OverrideListResponse,\n OverrideStatus,\n OverrideEventType,\n OverrideV1,\n} from \"./overrides.js\";\nexport type {\n TrustRootSnapshot,\n TrustRootKey,\n TrustRootRevocationEntry,\n TrustRootManagerOptions,\n} from \"./trustRoot.js\";\nexport {\n TrustRootManager,\n getGlobalTrustRootManager,\n __setGlobalTrustRootManagerForTests,\n} from \"./trustRoot.js\";\nexport {\n bootstrapTrust,\n isKidRevoked,\n isTrustSnapshotExpired,\n DEFAULT_TRUST_TTL_MS,\n type JWK,\n type TrustSnapshot,\n} from \"./trust.js\";\n\n// ── Economic Governance & Liability Attribution ─────────────────────────────────────────────────────────────\nexport {\n DEFAULT_RISK_TIER_THRESHOLDS,\n classifyRiskTier,\n withinAutonomousCeiling,\n type CurrencyCode,\n type FinancialActionClass,\n type FinancialActionType,\n type FinancialExecutionRecord,\n type FinancialExecutionStatus,\n type FinancialRiskTier,\n type LiabilityClassification,\n type RiskTierThreshold,\n} from \"./financialAction.js\";\n\nexport {\n buildLiabilityChain,\n computeLiabilityWeights,\n findPrimaryLiabilityParties,\n validateLiabilityChain,\n type LiabilityAttributionInput,\n type LiabilityAttributionRecord,\n type LiabilityChainValidation,\n type LiabilityParty,\n type LiabilityPartyRole,\n type WeightDistribution,\n} from \"./liabilityAttribution.js\";\n\nexport {\n computeApprovalRiskScore,\n computeExposureScore,\n computeHHI,\n computeOverallRiskScore,\n computeOverrideScore,\n detectSelfApproval,\n hhiToConcentrationScore,\n scoreToRiskTier,\n type AnomalyType,\n type ApprovalConcentrationAnalysis,\n type ApproverBreakdown,\n type BudgetaryDriftAnalysis,\n type ConcentrationAlert,\n type ExecutionAnomaly,\n type FinancialRiskScore,\n type RiskFactor,\n} from \"./economicRisk.js\";\n\nexport {\n computeEscalatedApprovalCount,\n evaluateFinancialQuorum,\n type AmountThreshold,\n type EmergencyFreeze,\n type FinancialQuorumInput,\n type FinancialQuorumPolicy,\n type FinancialQuorumResult,\n type FinancialRoleRequirement,\n} from \"./financialQuorum.js\";\n\nexport {\n budgetUtilizationSeverity,\n checkBudgetConstraints,\n type BudgetConstraintCheckResult,\n type BudgetLimit,\n type BudgetPolicy,\n type BudgetScope,\n type BudgetSpendingState,\n type BudgetViolation,\n type SpendingConstraint,\n} from \"./budgetaryGovernance.js\";\n\nexport {\n checkAutonomousBounds,\n detectAutonomousAnomaly,\n type AutonomousExecutionBounds,\n type AutonomousExecutionCheckResult,\n type AutonomousExecutionRecord,\n type ExecutionCeiling,\n} from \"./autonomousFinancial.js\";\n\nexport {\n DEFAULT_INCENTIVE_CONFIG,\n computeGovernanceHealthScore,\n detectMisalignedIncentives,\n type GovernanceBehaviorPattern,\n type IncentiveAlignmentConfig,\n type IncentiveSignal,\n type IncentiveSignalType,\n type MisalignmentAlert,\n} from \"./incentiveAlignment.js\";\n\nexport {\n buildSignableContent,\n canonicalizeForEvidence,\n serializeSignableContent,\n verifyEvidenceBundleStructure,\n type ApprovalProvenance,\n type EconomicEvidenceBundle,\n type EvidenceBundleSignableContent,\n type EvidenceBundleVerificationResult,\n type EvidencePurpose,\n} from \"./economicEvidence.js\";\n\nexport {\n computeRemediationUrgency,\n isFreezeActive,\n transitionDispute,\n transitionReversal,\n type ActionFreeze,\n type DisputeOrigin,\n type DisputeRecord,\n type DisputeStatus,\n type ReversalStage,\n type ReversalWorkflow,\n} from \"./disputeReversal.js\";\n\nexport {\n buildLiabilityVisualization,\n buildRiskTimeline,\n type ActionTypeOverrideStat,\n type ActorOverrideStat,\n type DisputeReversalSummary,\n type FinancialGovernanceSummary,\n type LiabilityEdge,\n type LiabilityNode,\n type LiabilityVisualization,\n type OverrideAnalytics,\n type RiskTimelinePoint,\n} from \"./financialDashboard.js\";\n\n// ── Governance enforcement layer ────────────────────────────────────────────────────────────────────────────────────────\nexport {\n GovernanceEnforcementError,\n enforceAutonomousBounds,\n enforceBudgetConstraint,\n enforceEconomicGovernance,\n enforceFinancialQuorum,\n type AutonomousBoundsDenyCode,\n type BudgetDenyCode,\n type FinancialQuorumDenyCode,\n type GovernanceEnforcementErrorInit,\n type GovernanceGate,\n} from \"./governanceEnforcement.js\";\n\n// ── Governance Webhooks, Compliance Evidence & Policy Sync ────────────────────────────────────────────\nexport {\n verifyWebhookSignature,\n type CreateWebhookSubscriptionRequest,\n type EnforcementWebhookEvent,\n type GovernanceWebhookEvent,\n type ListWebhookDeliveriesResponse,\n type ListWebhookSubscriptionsResponse,\n type WebhookDelivery,\n type WebhookDeliveryStatus,\n type WebhookPayload,\n type WebhookSubscription,\n} from \"./governanceWebhooks.js\";\n\nexport {\n evidenceRunPasses,\n nonPassingControls,\n type ComplianceEvidenceRun,\n type ComplianceEvidenceSummary,\n type ComplianceFramework,\n type ComplianceRunStatus,\n type EvidenceControl,\n type EvidenceControlStatus,\n type ListEvidenceRunsResponse,\n type SOC2ControlId,\n type TriggerEvidenceRunRequest,\n type TriggerEvidenceRunResponse,\n} from \"./complianceEvidence.js\";\n\nexport {\n formatPolicySyncDiff,\n isPolicySyncTerminal,\n type ApplyPolicySyncResponse,\n type ListPolicySyncRunsResponse,\n type PolicyBundleEntry,\n type PolicyRef,\n type PolicySyncDiff,\n type PolicySyncRun,\n type PolicySyncStatus,\n type SubmitPolicySyncRequest,\n type SubmitPolicySyncResponse,\n} from \"./policySync.js\";\n\nexport {\n assertWebhook,\n verifyWebhook,\n WebhookVerificationError,\n} from \"./webhook.js\";\n\n// ── Governance Graph & Incident Reconstruction ────────────────────────────────────────────────\nexport type {\n GovernanceGraphQueryType,\n GovernanceGraphQueryParams,\n GovernanceGraphQueryResponse,\n GovernanceGraphResultRow,\n GraphNodeType,\n GraphEdgeType,\n GraphNode,\n GraphEdge,\n ProductionDeployerRow,\n ExecutionApproverRow,\n QuorumBypassConnectorRow,\n EmergencyOverrideActionRow,\n ConnectedSystemRow,\n UserApprovalRow,\n ListGraphNodesResponse,\n ListGraphEdgesResponse,\n CreateGraphNodeInput,\n CreateGraphEdgeInput,\n} from \"./governanceGraph.js\";\n\nexport type {\n IncidentChainExecutionRow,\n IncidentChainActorEntry,\n IncidentChainEvidenceRow,\n IncidentTimelineResponse,\n} from \"./incidentReconstruction.js\";\n\n// ── Connector Management & Organizational Risk Graph ──────────────────────────────────────────────────────\nexport type {\n ConnectorType,\n ConnectorStatus,\n ConnectorRow,\n ConnectorCredentialType,\n ConnectorCredentialRow,\n EnforcementAction,\n EnforcementQuorumConfig,\n ConnectorEnforcementPolicy,\n ConnectorAuditLogEntry,\n ConnectorSyncState,\n ConnectorEnforcementEventInput,\n ConnectorEnforcementResult,\n InstallConnectorInput,\n AuthenticateConnectorInput,\n UpsertEnforcementPolicyInput,\n ListConnectorsResponse,\n InstallConnectorResponse,\n AuthenticateConnectorResponse,\n SyncConnectorResponse,\n RevokeConnectorResponse,\n RotateCredentialsResponse,\n ListEnforcementPoliciesResponse,\n UpsertEnforcementPolicyResponse,\n} from \"./connectorManagement.js\";\n\nexport type {\n OrgRiskLevel,\n OrgRiskScore,\n ComputeOrgRiskOptions,\n ComputeOrgRiskResponse,\n GetLatestOrgRiskResponse,\n ListOrgRiskHistoryResponse,\n} from \"./orgRiskGraph.js\";\n\n// ── Cross-Org Permission Negotiation ────────────────────────────────────────────────────────────────────────────\nexport {\n summarizeCrossOrgPermission,\n type CrossOrgPermissionCheckListParams,\n type CrossOrgPermissionCheckRequest,\n type CrossOrgPermissionCheckResult,\n type CrossOrgTrustHop,\n} from \"./crossOrgPermission.js\";\n\n// ── Anomaly Response Automation ─────────────────────────────────────────────────────────────────────────────────────\nexport {\n highestSeverityAction,\n matchAnomalyRules,\n type AnomalyActionType,\n type AnomalyResponseEvent,\n type AnomalyResponseRule,\n type CreateAnomalyResponseRuleRequest,\n type TriggerAnomalyResponseRequest,\n} from \"./anomalyResponse.js\";\n\n// ── Budget Exception Workflows ──────────────────────────────────────────────────────────────────────────────────────────\nexport {\n isBudgetExceptionActive,\n isBudgetExceptionTerminal,\n type ApproveBudgetExceptionRequest,\n type BudgetExceptionRequest,\n type BudgetExceptionStatus,\n type CreateBudgetExceptionRequest,\n} from \"./budgetExceptions.js\";\n\n// ── Regulatory Escalation Chain ────────────────────────────────────────────────────────────────────────────────────\nexport {\n isEscalationSlaBreached,\n isRegulatoryEscalationTerminal,\n type CreateRegulatoryEscalationRequest,\n type RegulatoryAuthorityLevel,\n type RegulatoryEscalation,\n type RegulatoryEscalationStatus,\n} from \"./regulatoryEscalation.js\";\n\n// ── Incentive Signal Feedback Loop ───────────────────────────────────────────────────────────────────────────────────────\nexport {\n computeSignalEngagementRate,\n isSubstantiveSignalResponse,\n type GovernanceSignalAction,\n type RecordSignalActionRequest,\n type RecordSignalOutcomeRequest,\n type SignalActionSummary,\n type SignalActionType,\n} from \"./incentiveSignalFeedback.js\";\n\n// ── Cross-Org Impersonation ──────────────────────────────────────────────────────────────────────────────────────────\nexport {\n clampTokenDuration,\n isImpersonationGrantUsable,\n type CreateImpersonationGrantRequest,\n type CrossOrgImpersonationGrant,\n type ImpersonationToken,\n type ImpersonationValidationResult,\n} from \"./crossOrgImpersonation.js\";\n\n// ── V2 Wave-A endpoints ──────────────────────────────────────────────────────────────────────────────────────────────────\nexport {\n FeatureNotEnabledError,\n V2_BATCH_PATH,\n V2_GRAPHQL_MAX_DEPTH,\n V2_GRAPHQL_PATH,\n V2_MAX_BATCH_ITEMS,\n V2_MAX_BODY_BYTES,\n V2_STREAM_PATH,\n authorizeStream,\n evaluateMany,\n graphql,\n type AuthorizeStreamHandlers,\n type EvaluateBatchItem,\n type EvaluateBatchResponse,\n type EvaluateManyRequest,\n type FeatureNotEnabledErrorInit,\n type GraphQLRequest,\n type GraphQLResponse,\n type StreamComplete,\n type StreamDecisionFrame,\n type StreamErrorFrame,\n type V2Feature,\n type V2Transport,\n} from \"./v2.js\";\n\n// ── Runtime v2 — four-plane lifecycle ─────────────────────────────────────────\nexport {\n RuntimeV2Client,\n type AuditChainFilters,\n type AuditChainPage,\n type AuthorizationDecision,\n type AuthorityRecord,\n type ChainIntegrityReport,\n type ComplianceExport,\n type ExecutionReceipt,\n type PostExecutionResult,\n type RuntimeAuditEntry,\n type VerificationFailure,\n type VerificationResult,\n} from \"./runtime_v2.js\";\n\n// ── Approval / Override Runtime ────────────────────────────────────────────────────────────────────────────────────\nexport {\n configureApprovalRuntime,\n createEscalation,\n EscalationDeniedError,\n EscalationTimeoutError,\n protectOrEscalate,\n requestOverride,\n waitForEscalationApproval,\n type ApprovalPermit,\n type ApprovalRuntimeConfig,\n type ApprovalStatus,\n type CreateEscalationOptions,\n type EscalationHandle,\n type EscalationOutcome,\n type ProtectOrEscalateOptions,\n type RequestOverrideOptions,\n type WaitForApprovalOptions,\n} from \"./approvalRuntime.js\";\n\n// ── Context Layer ───────────────────────────────────────────────────────────────────────────────────────────────────────\nexport {\n DEFAULT_REDACTION_RULES,\n buildActionContext,\n flattenActionContext,\n redactContext,\n validateActionContext,\n type ActionContext,\n type ActionMetaContext,\n type ActorContext,\n type BuildActionContextInput,\n type ContextValidationError,\n type ContextValidationResult,\n type ContextValidationWarning,\n type EnvironmentContext,\n type HistoricalContext,\n type RedactionMode,\n type RedactionRule,\n type ResourceContext,\n type ValidateContextOptions,\n} from \"./actionContext.js\";\n\n// ── Shadow Mode ──────────────────────────────────────────────────────────────────────────────────────────────────────────\nexport {\n configureShadow,\n protectShadow,\n reportShadowEvent,\n type ShadowConfig,\n type ShadowEventPayload,\n type ShadowMode,\n type ShadowOptions,\n type ShadowOutcome,\n} from \"./shadow.js\";\n\n// ── Enterprise Control Surface ────────────────────────────────────────────────────────────────────────────────────\nexport {\n checkIntegrationHealth,\n configureControlSurface,\n getEnforcementStatus,\n getOrgSummary,\n reportProtectedAction,\n type ControlSurfaceConfig,\n type EnforcementMode,\n type EnforcementStatus,\n type HealthReport,\n type GetEnforcementStatusOptions,\n type OrgSummary,\n type ProtectedActionEntry,\n type ReportProtectedActionOptions,\n} from \"./controlSurface.js\";\n\n// ── Pilot Verticals ────────────────────────────────────────────────────────────────────────────────────────────────────────\nexport {\n protectDeploy,\n type DeployGateOptions,\n type DeployEnvironment,\n protectCloseAction,\n protectReconciliationCertify,\n type CloseGovernanceOptions,\n type CloseActionType,\n type ReconciliationCertifyOptions,\n protectPaymentRelease,\n type PaymentReleaseOptions,\n VENDOR_PAYMENT_ACTION,\n protectDataExport,\n type DataExportOptions,\n CUSTOMER_DATA_EXPORT_ACTION,\n protectToolCall,\n classifyToolRisk,\n type AgentToolOptions,\n type AgentToolMode,\n protectGxpAction,\n protectBatchRecordRelease,\n type GxpActionType,\n type GxpActionOptions,\n type BatchRecordReleaseOptions,\n type ClinicalDataAccessOptions,\n type CAPAOptions,\n protectPaymentOperation,\n type PaymentOperationActionType,\n type PaymentOperationOptions,\n protectDeploymentV2,\n type DeploymentActionType,\n type DeploymentV2Options,\n DEPLOY_V1_ACTION,\n protectBehaviorEvent,\n type BehaviorEventCategory,\n type BehaviorEventOptions,\n BEHAVIOR_SENSITIVE_CATEGORIES,\n protectInfraAction,\n type InfraActionType,\n type InfraActionOptions,\n protectHrAction,\n protectHrOffboard,\n protectHrRoleEscalate,\n type HrActionType,\n type HrActionOptions,\n protectModelGovernance,\n protectModelPromotion,\n type ModelGovernanceActionType,\n type ModelGovernanceOptions,\n protectCustomerDataDelete,\n type DataDeleteActionType,\n type DataDeleteOptions,\n type GdprLegalBasis,\n protectContractAction,\n protectContractExecution,\n type ContractActionType,\n type ContractActionOptions,\n protectPricingAction,\n protectPricingRule,\n type PricingActionType,\n type PricingActionOptions,\n protectSecurityAction,\n protectSecurityIncidentEscalate,\n protectSecurityAccessQuarantine,\n type SecurityActionType,\n type SecurityActionOptions,\n protectAccessCertAction,\n protectAccessCertRevoke,\n type AccessCertActionType,\n type AccessCertOptions,\n protectFinancialCloseAction,\n protectPeriodCloseCertify,\n type FinancialCloseActionType,\n type FinancialCloseOptions,\n protectDatabaseAction,\n protectDatabaseMigration,\n protectDatabaseSchemaDrop,\n protectDatabaseTableDelete,\n type DatabaseMigrationActionType,\n type DatabaseDestructiveActionType,\n type DatabaseActionType,\n type PermitEvidence,\n type DenialEvidence,\n type DatabaseActionOptions,\n} from \"./verticals/index.js\";\n\n/**\n * Default export. The opinionated, category-defining entry point:\n *\n * ```ts\n * import atlasent from \"@atlasent/sdk\";\n * const permit = await atlasent.protect({ ... }); // primitive\n * await atlasent.withPermit({ ... }, async (permit) => …); // scoped form\n * await atlasent.requirePermit({ ... }, executor); // descriptor form\n * ```\n */\nconst atlasent = {\n protect,\n withPermit,\n deployGate,\n configure,\n requirePermit,\n classifyCommand,\n verifyBundle,\n PRODUCTION_DEPLOY_ACTION,\n DEPLOYMENT_PRODUCTION_ACTION,\n AtlaSentClient,\n AtlaSentError,\n AtlaSentDeniedError,\n paymentGate: protectPaymentRelease,\n dataExportGate: protectDataExport,\n reconciliationGate: protectReconciliationCertify,\n agentGuard: protectToolCall,\n gxpGate: protectGxpAction,\n batchRecordGate: protectBatchRecordRelease,\n paymentOpsGate: protectPaymentOperation,\n deployV2Gate: protectDeploymentV2,\n behaviorEventGate: protectBehaviorEvent,\n infraGate: protectInfraAction,\n hrGate: protectHrOffboard,\n modelGovernanceGate: protectModelPromotion,\n dataDeleteGate: protectCustomerDataDelete,\n contractGate: protectContractExecution,\n pricingGate: protectPricingRule,\n securityGate: protectSecurityIncidentEscalate,\n accessCertGate: protectAccessCertRevoke,\n financialCloseGate: protectPeriodCloseCertify,\n databaseMigrationGate: protectDatabaseMigration,\n databaseSchemaDropGate: protectDatabaseSchemaDrop,\n databaseTableDeleteGate: protectDatabaseTableDelete,\n} as const;\n\nexport default atlasent;\n\nexport {\n buildClaimEvidenceLink,\n verifyClaimEvidenceLink,\n NOT_APPLICABLE,\n type BuildClaimEvidenceLinkOpts,\n type VerifyClaimEvidenceLinkOpts,\n type VerifyClaimEvidenceLinkResult,\n type ClaimEvidenceLink,\n type RuntimeEvidenceSlot,\n type DeployEvidenceSlot,\n type IntegrationEvidenceSlot,\n type ApprovalArtifactSlot,\n type DeltaSlot,\n type DriftDetail,\n type DriftChangeType,\n type DriftSeverity,\n type DeltaStatus,\n type EvidenceSlotStatus,\n type VerificationChecklist,\n type NotApplicable,\n type DeployEvidenceInput,\n type HitlChainSummary,\n type SignedApprovalArtifact,\n buildClaimEvidenceLinkFromActionBundle,\n type ActionBundleInput,\n type ActionBundleReceipt,\n type BuildFromActionBundleOpts,\n} from \"./claimLineage.js\";\n\n// ── BCCAE V1 — Phase 3 Execution Assurance substrate ───────────────────────────────────────────────\nexport {\n BCCAEClient,\n generateBccaeNonce,\n type BccaeActorType,\n type BccaeTrustLevel,\n type BccaeResourceClassification,\n type BccaeDeploymentEnv,\n type BccaeSecurityPosture,\n type BccaeRequestSource,\n type BccaeRevocationTargetType,\n type BccaeClientOptions,\n type BccaeEvaluateInput,\n type BccaeEvaluateResponse,\n type BccaeExecuteInput,\n type BccaeExecuteResponse,\n type BccaeRevokeInput,\n type BccaeRevokeResponse,\n type BccaeEvidenceResponse,\n} from \"./bccae.js\";\n\n// ── Constrained governance agents (advisory read surface) ───────────────────────────────────────────────\nexport {\n highestAgentFindingSeverity,\n type AgentAuthorityDomain,\n type AgentEvaluationStatus,\n type AgentEvidenceRef,\n type AgentFindingSeverity,\n type AgentInvokerKind,\n type AgentSubjectKind,\n type GovernanceAgent,\n type GovernanceAgentEvaluation,\n type GovernanceAgentFinding,\n type ListGovernanceAgentsResponse,\n type ListGovernanceEvaluationsQuery,\n type ListGovernanceEvaluationsResponse,\n type ListGovernanceFindingsQuery,\n type ListGovernanceFindingsResponse,\n} from \"./governanceAgents.js\";\n\n// ── SCIM 2.0 Provisioning ─────────────────────────────────────────────────────────────────────────────────────────\nexport {\n makeScimClient,\n SCIM_GROUP_SCHEMA,\n SCIM_PATCH_OP_SCHEMA,\n SCIM_USER_SCHEMA,\n type ScimEmail,\n type ScimGroupRef,\n type ScimGroupsSubClient,\n type ScimListParams,\n type ScimListResponse,\n type ScimMeta,\n type ScimName,\n type ScimPatchOp,\n type ScimSubClient,\n type ScimUser,\n type ScimUserCreate,\n type ScimUsersSubClient,\n type ScimUserUpdate,\n} from \"./scim.js\";\n\n// ── Evidence Bundles ──────────────────────────────────────────────────────────────────────────────────────────────\nexport {\n makeEvidenceBundleClient,\n type EvidenceBundle,\n type EvidenceBundleCreateParams,\n type EvidenceBundleListPage,\n type EvidenceBundleListParams,\n type EvidenceBundleStatus,\n type EvidenceBundleSubClient,\n} from \"./evidence-bundle.js\";\n\n// ── Auth Token Management ─────────────────────────────────────────────────────────────────────────────────────────────\nexport {\n makeAuthClient,\n type AuthSubClient,\n type IdpConnection,\n type TokenResponse,\n} from \"./auth.js\";\n\n// ── SSO Administration ────────────────────────────────────────────────────────────────────────────────────────────────\nexport {\n wireToSsoConnection,\n wireToSsoJitRule,\n wireToSsoEvent,\n wireToSsoReadiness,\n makeSsoClient,\n type SsoConnection,\n type SsoConnectionWire,\n type SsoConnectionInput,\n type SsoJitRule,\n type SsoJitRuleWire,\n type SsoJitRuleInput,\n type SsoJitRulePatch,\n type SsoEvent,\n type SsoEventWire,\n type SsoEnforceAction,\n type SsoEnforceResult,\n type SsoReadiness,\n type SsoReadinessWire,\n type SsoRole,\n type SsoSubClient,\n} from \"./sso.js\";\n\n// ── Access Governance Log ─────────────────────────────────────────────────────\nexport {\n makeAccessGovernanceLogClient,\n type AccessGovernanceEvent,\n type AccessGovernanceLogPage,\n type AccessGovernanceLogQuery,\n type AccessGovernanceLogSubClient,\n} from \"./access-governance-log.js\";\n\n// ── Delta VQP — AI re-derivation audit (service-role server-side client) ────────────────────────────────\nexport {\n VQPClient,\n type VqpVerdict,\n type VQPClientOptions,\n type VQPGenerateInput,\n type VQPGenerateResponse,\n type VQPVerifyInput,\n type VQPVerifyResponse,\n} from \"./vqp.js\";\n\n// ── Action Dependencies ───────────────────────────────────────────────────────\nexport type {\n ActionDependency,\n ActionDependencyResponse,\n CreateActionDependencyRequest,\n DependencyLink,\n DependencyRequirement,\n DependencyStatus,\n ListActionDependenciesResponse,\n} from \"./actionDependencies.js\";\n\n// ── Engine Versions ───────────────────────────────────────────────────────────\nexport type {\n EngineVersionRecord,\n EngineVersionResponse,\n EngineVersionStatus,\n ListEngineVersionsResponse,\n RegisterEngineVersionRequest,\n} from \"./engineVersions.js\";\n\n// ── State Snapshots ───────────────────────────────────────────────────────────\nexport type {\n SnapshotSourceKind,\n StateSnapshot,\n StateSnapshotInput,\n StateSnapshotRef,\n} from \"./snapshots.js\";\n","/**\n * Error types for the AtlaSent TypeScript SDK.\n *\n * The SDK follows a fail-closed design: a clean policy DENY is\n * returned as `EvaluateResponse.decision === \"deny\"` (not thrown),\n * but any failure to confirm authorization — network, timeout,\n * bad response, invalid key, rate limit — throws an\n * {@link AtlaSentError}.\n */\n\n// ── Streaming-specific errors ─────────────────────────────────────────────────\n\n/**\n * Thrown when no SSE event arrives within the configured timeout window.\n *\n * Callers can catch this specifically to distinguish a stalled stream\n * from other network or parse failures:\n *\n * ```ts\n * catch (e) {\n * if (e instanceof StreamTimeoutError) { // reconnect or alert }\n * }\n * ```\n */\nexport class StreamTimeoutError extends Error {\n override name: string = \"StreamTimeoutError\";\n /** Timeout that was exceeded, in milliseconds. */\n readonly timeoutMs: number;\n\n constructor(timeoutMs: number) {\n super(`AtlaSent stream timed out after ${timeoutMs}ms with no event`);\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Thrown when the SSE stream closes with a partial / malformed JSON payload.\n *\n * This is a recoverable condition — the stream closed mid-JSON. The\n * caller can reconnect using the last received `Last-Event-ID` and\n * resume from where the server left off.\n *\n * ```ts\n * catch (e) {\n * if (e instanceof StreamParseError) { // log raw data, maybe reconnect }\n * }\n * ```\n */\nexport class StreamParseError extends Error {\n override name: string = \"StreamParseError\";\n /** The raw data string that failed to parse. */\n readonly rawData: string;\n\n constructor(rawData: string, cause?: unknown) {\n super(`AtlaSent stream received malformed JSON: ${rawData.slice(0, 200)}`);\n this.rawData = rawData;\n if (cause !== undefined) {\n // ES2022 cause\n (this as { cause?: unknown }).cause = cause;\n }\n }\n}\n\n/** Discriminator for {@link AtlaSentError.code}. */\nexport type AtlaSentErrorCode =\n | \"invalid_api_key\"\n | \"forbidden\"\n | \"rate_limited\"\n | \"timeout\"\n | \"network\"\n | \"bad_response\"\n | \"bad_request\"\n | \"server_error\"\n // Tenant lacks a v2_<feature> flag — server returned 404. Distinct\n // from \"forbidden\" (403 authorization denial) so callers can branch\n // on the failure mode.\n | \"feature_disabled\"\n | \"claim_evidence_incomplete\";\n\n/** Initialization options for {@link AtlaSentError}. */\nexport interface AtlaSentErrorInit {\n status?: number;\n code?: AtlaSentErrorCode;\n requestId?: string;\n retryAfterMs?: number;\n cause?: unknown;\n}\n\n/**\n * The only error type this SDK throws.\n *\n * Flat top-level properties mirror the convention used by Stripe,\n * Octokit, and Supabase. `cause` is forwarded to the standard\n * ES2022 `Error` constructor.\n */\nexport class AtlaSentError extends Error {\n // Subclasses override to their own literal (e.g. \"AtlaSentDeniedError\");\n // keep this assignable rather than pinned to a single literal.\n override name: string = \"AtlaSentError\";\n\n /** HTTP status code, when the error originated from an API response. */\n readonly status: number | undefined;\n /** Coarse category — useful for `switch` statements at call sites. */\n readonly code: AtlaSentErrorCode | undefined;\n /** Correlation ID echoed from the `X-Request-ID` header the SDK sent. */\n readonly requestId: string | undefined;\n /** Parsed `Retry-After` header value, in milliseconds. Only set for 429. */\n readonly retryAfterMs: number | undefined;\n\n constructor(message: string, init: AtlaSentErrorInit = {}) {\n super(\n message,\n init.cause !== undefined ? { cause: init.cause } : undefined,\n );\n this.status = init.status;\n this.code = init.code;\n this.requestId = init.requestId;\n this.retryAfterMs = init.retryAfterMs;\n }\n}\n\n/**\n * Outcome of a denied decision.\n *\n * `\"deny\"` is what the current `/v1-evaluate` API returns. `\"hold\"`\n * and `\"escalate\"` are reserved for forthcoming API decisions that\n * put a permit into a pending state requiring human review; the\n * union is declared now so call sites can `switch` exhaustively\n * from the start and adopt new decisions without a breaking change.\n */\nexport type AtlaSentDecision = \"deny\" | \"hold\" | \"escalate\";\n\n/**\n * Reason an already-issued permit failed verification.\n *\n * Surfaced on {@link AtlaSentDeniedError.outcome} so callers can\n * distinguish replay (`permit_consumed`) from revocation\n * (`permit_revoked`) from natural expiry (`permit_expired`) without\n * parsing {@link AtlaSentDeniedError.reason}. The set is defined by\n * `contract/vectors/permit_outcomes.json`; any new outcome MUST be\n * added there first.\n *\n * Mirrors the Python SDK's `PermitOutcome`. See\n * `atlasent/docs/REVOCATION_RUNBOOK.md` for the operator-facing\n * matrix this discriminator drives.\n */\nexport type PermitOutcome =\n | \"permit_consumed\"\n | \"permit_expired\"\n | \"permit_revoked\"\n | \"permit_not_found\"\n | \"permit_signing_key_revoked\";\n\nconst KNOWN_PERMIT_OUTCOMES: ReadonlySet<string> = new Set([\n \"permit_consumed\",\n \"permit_expired\",\n \"permit_revoked\",\n \"permit_not_found\",\n \"permit_signing_key_revoked\",\n]);\n\n/**\n * Map a server-supplied `outcome` string to {@link PermitOutcome}.\n *\n * Returns `undefined` for `undefined`, `\"\"`, `\"verified\"`, or any\n * unrecognized value. Used at the SDK's deny boundary so we don't\n * surface mis-typed outcomes — when the server adds a new outcome\n * string, callers branching on {@link AtlaSentDeniedError.outcome}\n * see `undefined` and fall through to their generic deny path\n * rather than match an unknown literal.\n */\nexport function normalizePermitOutcome(\n raw: string | undefined,\n): PermitOutcome | undefined {\n if (raw !== undefined && KNOWN_PERMIT_OUTCOMES.has(raw)) {\n return raw as PermitOutcome;\n }\n return undefined;\n}\n\n/** Initialization options for {@link AtlaSentDeniedError}. */\nexport interface AtlaSentDeniedErrorInit {\n decision: AtlaSentDecision;\n evaluationId: string;\n reason?: string;\n requestId?: string;\n auditHash?: string;\n /**\n * When the denial came from permit verification (not policy\n * evaluation), the discriminator that distinguishes replay,\n * expiry, revocation, and missing-record failures. `undefined`\n * for evaluate-time denials.\n */\n outcome?: PermitOutcome;\n}\n\n/**\n * Thrown by {@link atlasent.protect} when the policy engine refuses\n * the action, or when a permit fails end-to-end verification.\n *\n * This is the **fail-closed boundary** of the SDK: every code path\n * that short-circuits an action because authorization was not\n * confirmed raises an `AtlaSentDeniedError`. Callers cannot silently\n * proceed on a denial by forgetting to branch on a return value.\n *\n * Extends {@link AtlaSentError} so `instanceof AtlaSentError`\n * catches denials as part of the SDK's single exception family;\n * use `instanceof AtlaSentDeniedError` to distinguish a policy\n * denial from a transport/auth error.\n */\nexport class AtlaSentDeniedError extends AtlaSentError {\n override name: string = \"AtlaSentDeniedError\";\n\n /** Policy decision — `\"deny\"` today; `\"hold\"` / `\"escalate\"` reserved. */\n readonly decision: AtlaSentDecision;\n /** Opaque permit/decision id from `/v1-evaluate`. */\n readonly evaluationId: string;\n /** Human-readable explanation from the policy engine, if provided. */\n readonly reason: string | undefined;\n /** Hash-chained audit-trail entry associated with the decision. */\n readonly auditHash: string | undefined;\n /**\n * Discriminator for permit-side denial reasons. Populated only\n * when the server reported `verified=false` from `/v1-verify-permit`;\n * `undefined` for evaluate-time denials. See {@link PermitOutcome}.\n */\n readonly outcome: PermitOutcome | undefined;\n\n constructor(init: AtlaSentDeniedErrorInit) {\n const msg = init.reason\n ? `AtlaSent ${init.decision}: ${init.reason}`\n : `AtlaSent ${init.decision}`;\n const errInit: AtlaSentErrorInit = { status: 200 };\n if (init.requestId !== undefined) errInit.requestId = init.requestId;\n super(msg, errInit);\n this.decision = init.decision;\n this.evaluationId = init.evaluationId;\n this.reason = init.reason;\n this.auditHash = init.auditHash;\n this.outcome = init.outcome;\n }\n\n // ── Outcome discriminators ───────────────────────────────────────\n // Convenience predicates that mirror the operator runbook's matrix.\n // Callers can compare `outcome` directly; these are sugar so the\n // common cases are explicit at the call site.\n\n /** `true` when the permit was explicitly revoked (D3 endpoint). */\n get isRevoked(): boolean {\n return this.outcome === \"permit_revoked\";\n }\n\n /** `true` when the permit's TTL passed before verification. */\n get isExpired(): boolean {\n return this.outcome === \"permit_expired\";\n }\n\n /**\n * `true` when the permit was already consumed by a prior verify\n * (v1 single-use replay protection).\n */\n get isConsumed(): boolean {\n return this.outcome === \"permit_consumed\";\n }\n\n /**\n * `true` when the permit id wasn't recognized server-side\n * (typo, cross-tenant lookup, or pre-issuance race).\n */\n get isNotFound(): boolean {\n return this.outcome === \"permit_not_found\";\n }\n\n /**\n * `true` when the permit's signing key KID appears in the\n * trust-root revocation list (ADR-005 D3 R2/R3 key rotation).\n */\n get isSigningKeyRevoked(): boolean {\n return this.outcome === \"permit_signing_key_revoked\";\n }\n}\n\n/** Initialization options for {@link AtlaSentEscalateError}. */\nexport interface AtlaSentEscalateErrorInit {\n requestId?: string;\n userId?: string;\n cause?: unknown;\n}\n\n/**\n * Thrown when an evaluate response carries `decision: \"escalate\"`.\n *\n * Distinct from {@link AtlaSentDeniedError} — an escalation does not\n * constitute a hard denial. It signals that the policy engine has\n * deferred the authorization decision to a human review queue.\n * Middleware and agent orchestrators should catch this specifically\n * and route the pending action to the appropriate HITL channel.\n *\n * ```ts\n * catch (e) {\n * if (e instanceof AtlaSentEscalateError) {\n * await humanReviewQueue.submit({ userId: e.userId, requestId: e.requestId });\n * }\n * }\n * ```\n *\n * Extends {@link AtlaSentError} so `instanceof AtlaSentError` catches\n * escalations alongside other SDK errors; use\n * `instanceof AtlaSentEscalateError` to branch specifically.\n */\nexport class AtlaSentEscalateError extends AtlaSentError {\n override name: string = \"AtlaSentEscalateError\";\n\n /** Always `\"escalate\"` — discriminates this error from other AtlaSent errors. */\n readonly decision = \"escalate\" as const;\n\n /** The user whose action triggered the escalation, if available. */\n readonly userId: string | undefined;\n\n constructor(message: string, opts?: AtlaSentEscalateErrorInit) {\n super(message, {\n ...(opts?.requestId !== undefined ? { requestId: opts.requestId } : {}),\n cause: opts?.cause,\n });\n this.userId = opts?.userId;\n }\n}\n\n// ── Permit revocation error (PROD-D9 continuous-authorization) ────────────────\n\n/**\n * Thrown by an SDK guard heartbeat when `GET /v1/permits/:id/valid`\n * returns `status: 'revoked'` during tool execution (PROD-D9\n * continuous-authorization lease model).\n *\n * This error is **always re-thrown** — it is never serialized as a\n * `tool-result` denial because it represents a live enforcement action,\n * not a policy evaluation at request time. Callers should treat it as\n * an immediate halt signal.\n *\n * ```ts\n * catch (e) {\n * if (e instanceof PermitRevoked) {\n * // log e.permitId and e.revocationId for incident correlation\n * await incidentLog.record({ permitId: e.permitId, revocationId: e.revocationId });\n * }\n * }\n * ```\n *\n * Guard heartbeat is configured via `permitRevalidationIntervalMs` in\n * the guard options (minimum 1000 ms). The heartbeat activates only\n * when the {@link AtlaSentClient} exposes `checkPermitValid` — i.e.\n * when `atlasent-api` has deployed `GET /v1/permits/:id/valid`.\n */\nexport class PermitRevoked extends AtlaSentError {\n override name: string = 'PermitRevoked';\n /** The id of the permit that was revoked mid-execution. */\n readonly permitId: string;\n /** The `scope_revocations.id` that triggered the revocation, when available. */\n readonly revocationId: string | undefined;\n\n constructor(permitId: string, revocationId?: string) {\n super(\n revocationId\n ? `AtlaSent: permit ${permitId} revoked (revocation: ${revocationId}) — guard heartbeat halted execution`\n : `AtlaSent: permit ${permitId} revoked — guard heartbeat halted execution`,\n );\n this.permitId = permitId;\n this.revocationId = revocationId;\n }\n}\n\n// ── Bundle verification error (ADR-005 D3 fail-closed expiry / revocation) ────\n\n/**\n * Initialization options for {@link BundleVerificationError}.\n */\nexport interface BundleVerificationErrorInit {\n /**\n * Machine-readable reason code:\n * - `trust_snapshot_expired`: the snapshot's `valid_until` has passed\n * and `allowExpiredSnapshot` was not set.\n * - `key_revoked`: the bundle's `signing_key_id` appears in\n * `revoked_keys` of the active trust snapshot.\n * - `key_role_mismatch`: the signing key's `role` is not `\"R3_audit\"`.\n */\n reason: \"trust_snapshot_expired\" | \"key_revoked\" | \"key_role_mismatch\";\n /** ISO-8601 `valid_until` of the snapshot that caused the failure. */\n snapshotValidUntil?: string;\n /** ISO-8601 `issued_at` of the snapshot (its fetch/pin time). */\n snapshotFetchedAt?: string;\n /** Whether the snapshot came from the bundled vendor files or a live refresh. */\n snapshotSource?: \"pinned\" | \"live\";\n /** Which key id was revoked or role-mismatched, when applicable. */\n kid?: string;\n}\n\n/**\n * Thrown by {@link verifyAuditBundle} / {@link verifyBundle} when the\n * active trust-root snapshot is expired (ADR-005 D3) or the bundle's\n * signing key is revoked / has the wrong role.\n *\n * This error is **always thrown** — it is never returned as a\n * {@link BundleVerificationResult} because ADR-005 D3 requires that\n * an expired snapshot or revoked key constitutes a hard enforcement\n * action, not a soft verification failure.\n *\n * To opt out of fail-closed expiry (air-gap / offline use), pass\n * `allowExpiredSnapshot: true` to `verifyBundle`.\n */\nexport class BundleVerificationError extends AtlaSentError {\n override name = \"BundleVerificationError\";\n\n readonly reason: BundleVerificationErrorInit[\"reason\"];\n readonly snapshotValidUntil: string | undefined;\n readonly snapshotFetchedAt: string | undefined;\n readonly snapshotSource: \"pinned\" | \"live\" | undefined;\n readonly kid: string | undefined;\n\n constructor(init: BundleVerificationErrorInit) {\n super(`AtlaSent audit bundle verification failed: ${init.reason}`);\n this.reason = init.reason;\n this.snapshotValidUntil = init.snapshotValidUntil;\n this.snapshotFetchedAt = init.snapshotFetchedAt;\n this.snapshotSource = init.snapshotSource;\n this.kid = init.kid;\n }\n}\n\n","/**\n * Hybrid trust-root bootstrap and snapshot management.\n *\n * At module load, seeds from the vendor snapshot in vendor/trust-root/.\n * Optionally refreshes from https://keys.atlasent.io/.well-known/ on\n * a configurable interval (default 4h, floor 5 min per ADR-005 D2).\n * Refresh failure is silent — falls back to the in-memory snapshot.\n *\n * Snapshot expiry (valid_until) is fail-closed per ADR-005 D3:\n * checkExpiry() emits a one-time console.warn at half-life, and again\n * on expiry. verifyAuditBundle throws BundleVerificationError when\n * expired (unless allowExpiredSnapshot=true is passed).\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { resolve, dirname } from \"node:path\";\n\n// Types for the trust-root document shapes\nexport interface TrustRootKey {\n kid: string;\n role: \"R1_release\" | \"R2_permit\" | \"R3_audit\" | \"R4_pack\";\n kty: string;\n crv?: string;\n alg: string;\n x?: string;\n valid_from?: string | null;\n valid_until?: string | null;\n replaced_by?: string | null;\n revoked?: boolean;\n tenant?: string | null;\n}\n\nexport interface TrustRootRevocationEntry {\n kid: string;\n role?: string;\n revoked_at: string;\n reason?: string;\n}\n\nexport interface TrustRootSnapshot {\n /** ISO-8601 expiry of this snapshot; fail-closed when exceeded */\n valid_until: string;\n issued_at: string;\n keys: TrustRootKey[];\n revoked_keys: TrustRootRevocationEntry[];\n revoked_identities: Array<{ identity: string; revoked_at: string; reason?: string }>;\n}\n\nexport interface TrustRootManagerOptions {\n /** Override the refresh URL (default: https://keys.atlasent.io/.well-known/) */\n refreshBaseUrl?: string;\n /** Refresh interval in ms. Default: 4h. Floor: 5 min. */\n refreshIntervalMs?: number;\n /** Disable automatic background refresh. */\n disableRefresh?: boolean;\n /** Custom fetch implementation (for tests). */\n fetch?: typeof fetch;\n}\n\nconst REFRESH_INTERVAL_MS_DEFAULT = 4 * 60 * 60 * 1000; // 4 hours\nconst REFRESH_INTERVAL_MS_FLOOR = 5 * 60 * 1000; // 5 minutes\nconst KEYS_BASE_URL = \"https://keys.atlasent.io/.well-known\";\n\n// Half-life and expiry warnings: emitted once per process (ADR-005 D3).\nlet _halfLifeWarningEmitted = false;\nlet _expiredWarningEmitted = false;\n\nfunction _resetWarningFlags(): void {\n _halfLifeWarningEmitted = false;\n _expiredWarningEmitted = false;\n}\n\nexport class TrustRootManager {\n private _snapshot: TrustRootSnapshot;\n private _refreshTimer: ReturnType<typeof setInterval> | null = null;\n private readonly _opts: Required<TrustRootManagerOptions>;\n\n constructor(\n initialSnapshot: TrustRootSnapshot,\n opts: TrustRootManagerOptions = {},\n ) {\n this._snapshot = initialSnapshot;\n const intervalMs = Math.max(\n opts.refreshIntervalMs ?? REFRESH_INTERVAL_MS_DEFAULT,\n REFRESH_INTERVAL_MS_FLOOR,\n );\n this._opts = {\n refreshBaseUrl: opts.refreshBaseUrl ?? KEYS_BASE_URL,\n refreshIntervalMs: intervalMs,\n disableRefresh: opts.disableRefresh ?? false,\n fetch:\n opts.fetch ??\n (typeof globalThis !== \"undefined\" && globalThis.fetch\n ? globalThis.fetch.bind(globalThis)\n : ((_url: string) =>\n Promise.reject(new Error(\"fetch not available\"))) as typeof fetch),\n };\n if (!this._opts.disableRefresh) {\n this._scheduleRefresh();\n }\n }\n\n getSnapshot(): TrustRootSnapshot {\n return this._snapshot;\n }\n\n /**\n * Check whether the snapshot is expired, emit one-time warnings at\n * half-life and expiry. Returns \"ok\" | \"half_life\" | \"expired\".\n *\n * Emits console.warn once per process at half-life (ADR-005 D3).\n * Emits console.warn once per process on expiry.\n */\n checkExpiry(): \"ok\" | \"half_life\" | \"expired\" {\n const snap = this._snapshot;\n const now = Date.now();\n const issuedAt = new Date(snap.issued_at).getTime();\n const validUntil = new Date(snap.valid_until).getTime();\n\n if (now > validUntil) {\n if (!_expiredWarningEmitted) {\n _expiredWarningEmitted = true;\n const daysAgo = Math.floor((now - validUntil) / (24 * 60 * 60 * 1000));\n // eslint-disable-next-line no-console\n console.warn(\n `[atlasent] Trust snapshot expired ${daysAgo} day(s) ago (valid_until: ${snap.valid_until}). ` +\n \"Update to a newer SDK build or enable allowExpiredSnapshot.\",\n );\n }\n return \"expired\";\n }\n const window = validUntil - issuedAt;\n const halfLife = issuedAt + window / 2;\n if (now > halfLife) {\n if (!_halfLifeWarningEmitted) {\n _halfLifeWarningEmitted = true;\n const daysLeft = Math.floor((validUntil - now) / (24 * 60 * 60 * 1000));\n // eslint-disable-next-line no-console\n console.warn(\n `[atlasent] Trust snapshot at half-life: expires in ${daysLeft} day(s) (valid_until: ${snap.valid_until}). ` +\n \"Plan an SDK update.\",\n );\n }\n return \"half_life\";\n }\n return \"ok\";\n }\n\n /** Look up a key entry by kid. Returns undefined if not found. */\n lookupKey(kid: string): TrustRootKey | undefined {\n return this._snapshot.keys.find((k) => k.kid === kid);\n }\n\n /** Returns true if the kid appears in revoked_keys. */\n isRevoked(kid: string): boolean {\n return this._snapshot.revoked_keys.some((r) => r.kid === kid);\n }\n\n /** Replace the snapshot (e.g. after a successful refresh). */\n replaceSnapshot(next: TrustRootSnapshot): void {\n this._snapshot = next;\n }\n\n stopRefresh(): void {\n if (this._refreshTimer !== null) {\n clearInterval(this._refreshTimer);\n this._refreshTimer = null;\n }\n }\n\n private _scheduleRefresh(): void {\n this._refreshTimer = setInterval(() => {\n void this._doRefresh();\n }, this._opts.refreshIntervalMs);\n // Don't hold the process open.\n if (\n this._refreshTimer &&\n typeof this._refreshTimer === \"object\" &&\n \"unref\" in this._refreshTimer\n ) {\n (this._refreshTimer as { unref(): void }).unref();\n }\n }\n\n private async _doRefresh(): Promise<void> {\n try {\n const base = this._opts.refreshBaseUrl.replace(/\\/$/, \"\");\n const [keysRes, revocRes] = await Promise.all([\n this._opts.fetch(`${base}/atlasent-verifier-keys.json`),\n this._opts.fetch(`${base}/atlasent-revocations.json`),\n ]);\n const indexRes = await this._opts.fetch(`${base}/atlasent-trust-root.json`);\n\n if (!keysRes.ok || !revocRes.ok || !indexRes.ok) return;\n\n const [keys, revoc, index] = await Promise.all([\n keysRes.json() as Promise<{ keys: TrustRootKey[] }>,\n revocRes.json() as Promise<{\n revoked_keys: TrustRootRevocationEntry[];\n revoked_identities: unknown[];\n }>,\n indexRes.json() as Promise<{ valid_until: string; issued_at: string }>,\n ]);\n\n if (!index.valid_until || !Array.isArray(keys.keys)) return;\n\n this._snapshot = {\n valid_until: index.valid_until,\n issued_at: index.issued_at ?? this._snapshot.issued_at,\n keys: keys.keys,\n revoked_keys: revoc.revoked_keys ?? [],\n revoked_identities:\n (revoc.revoked_identities as Array<{\n identity: string;\n revoked_at: string;\n }>) ?? [],\n };\n } catch {\n // Refresh failure is silent — keep using the current snapshot.\n }\n }\n}\n\n// ─── Load the embedded (vendor) snapshot ─────────────────────────────────────\n\nfunction _loadVendorSnapshot(): TrustRootSnapshot {\n try {\n // Resolve relative to the package root. Works both when running from\n // typescript/ (dev) and from dist/ (published).\n let packageRoot: string;\n try {\n // ESM: use import.meta.url\n const thisFile = fileURLToPath(import.meta.url);\n // src/trustRoot.ts → ../../vendor/trust-root OR\n // dist/trustRoot.js → ../../vendor/trust-root\n packageRoot = resolve(dirname(thisFile), \"..\", \"..\");\n } catch {\n // CJS or bundler: fall back to __dirname if available\n packageRoot = resolve(__dirname, \"..\", \"..\");\n }\n\n const vendorDir = resolve(packageRoot, \"vendor\", \"trust-root\");\n\n const index = JSON.parse(\n readFileSync(resolve(vendorDir, \"atlasent-trust-root.json\"), \"utf8\"),\n ) as { valid_until: string; issued_at: string };\n\n const verifierKeys = JSON.parse(\n readFileSync(resolve(vendorDir, \"atlasent-verifier-keys.json\"), \"utf8\"),\n ) as { keys: TrustRootKey[] };\n\n const revocations = JSON.parse(\n readFileSync(resolve(vendorDir, \"atlasent-revocations.json\"), \"utf8\"),\n ) as {\n revoked_keys: TrustRootRevocationEntry[];\n revoked_identities: Array<{ identity: string; revoked_at: string }>;\n };\n\n return {\n valid_until: index.valid_until,\n issued_at: index.issued_at,\n keys: verifierKeys.keys ?? [],\n revoked_keys: revocations.revoked_keys ?? [],\n revoked_identities: revocations.revoked_identities ?? [],\n };\n } catch {\n // Fallback: a minimal never-expiring snapshot so the SDK degrades\n // gracefully in build environments where vendor/ is not present.\n return {\n valid_until: \"2099-01-01T00:00:00Z\",\n issued_at: \"2026-05-26T00:00:00Z\",\n keys: [],\n revoked_keys: [],\n revoked_identities: [],\n };\n }\n}\n\n// Process-global manager — created lazily.\nlet _globalManager: TrustRootManager | null = null;\n\nexport function getGlobalTrustRootManager(\n opts?: TrustRootManagerOptions,\n): TrustRootManager {\n if (!_globalManager) {\n _globalManager = new TrustRootManager(\n _loadVendorSnapshot(),\n opts ?? { disableRefresh: false },\n );\n }\n return _globalManager;\n}\n\n/** Replace the global manager (primarily for tests). */\nexport function __setGlobalTrustRootManagerForTests(\n mgr: TrustRootManager | null,\n): void {\n _globalManager = mgr;\n _resetWarningFlags();\n}\n\nexport { _resetWarningFlags as __resetWarningFlagsForTests };\n","/**\n * Public types for the AtlaSent TypeScript SDK.\n *\n * These shapes are deliberately minimal and 1:1 with the AtlaSent\n * authorization API. Request / response fields are camelCase on the\n * SDK side; the client handles snake_case translation on the wire.\n */\n\nimport type { AuditEventsPage, AuditExport } from \"./audit.js\";\n\n/**\n * Canonical 4-value policy decision, byte-identical to the wire.\n *\n * - `allow` — action is authorized; a Permit is issued.\n * - `deny` — action is blocked.\n * - `hold` — decision deferred (e.g. waiting on an approval signal).\n * - `escalate` — routed to a human reviewer queue.\n *\n * Pin to this type on new code.\n */\nexport type DecisionCanonical = \"allow\" | \"deny\" | \"hold\" | \"escalate\";\n\n/**\n * Decision type — unified with the canonical 4-value vocabulary.\n *\n * This type previously emitted `\"ALLOW\"` / `\"DENY\"` (uppercase, 2-value).\n * It now reflects the canonical wire values (`\"allow\" | \"deny\" | \"hold\" |\n * \"escalate\"`) so the `decision` and `decision_canonical` fields on\n * {@link EvaluateResponse} carry identical values and types.\n *\n * Backward compatibility: the SDK normalises API response values to\n * lowercase (`.toLowerCase()`) before returning them, so callers that\n * previously checked `=== \"ALLOW\"` must update to `=== \"allow\"`. The\n * canonical field `decision_canonical` is also available and was always\n * lowercase — prefer it on new code.\n *\n * Legacy uppercase input accepted by the SDK is normalised to lowercase\n * output; `\"ALLOW\"` in → `\"allow\"` out, `\"DENY\"` in → `\"deny\"` out.\n */\nexport type Decision = DecisionCanonical;\n\n/**\n * Rate-limit state parsed from the server's `X-RateLimit-*` headers.\n *\n * Present on every authenticated response (success and 429) when the\n * server emits the headers. `null` when the server doesn't — older\n * deployments, or internal endpoints that skip per-key rate limiting.\n *\n * Clients should check `remaining` and sleep until `resetAt` to\n * preemptively back off before hitting a 429.\n */\nexport interface RateLimitState {\n /** Value of `X-RateLimit-Limit` — the per-minute budget. */\n limit: number;\n /** Value of `X-RateLimit-Remaining` — unused budget in the current window. */\n remaining: number;\n /**\n * Parsed `X-RateLimit-Reset` — the UTC instant when the current\n * window's counter zeroes. Accepts either a unix-seconds integer or\n * an ISO 8601 string on the wire.\n */\n resetAt: Date;\n}\n\n/**\n * Canonical Deploy Gate V1 protected action.\n *\n * Use this constant (or its string value `\"production.deploy\"`) on all\n * new code. Server-side `action_classes.slug` was canonicalised to\n * `production.deploy` in atlasent-api PR #662 / atlasent-console\n * PR #432; the SDK default now matches.\n */\nexport const PRODUCTION_DEPLOY_ACTION = \"production.deploy\" as const;\n\n/**\n * Legacy alias for {@link PRODUCTION_DEPLOY_ACTION}.\n *\n * @deprecated since 2.3.0 — use {@link PRODUCTION_DEPLOY_ACTION}. The\n * server alias-tolerates `deployment.production` during the V1 alias\n * window, so existing callers continue to work unchanged; please\n * migrate by the next minor release.\n */\nexport const DEPLOYMENT_PRODUCTION_ACTION = \"deployment.production\" as const;\n\n// ── Deploy Gate V1 context types ──────────────────────────────────────────────────────\n\n/**\n * Permit claim for `production.deploy` evaluations (Rule 3).\n *\n * Pass as `permit` inside {@link DeployGateContext}.\n * The `verified` flag is set by the verify-permit service after a\n * successful `/v1-verify-permit` call — do not self-assert it.\n */\nexport interface DeployPermitClaim {\n permit_id?: string;\n environment?: string;\n action_type?: string;\n /** ISO-8601 timestamp when the permit was issued. */\n issued_at?: string;\n /** Set server-side by the verify-permit service. Do not self-assert. */\n verified?: boolean;\n}\n\n/**\n * Override claim for `production.deploy` evaluations (Rule 8).\n *\n * Both `override_reason` and `authority_basis` must be non-empty to\n * receive `OVERRIDE_APPROVED`. Missing or blank fields return `DENY_POLICY`.\n */\nexport interface DeployOverrideClaim {\n /** Human-readable reason. Required and non-empty. */\n override_reason?: string;\n /** Authoritative basis — runbook section, incident ticket, etc. Required and non-empty. */\n authority_basis?: string;\n /** Approver actor ID (audit record; does not gate the decision). */\n approver_actor_id?: string;\n}\n\n/**\n * Typed context shape for `production.deploy` evaluations.\n *\n * Pass as `context` to `protect()`, `deployGate()`, or\n * {@link AtlaSentClient.evaluate} for the Deploy Gate V1 flow.\n *\n * @example\n * ```ts\n * const permit = await atlasent.protect({\n * agent: \"deploy-bot\",\n * action: PRODUCTION_DEPLOY_ACTION,\n * context: {\n * environment: \"production\",\n * evaluation_confirmed: true,\n * actorMetadata: { role: \"deploy_engineer\" },\n * permit: {\n * permit_id: permitToken,\n * environment: \"production\",\n * action_type: PRODUCTION_DEPLOY_ACTION,\n * issued_at: new Date().toISOString(),\n * verified: true,\n * },\n * } satisfies DeployGateContext,\n * });\n * ```\n */\nexport interface DeployGateContext {\n /** Must be `\"production\"` for the production gate to apply. */\n environment?: \"production\" | \"staging\" | \"development\";\n /**\n * When `true`, all rule failures are shadowed to `allow` (fail-open).\n * Malformed-timestamp inconsistencies still escalate.\n * Use for initial rollout before locking enforcement.\n */\n pilot_mode?: boolean;\n /** Must be `true` — confirms an evaluation record exists before proceeding. */\n evaluation_confirmed?: boolean;\n /** ISO-8601 timestamp of when evaluation was confirmed. */\n evaluation_confirmed_at?: string;\n /** Actor role metadata. `role` must be one of the approved deploy roles. */\n actorMetadata?: { role?: string };\n /** Signed permit claim — required for non-pilot production deployments. */\n permit?: DeployPermitClaim;\n /** Override claim — short-circuits all rules when both fields are non-empty. */\n override?: DeployOverrideClaim;\n [key: string]: unknown;\n}\n\n/**\n * Canonical deploy gate decision codes emitted for `production.deploy`.\n *\n * Appears as `deny_code` / `matchedRuleId` on evaluation responses.\n * Pin dashboards, alerting, and routing logic to these codes — not to\n * `deny_reason` strings, which may change.\n */\nexport type DeployGateDenyCode =\n | \"ALLOW\"\n | \"DENY_POLICY\"\n | \"DENY_AUTHORITY\"\n | \"DENY_ENVIRONMENT\"\n | \"PERMIT_EXPIRED\"\n | \"VERIFY_FAILED\"\n | \"ESCALATE_REQUIRED\"\n | \"OVERRIDE_APPROVED\";\n\n/** Typed constants for {@link DeployGateDenyCode}. */\nexport const DEPLOY_GATE_CODES = Object.freeze({\n ALLOW: \"ALLOW\",\n DENY_POLICY: \"DENY_POLICY\",\n DENY_AUTHORITY: \"DENY_AUTHORITY\",\n DENY_ENVIRONMENT: \"DENY_ENVIRONMENT\",\n PERMIT_EXPIRED: \"PERMIT_EXPIRED\",\n VERIFY_FAILED: \"VERIFY_FAILED\",\n ESCALATE_REQUIRED: \"ESCALATE_REQUIRED\",\n OVERRIDE_APPROVED: \"OVERRIDE_APPROVED\",\n} satisfies Record<DeployGateDenyCode, DeployGateDenyCode>);\n\n/** Input to {@link AtlaSentClient.deployGate}. */\nexport interface DeployGateRequest {\n /** CI/repo actor performing the deployment. Defaults to `ci-deploy-bot`. */\n agent?: string;\n /** Protected action. Defaults to `production.deploy`. */\n action?:\n | typeof PRODUCTION_DEPLOY_ACTION\n | typeof DEPLOYMENT_PRODUCTION_ACTION\n | string;\n /** Typed deploy gate context for `production.deploy`. */\n context?: DeployGateContext | Record<string, unknown>;\n}\n\n/** Evidence metadata returned by {@link AtlaSentClient.deployGate}. */\nexport interface DeployGateEvidence {\n permitId?: string;\n permitHash?: string;\n auditHash?: string;\n verifiedAt?: string;\n}\n\n/** Result of the canonical Deploy Gate V1 flow. */\nexport interface DeployGateResponse {\n /** True only after evaluate allowed AND `/v1-verify-permit` verified server-side. */\n allowed: boolean;\n /** Evaluation response from `POST /v1-evaluate`, when available. */\n evaluation?: EvaluateResponse;\n /** Verification response from `POST /v1-verify-permit`, when evaluation allowed. */\n verification?: VerifyPermitResponse;\n /** Human-readable block/allow reason. */\n reason: string;\n /** Best-effort audit/evidence metadata available to the SDK. */\n evidence: DeployGateEvidence;\n}\n\n/**\n * Frozen BVS snapshot wire shape (BI4).\n * Carried in {@link EvaluateRequest}.context.bvsSnapshot when\n * the `behavior_conditioning` flag is enabled for the tenant.\n * Produced by behavior-insights GET /api/patterns/snapshot/:userId\n * and attached via `@atlasent/behavior` attachToEvaluate().\n */\nexport interface BvsSnapshot {\n user_id: string;\n /** Factor model output — keyed by BVS factor slug, value is score 0-1. */\n factors: Record<string, number>;\n /** Aggregate confidence score (0-1). Decays on a 60-day half-life. */\n confidence: number;\n /** True when the aggregate is fresh-and-thin (too few events to trust). */\n confidence_low: boolean;\n /** ISO-8601 timestamp of the compute run that produced this snapshot. */\n computed_at: string;\n}\n\n/**\n * Consent-class projection (BI5) — the privacy-safe aggregate shape that\n * third-party apps (LedgersMe, hiCoach, echobloom) receive when reading a\n * user's behavioral summary. Counts and timestamps only; no raw free-text.\n * Produced by behavior-insights `/api/patterns/summary/:userId` and fetched\n * via `@atlasent/behavior` getStateSummary(). The SDK enforces\n * {@link https://github.com/AtlaSent-Systems-Inc/atlasent-sdk | assertNoRawText}\n * client-side before returning this shape to callers.\n */\nexport interface ConsentClassProjection {\n user_id: string;\n window_start: string;\n window_end: string;\n event_count: number;\n category_counts: Partial<Record<string, number>>;\n}\n\n/**\n * Proof that a specific actor consumed a specific permit for a specific\n * action_type. Pass an array of these as `completion_proofs` on an evaluate\n * request to satisfy multi-actor quorum dependencies.\n *\n * The runtime verifies each proof via two gates (both must pass):\n * 1. A `permit_uses` row exists for `permit_id` (permit was consumed).\n * 2. An `execution_evaluations` row is bound to `actor_id` + `action_type`\n * for the same permit (actor/action binding — Codex P1 #1148 FIX #3).\n * Proofs that fail either gate are silently dropped (fail-closed).\n */\nexport interface CompletionProof {\n /** The action_type (slug) that was completed by the prior actor. */\n action_type: string;\n /** The actor who completed the action. */\n actor_id: string;\n /** The permit token (or its hash) issued when the action was permitted. */\n permit_id: string;\n}\n\n/** Input to {@link AtlaSentClient.evaluate}. */\nexport interface EvaluateRequest {\n /** Identifier of the calling agent (e.g. \"clinical-data-agent\"). */\n agent: string;\n /** The action being authorized (e.g. \"modify_patient_record\"). */\n action: string;\n /** Arbitrary policy context (user, environment, resource IDs). */\n context?: Record<string, unknown>;\n /**\n * When `true`, the server populates `riskEnvelope.factors` with a\n * per-factor breakdown of the weighted risk score. Omit (or `false`)\n * to keep response payloads small.\n */\n explain?: boolean;\n /** Deployment environment where the action executes (e.g. `\"production\"`). */\n environment?: string;\n /** Structured resource descriptor. Prefer over embedding resource info in `context`. */\n resource?: { type: string; id?: string; attributes?: Record<string, unknown> };\n /** Snapshot of the resource state before the proposed action. Enables state-transition-aware policy evaluation. */\n current_state?: { description: string; attributes?: Record<string, unknown> };\n /** Desired resource state after the action executes. */\n proposed_state?: { description: string; attributes?: Record<string, unknown> };\n /** Execution surface binding — identifies the CI/CD adapter, DB driver, or enforcement point. */\n execution_binding?: { kind: string; adapter_version?: string; resource_id?: string; enforcement_point?: string };\n /** The desired end-state the actor wants the resource to reach. Enables trajectory-aware authorization. */\n desired_state?: { description: string; attributes?: Record<string, unknown>; fingerprint?: string };\n /** Actor-proposed execution path from current_state to desired_state. The engine returns an authorized_trajectory that may differ. */\n proposed_trajectory?: {\n steps: Array<{\n step: string;\n description?: string;\n required: boolean;\n time_limit_seconds?: number;\n authorized_by?: string;\n constraints?: Record<string, unknown>;\n }>;\n description?: string;\n };\n /**\n * Multi-actor quorum completion proofs. Supply one entry per prior actor\n * whose completed action this evaluation depends on. The runtime verifies\n * each proof (consumed-permit gate + actor/action binding gate) and counts\n * only valid proofs toward quorum. Absent or empty → no quorum proofs\n * submitted (no behavioral change for non-quorum dependencies).\n */\n completion_proofs?: CompletionProof[];\n}\n\n/**\n * Slim permit object embedded in {@link EvaluateResponse} when the decision\n * is `\"allow\"`. Contains the essential fields needed to act on the permit\n * immediately without a separate `GET /v1/permits/:id` round-trip.\n *\n * Mirrors the `Permit` schema in atlasent-control-plane\n * `api/src/schemas/permits.ts`.\n */\nexport interface EvaluateResponsePermit {\n id: string;\n orgId: string;\n subject: string;\n scope: string;\n status: \"active\" | \"revoked\" | \"expired\";\n /** The evaluation that produced this permit. */\n evaluationId: string | null;\n issuedBy: string;\n revokedBy: string | null;\n /** ISO-8601 issuance timestamp. */\n issuedAt: string;\n revokedAt: string | null;\n expiresAt: string | null;\n metadata: Record<string, unknown> | null;\n}\n\n/** Result of {@link AtlaSentClient.evaluate}. */\nexport interface EvaluateResponse {\n /**\n * Policy decision — canonical 4-value lowercase vocabulary:\n * `\"allow\"`, `\"deny\"`, `\"hold\"`, or `\"escalate\"`.\n *\n * Previously emitted `\"ALLOW\"` / `\"DENY\"` (uppercase, 2-value);\n * the SDK now normalises all values to lowercase and passes `hold`\n * and `escalate` through rather than collapsing them to `\"DENY\"`.\n *\n * The `decision_canonical` field carries the same value and is the\n * recommended field for new code.\n */\n decision: Decision;\n /**\n * Canonical 4-value decision, byte-identical to the wire.\n *\n * One of `\"allow\"`, `\"deny\"`, `\"hold\"`, `\"escalate\"`. Branch on\n * this field on new code. `hold` and `escalate` are non-terminal\n * states that route to a human reviewer / approval signal — they\n * are not equivalent to a `deny`.\n */\n decision_canonical: DecisionCanonical;\n /**\n * Server-assigned identifier for this evaluation decision.\n *\n * Stable across retries and used as the key for proof retrieval\n * (`GET /v1/proof/:evaluationId`) and override requests. Also\n * available as the legacy `permitId` field for backward compatibility.\n */\n evaluationId: string;\n /** Opaque permit identifier, passed to {@link AtlaSentClient.verifyPermit}.\n *\n * @deprecated Prefer `evaluationId`. This field is kept for backward\n * compatibility and points to the same server-assigned ID.\n */\n permitId: string;\n /**\n * Slim permit object issued when `decision === \"allow\"`.\n * `null` on deny, hold, or escalate decisions.\n *\n * Mirrors the `Permit` schema from the control-plane.\n */\n permit: EvaluateResponsePermit | null;\n /**\n * Opaque HMAC-signed permit token issued when `decision === \"allow\"`.\n * Pass to `POST /v1/verify-permit` to verify the permit server-side.\n * `null` on deny, hold, or escalate decisions.\n */\n permitToken: string | null;\n /**\n * Machine-readable reasons emitted by the policy engine.\n *\n * The array may be empty. For deny/hold/escalate decisions the array\n * typically contains a single human-readable explanation; for allow\n * decisions it is often empty. Do not parse these strings — use\n * `decision` for branching.\n */\n reasons: string[];\n /** Human-readable explanation from the policy engine.\n *\n * @deprecated Prefer `reasons[0]` or `reasons`. This field is the\n * first element of `reasons` (or an empty string) for backward compat.\n */\n reason: string;\n /** Hash-chained audit-trail entry (21 CFR Part 11 / GxP-ready). */\n auditHash: string;\n /** ISO 8601 timestamp of the decision. */\n timestamp: string;\n /**\n * Per-key rate-limit state for this request's response, parsed from\n * `X-RateLimit-*` headers. `null` when the server didn't emit them.\n */\n rateLimit: RateLimitState | null;\n /**\n * Risk envelope summary from the policy engine. Present on all responses\n * from engine version wire-v1@1.0.0+. Provides the weighted risk score,\n * the pre/post-promotion decisions, and (when evaluate was called with\n * `explain: true`) a per-factor breakdown.\n *\n * The envelope can only raise severity — it structurally cannot soften\n * a deny to allow. When `promoted` is true the live `decision` was\n * upgraded from `engineDecision` to `envelopeDecision`.\n */\n riskEnvelope?: EvaluateRiskEnvelope;\n /**\n * Resolved risk class from the evaluation engine.\n * One of `\"critical\"`, `\"high\"`, `\"medium\"`, `\"low\"`.\n * Present when the risk envelope assigns a class.\n */\n riskClass?: string;\n /**\n * WHY this permit was issued — the authority kind and a reference to the\n * authorizing entity. Present on `allow` decisions when the control plane\n * attaches explicit authority provenance.\n */\n authorityBasis?: {\n kind: \"policy\" | \"approval\" | \"emergency\" | \"maintenance_window\" | \"delegation\" | \"quorum\";\n reference?: string;\n grantedBy?: string;\n rationale?: string;\n expiresAt?: string;\n };\n /**\n * ID of the HITL escalation auto-created by the control plane.\n * Present iff `decision === \"hold\"`. Poll `GET /v1/escalations/{id}`\n * for resolution status.\n */\n escalationId?: string;\n /**\n * Authorized execution trajectory returned when the engine approved a\n * `proposed_trajectory`. Present only on `allow` decisions.\n * May differ from what was proposed — the engine may add checkpoints,\n * restrict steps, or tighten time limits. Follow this trajectory exactly;\n * call `POST /v1/trajectory-verify` at each step to confirm on_trajectory.\n */\n authorized_trajectory?: {\n trajectory_id: string;\n steps: Array<{\n step: string;\n description?: string;\n required: boolean;\n time_limit_seconds?: number;\n authorized_by?: string;\n constraints?: Record<string, unknown>;\n expected_intermediate_state?: { description: string; attributes?: Record<string, unknown>; fingerprint?: string };\n }>;\n description?: string;\n forbidden_states?: Array<{ description: string; attributes?: Record<string, unknown>; fingerprint?: string }>;\n expires_at: string;\n };\n}\n\n/** Per-factor contribution in a {@link EvaluateRiskEnvelope}. */\nexport interface EvaluateRiskEnvelopeFactor {\n /** Factor identifier, e.g. `\"ACTION_SENSITIVITY\"`. */\n factor: string;\n /** Factor score in [0, 1]. Higher = more risk. */\n value: number;\n /** Configured weight for this factor. */\n weight: number;\n /** Human-readable explanation for the score. */\n reason: string;\n}\n\n/** Risk envelope summary returned in a top-level {@link EvaluateResponse}. */\nexport interface EvaluateRiskEnvelope {\n /** Weighted risk score in [0, 1]. Score ≥ 0.70 triggers a hold. */\n weightedScore: number;\n /** Policy engine decision before envelope promotion. */\n engineDecision: Decision;\n /** Decision resolved by the risk envelope. */\n envelopeDecision: Decision;\n /** `true` when the envelope raised the decision's severity (most-restrictive-wins). */\n promoted: boolean;\n /** Deny codes that unconditionally block regardless of score. */\n hardBlocks: string[];\n /** Per-factor breakdown. Present only when `explain: true` was passed. */\n factors?: EvaluateRiskEnvelopeFactor[];\n}\n\n/** Input to {@link AtlaSentClient.verifyPermit}. */\nexport interface VerifyPermitRequest {\n /** The permit ID returned by a prior evaluate() call. */\n permitId: string;\n /** Optional: re-state the action for cross-check with the server. */\n action?: string;\n /** Optional: re-state the agent for cross-check with the server. */\n agent?: string;\n /** Optional: re-state the context for cross-check with the server. */\n context?: Record<string, unknown>;\n /**\n * Environment of the permit being verified. Sourced from the evaluate\n * payload (context.environment → top-level environment → \"production\").\n * Required by the server for production permits as of 2026-05-14.\n * P1-1 fix: withPermit/protect now always populates this field.\n */\n environment?: string;\n /**\n * SHA-256 hex digest of the recursively key-sorted canonical JSON of the\n * original evaluate payload. Required by the server for production permits\n * as of 2026-05-14.\n * P1-5 fix: withPermit/protect now always computes and sends this field.\n */\n execution_hash?: string;\n}\n\n/**\n * Result of {@link AtlaSentClient.verifyPermit}.\n *\n * @deprecated Use {@link VerifyPermitByIdResponse} via\n * {@link AtlaSentClient.verifyPermitById} — the canonical REST surface\n * (`POST /v1/permits/{id}/verify`) returns the unified verification\n * envelope (`valid`, `verification_type`, `reason`, `verified_at`,\n * `evidence`) plus the full {@link PermitRecord} fields. Will be\n * removed in `@atlasent/sdk@3`.\n */\nexport interface VerifyPermitResponse {\n /** `true` when the permit is valid and un-revoked. */\n verified: boolean;\n /** Verification outcome string from the server. */\n outcome: string;\n /** Verification hash bound to the permit. */\n permitHash: string;\n /** ISO 8601 timestamp of the verification. */\n timestamp: string;\n /**\n * ISO-8601 expiration timestamp of the permit. `null` on pre-rollout\n * server versions that do not yet surface this field.\n */\n expiresAt: string | null;\n /**\n * Per-key rate-limit state for this request's response, parsed from\n * `X-RateLimit-*` headers. `null` when the server didn't emit them.\n */\n rateLimit: RateLimitState | null;\n}\n\n/**\n * Result of {@link AtlaSentClient.keySelf} — self-introspection of the API\n * key the client was constructed with. Returned by `GET /v1/api-key-self`.\n *\n * Never includes the raw key or its hash — introspection is intentionally\n * read-only and safe to surface in operator dashboards.\n */\nexport interface ApiKeySelfResponse {\n /** Server-side UUID of the api_keys row for this key. */\n keyId: string;\n /** Organization the key belongs to. */\n orgId: string;\n /** \"live\" or \"test\" (or any future environment label the server introduces). */\n environment: string;\n /** Granted scopes — e.g. [\"evaluate\", \"audit.read\"]. */\n scopes: string[];\n /**\n * Per-key IP allowlist as CIDR strings (e.g. [\"10.0.0.0/8\"]). `null`\n * when the key is unrestricted.\n */\n allowedCidrs: string[] | null;\n /** Server-enforced per-minute rate limit for this key. */\n rateLimitPerMinute: number;\n /** Client IP as the server observed it (first hop of X-Forwarded-For). */\n clientIp: string | null;\n /** Server-stored expiry; `null` means the key does not auto-expire. */\n expiresAt: string | null;\n /**\n * Per-key rate-limit state for this request's response, parsed from\n * `X-RateLimit-*` headers. `null` when the server didn't emit them.\n */\n rateLimit: RateLimitState | null;\n}\n\n/**\n * Result of {@link AtlaSentClient.listAuditEvents}. Extends the raw\n * wire page with a camelCase `rateLimit` alongside the snake_case\n * wire fields.\n */\nexport interface AuditEventsResult extends AuditEventsPage {\n rateLimit: RateLimitState | null;\n}\n\n/**\n * Filter accepted by {@link AtlaSentClient.createAuditExport}.\n */\nexport interface AuditExportRequest {\n /** Comma-joined list of event types to include. */\n types?: string;\n /** Filter to a single actor. */\n actor_id?: string;\n /** Inclusive lower bound on `occurred_at` (ISO 8601). */\n from?: string;\n /** Inclusive upper bound on `occurred_at` (ISO 8601). */\n to?: string;\n}\n\n/**\n * Result of {@link AtlaSentClient.createAuditExport}.\n */\nexport interface AuditExportResult extends AuditExport {\n rateLimit: RateLimitState | null;\n}\n\n/** Constructor options for {@link AtlaSentClient}. */\nexport interface AtlaSentClientOptions {\n /** Required. Your AtlaSent API key. */\n apiKey: string;\n /** API base URL. Defaults to \"https://api.atlasent.io\". */\n baseUrl?: string;\n /** Per-request timeout in milliseconds. Defaults to 10_000. */\n timeoutMs?: number;\n /**\n * Inject a fetch implementation (primarily for testing).\n * Defaults to `globalThis.fetch`.\n */\n fetch?: typeof fetch;\n /**\n * Retry policy for transient failures (network errors, timeouts,\n * 429 rate-limit, 5xx server errors, malformed responses).\n * Omit to use the default: 4 total attempts, 2 000 ms base, 16 000 ms cap,\n * full-jitter exponential backoff matching the Python SDK schedule\n * (2 s → 4 s → 8 s → 16 s).\n * Pass `{ maxAttempts: 1 }` to disable retries entirely.\n */\n retryPolicy?: import(\"./retry.js\").RetryPolicy;\n /**\n * Base URL for the trust-root host (default: https://keys.atlasent.io/.well-known).\n * Override for air-gapped / enterprise mirror deployments.\n * Per ADR-005 D2.\n */\n trustRootUrl?: string;\n /**\n * Trust-root snapshot refresh interval in milliseconds.\n * Default: 4 hours. Floor: 5 minutes (ADR-005 D2).\n * Set to 0 to inherit the default.\n */\n trustSnapshotRefreshMs?: number;\n}\n\n// ── Permit lifecycle (canonical REST shapes) ───────────────────────────────────────────\n\n/** Permit lifecycle status. */\nexport type PermitStatus =\n | \"issued\"\n | \"verified\"\n | \"consumed\"\n | \"expired\"\n | \"revoked\";\n\n/**\n * Wire shape of a Permit row, returned by {@link AtlaSentClient.getPermit}\n * and {@link AtlaSentClient.listPermits}.\n */\nexport interface PermitRecord {\n id: string;\n org_id: string;\n actor_id: string;\n action_id: string;\n target_id?: string;\n environment?: string;\n status: PermitStatus;\n issued_at: string;\n expires_at: string;\n consumed_at?: string | null;\n revoked_at?: string | null;\n revoked_by?: string | null;\n revoke_reason?: string | null;\n signature?: string;\n payload_hash?: string | null;\n decision_id?: string | null;\n /** SHA-256 hex of the CDO that produced this permit. P1 provisional. */\n cdo_hash?: string | null;\n}\n\n/** Optional filters for {@link AtlaSentClient.listPermits}. */\nexport interface ListPermitsRequest {\n status?: PermitStatus;\n actorId?: string;\n actionType?: string;\n from?: string;\n to?: string;\n limit?: number;\n cursor?: string;\n}\n\n/** Response from {@link AtlaSentClient.listPermits}. */\nexport interface ListPermitsResponse {\n permits: PermitRecord[];\n total: number;\n nextCursor?: string;\n rateLimit: RateLimitState | null;\n}\n\n/** Response from {@link AtlaSentClient.getPermit}. */\nexport interface GetPermitResponse {\n permit: PermitRecord;\n rateLimit: RateLimitState | null;\n}\n\n/**\n * Response from {@link AtlaSentClient.checkPermitValid}.\n */\nexport interface PermitValidResponse {\n valid: boolean;\n status: \"active\" | \"expired\" | \"revoked\" | \"consumed\";\n revoked_at?: string;\n revocation_id?: string;\n}\n\n// ── Canonical revoke / verify (REST) ──────────────────────────────────────────────────\n\n/** Input for {@link AtlaSentClient.revokePermitById}. */\nexport interface RevokePermitByIdInput {\n reason?: string;\n}\n\n/**\n * Response from {@link AtlaSentClient.revokePermitById}.\n */\nexport interface RevokePermitByIdResponse {\n permit: PermitRecord;\n rateLimit: RateLimitState | null;\n}\n\n/**\n * Response from {@link AtlaSentClient.verifyPermitById}.\n */\nexport interface VerifyPermitByIdResponse {\n valid: boolean;\n verification_type: \"permit\";\n reason: string | null;\n verified_at: string;\n evidence: {\n permit_id: string;\n status: PermitStatus;\n actor_id?: string;\n action_id?: string;\n expires_at?: string;\n payload_hash?: string | null;\n decision_id?: string | null;\n };\n permit: PermitRecord;\n rateLimit: RateLimitState | null;\n}\n\n// ── Revoke permit ─────────────────────────────────────────────────────────────────────────\n\n/** Input for {@link AtlaSentClient.revokePermit}. */\nexport interface RevokePermitRequest {\n permitId: string;\n reason?: string;\n}\n\n/**\n * Result of {@link AtlaSentClient.revokePermit}.\n *\n * @deprecated Use {@link RevokePermitByIdResponse} via\n * {@link AtlaSentClient.revokePermitById}.\n * Will be removed in `@atlasent/sdk@3`.\n */\nexport interface RevokePermitResponse {\n revoked: boolean;\n permitId: string;\n revokedAt?: string | undefined;\n auditHash?: string | undefined;\n rateLimit: RateLimitState | null;\n}\n\n// ── Constraint trace (preflight) ────────────────────────────────────────────────────────\n\nexport interface ConstraintTraceStage {\n readonly stage: string;\n readonly rule?: string;\n readonly matched: boolean;\n readonly detail?: string;\n readonly order: number;\n readonly [key: string]: unknown;\n}\n\nexport interface ConstraintTracePolicy {\n readonly policy_id: string;\n readonly decision: string;\n readonly fingerprint: string;\n readonly risk_score?: number;\n readonly stages: ReadonlyArray<ConstraintTraceStage>;\n readonly [key: string]: unknown;\n}\n\nexport interface ConstraintTrace {\n readonly rules_evaluated: ReadonlyArray<ConstraintTracePolicy>;\n readonly matching_policy_id?: string;\n readonly [key: string]: unknown;\n}\n\nexport interface EvaluatePreflightResponse {\n readonly evaluation: EvaluateResponse;\n readonly constraintTrace: ConstraintTrace | null;\n}\n\n// ── Streaming evaluate ─────────────────────────────────────────────────────────────────────\n\nexport interface StreamOptions {\n signal?: AbortSignal;\n timeoutMs?: number;\n maxRetries?: number;\n}\n\nexport interface StreamDecisionEvent {\n type: \"decision\";\n decision: Decision;\n decision_canonical: DecisionCanonical;\n permitId: string;\n reason: string;\n auditHash: string;\n timestamp: string;\n isFinal: boolean;\n}\n\nexport interface StreamProgressEvent {\n type: \"progress\";\n stage: string;\n [key: string]: unknown;\n}\n\nexport type StreamEvent = StreamDecisionEvent | StreamProgressEvent;\n\n// ── Batch evaluate ────────────────────────────────────────────────────────────────────────────\n\nexport interface BatchEvalItem {\n agent: string;\n action: string;\n context?: Record<string, unknown>;\n}\n\nexport interface EvaluateBatchResultItem {\n index: number;\n decision?: DecisionCanonical;\n decisionId?: string;\n permitToken?: string | null;\n reason?: string;\n auditHash?: string;\n timestamp?: string;\n error?: string;\n message?: string;\n}\n\nexport interface BatchEvalResponse {\n batchId: string;\n items: EvaluateBatchResultItem[];\n partial: boolean;\n replayed?: boolean;\n rateLimit: RateLimitState | null;\n}\n\n// ── Decisions stream ──────────────────────────────────────────────────────────────────────\n\nexport interface SubscribeDecisionsOptions {\n types?: string[];\n actorId?: string;\n lastEventId?: string;\n maxSeconds?: number;\n signal?: AbortSignal;\n}\n\nexport interface DecisionStreamEvent {\n id?: string;\n type: string;\n decision?: DecisionCanonical;\n actorId?: string;\n resourceType?: string;\n resourceId?: string;\n payload?: Record<string, unknown>;\n hash?: string;\n previousHash?: string;\n occurredAt?: string;\n}\n\n// ── Trajectory authorization ────────────────────────────────────────────────────────────\n\n/** Verified snapshot of resource state. */\nexport interface StateSnapshot {\n description: string;\n attributes?: Record<string, unknown>;\n /** Deterministic hash of the state (e.g. schema fingerprint, content hash). */\n fingerprint?: string;\n recorded_at?: string;\n}\n\n/** Step in an execution trajectory. */\nexport interface TrajectoryStep {\n step: string;\n description?: string;\n required: boolean;\n time_limit_seconds?: number;\n authorized_by?: string;\n constraints?: Record<string, unknown>;\n expected_intermediate_state?: StateSnapshot;\n}\n\n/** Actor-submitted trajectory proposal. */\nexport interface ProposedTrajectory {\n steps: TrajectoryStep[];\n description?: string;\n}\n\n/** Evaluation-engine-returned authorized trajectory. May differ from the proposed trajectory. */\nexport interface AuthorizedTrajectory extends ProposedTrajectory {\n trajectory_id: string;\n forbidden_states?: StateSnapshot[];\n expires_at: string;\n}\n\n/** Input to POST /v1/trajectory-verify. */\nexport interface TrajectoryVerifyRequest {\n permit_token: string;\n current_step: string;\n current_state?: StateSnapshot;\n completed_steps?: string[];\n execution_context?: Record<string, unknown>;\n}\n\n/** Response from POST /v1/trajectory-verify. */\nexport interface TrajectoryVerifyResponse {\n on_trajectory: boolean;\n trajectory_position?: number;\n trajectory_complete: boolean;\n deviation?: TrajectoryDeviationEvent;\n verified_at: string;\n}\n\n/** Deviation type for trajectory deviation events. */\nexport type TrajectoryDeviationType =\n | \"step_not_on_trajectory\"\n | \"step_out_of_sequence\"\n | \"forbidden_state_reached\"\n | \"required_step_skipped\"\n | \"time_limit_exceeded\"\n | \"constraint_violation\"\n | \"trajectory_expired\";\n\n/** Emitted when execution departs from the authorized trajectory. */\nexport interface TrajectoryDeviationEvent {\n deviation_type: TrajectoryDeviationType;\n trajectory_id: string;\n permit_id: string;\n step?: string;\n actual_state?: StateSnapshot;\n expected_state?: StateSnapshot;\n reason: string;\n detected_at: string;\n}\n\n/** Evidence artifact: authorized trajectory vs. actual execution trace. */\nexport interface ComplianceComparisonArtifact {\n version: \"compliance_comparison.v1\";\n artifact_id: string;\n authorized_transition: {\n permit_id: string;\n desired_state: StateSnapshot;\n trajectory: AuthorizedTrajectory;\n spec_signature?: string;\n };\n execution_trace: {\n executed_steps: Array<{\n step: string;\n started_at: string;\n completed_at?: string;\n outcome: \"success\" | \"failure\" | \"skipped\";\n state_after?: StateSnapshot;\n }>;\n final_state: StateSnapshot;\n trace_signature?: string;\n };\n fidelity: {\n compliant: boolean;\n /** Score in [0, 1] measuring closeness of actual to authorized trajectory. */\n fidelity_score: number;\n missing_required_steps: string[];\n unexpected_steps: string[];\n forbidden_states_reached: StateSnapshot[];\n deviation_events: TrajectoryDeviationEvent[];\n };\n artifact_hash: string;\n generated_at: string;\n}\n","/**\n * Dual-shape input bridge for the v2.0.0 wire format change.\n *\n * The v2.0.0 wire format renamed the evaluate request fields:\n * OLD: { action, agent, context, api_key }\n * NEW: { action_type, actor_id, context }\n *\n * And the response fields:\n * OLD: { permitted, decision_id }\n * NEW: { decision, permit_token }\n *\n * TypeScript callers on the old v1.x request shape receive a\n * deprecation warning and are transparently upgraded to the new\n * shape. The response compat bridge normalises the legacy\n * `permitted` boolean to `decision === \"allow\"`.\n *\n * Both shims will be removed in v3.0.0.\n */\n\n/** Legacy v1.x evaluate request shape. */\nexport interface LegacyEvaluateRequest {\n action?: string;\n agent?: string;\n context?: Record<string, unknown>;\n}\n\n/** v2.0 evaluate request shape (canonical wire format). */\nexport interface V2EvaluateRequest {\n action_type: string;\n actor_id: string;\n context?: Record<string, unknown>;\n /** Populate `risk_envelope.factors` in the response (Phase C). */\n explain?: boolean;\n /** Deployment environment where the action executes (e.g. `\"production\"`). */\n environment?: string;\n /** Structured resource descriptor. Prefer over `resource_id` for new callers. */\n resource?: { type: string; id?: string; attributes?: Record<string, unknown> };\n /** Snapshot of the resource before the proposed action. Enables state-transition-aware policy evaluation. */\n current_state?: { description: string; attributes?: Record<string, unknown> };\n /** Desired resource state after the action. */\n proposed_state?: { description: string; attributes?: Record<string, unknown> };\n /** Execution surface binding (CI/CD adapter, DB driver, etc.). */\n execution_binding?: { kind: string; adapter_version?: string; resource_id?: string; enforcement_point?: string };\n}\n\n/**\n * Normalise an evaluate request from either the legacy v1.x shape\n * (`action` / `agent`) or the current v2.0 shape (`action_type` /\n * `actor_id`) into the canonical v2.0 wire format.\n *\n * When the legacy shape is detected a `console.warn` deprecation\n * notice is emitted once per call-site process lifetime. The shim\n * will be removed in v3.0.0.\n */\nexport function normalizeEvaluateRequest(\n input: LegacyEvaluateRequest | V2EvaluateRequest,\n): V2EvaluateRequest {\n // Detect legacy shape: has `action` or `agent` but NOT `action_type` /\n // `actor_id`. Both old fields are optional in the legacy interface so\n // we key on the absence of the new fields.\n if ('action' in input && !('action_type' in input)) {\n // eslint-disable-next-line no-console\n console.warn(\n '[atlasent] Deprecation: action/agent request shape is deprecated. ' +\n 'Use action_type/actor_id instead. This compatibility shim will be removed in v3.0.0.',\n );\n const legacy = input as LegacyEvaluateRequest;\n const normalized: V2EvaluateRequest = {\n action_type: legacy.action!,\n actor_id: legacy.agent!,\n };\n if (legacy.context !== undefined) normalized.context = legacy.context;\n const l = legacy as any;\n if (l.explain !== undefined) normalized.explain = l.explain;\n if (l.environment !== undefined) normalized.environment = l.environment;\n if (l.resource !== undefined) normalized.resource = l.resource;\n if (l.current_state !== undefined) normalized.current_state = l.current_state;\n if (l.proposed_state !== undefined) normalized.proposed_state = l.proposed_state;\n if (l.execution_binding !== undefined) normalized.execution_binding = l.execution_binding;\n return normalized;\n }\n return input as V2EvaluateRequest;\n}\n\n/**\n * Legacy v1.x evaluate response shape returned by older server\n * deployments.\n */\nexport interface LegacyEvaluateResponse {\n permitted?: boolean;\n decision_id?: string;\n reason?: string;\n audit_hash?: string;\n timestamp?: string;\n}\n\n/** v2.0 evaluate response shape (canonical wire format). */\nexport interface V2EvaluateResponse {\n decision: 'allow' | 'deny' | 'hold' | 'escalate';\n permit_token?: string;\n request_id?: string;\n expires_at?: string;\n denial?: { reason?: string; code?: string };\n}\n\n/**\n * Normalise an evaluate response from either the legacy v1.x shape\n * (`permitted` / `decision_id`) or the current v2.0 shape\n * (`decision` / `permit_token`) into the canonical v2.0 wire format.\n *\n * Used internally by the client to tolerate older atlasent-api\n * deployments without surfacing the impedance mismatch to callers.\n */\nexport function normalizeEvaluateResponse(\n wire: LegacyEvaluateResponse | V2EvaluateResponse,\n): V2EvaluateResponse {\n if (!('decision' in wire) && 'permitted' in wire) {\n // Legacy server — map `permitted` boolean → canonical `decision`.\n const legacy = wire as LegacyEvaluateResponse;\n const normalized: V2EvaluateResponse = {\n decision: legacy.permitted ? 'allow' : 'deny',\n };\n if (legacy.decision_id !== undefined) {\n normalized.permit_token = legacy.decision_id;\n }\n if (!legacy.permitted && legacy.reason) {\n normalized.denial = { reason: legacy.reason };\n }\n return normalized;\n }\n return wire as V2EvaluateResponse;\n}\n","/**\n * Retry-policy helpers for the AtlaSent TypeScript SDK.\n *\n * This module is **pure**: no I/O, no network, no globals beyond\n * `Math.random`. The intent is that {@link AtlaSentClient} (and any\n * caller wrapping `protect()` / `evaluate()`) can ask\n * {@link isRetryable} whether to retry a given {@link AtlaSentError},\n * then ask {@link computeBackoffMs} how long to sleep before the next\n * attempt.\n *\n * Wire-up into the client itself is intentionally deferred — see\n * ROADMAP item #7 (Post-GA). Sentry breadcrumb emission is also\n * deferred; both will land together once a transport-level retry\n * loop is wired into `client.ts`.\n *\n * Retry classification (matches the server's documented contract):\n * - `network` / `timeout` → retry (transient transport)\n * - `server_error` (HTTP 5xx) → retry\n * - `rate_limited` (HTTP 429) → retry, honour `retryAfterMs`\n * - `bad_response` → retry (likely truncated body)\n * - `invalid_api_key`/`forbidden`/`bad_request` → never retry\n *\n * Backoff: capped exponential with full jitter.\n * delay = min(maxDelayMs, baseDelayMs * 2^attempt) * random[0, 1)\n *\n * \"Full jitter\" is the AWS-recommended scheme — see\n * https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/.\n * It avoids thundering-herd retries from many SDK instances that hit\n * a 429 in the same window.\n *\n * Default schedule:\n * attempt 0 (1st retry): base 250 ms, jittered in [0, 250)\n * attempt 1 (2nd retry): base 500 ms, jittered in [0, 500)\n * Total attempts (including initial): 3\n */\n\nimport { AtlaSentError, type AtlaSentErrorCode } from \"./errors.js\";\n\n/**\n * Defaults for {@link RetryPolicy}.\n *\n * Exponential backoff with full jitter, base 250 ms, capped at 10 s:\n * attempt 0 (1st retry): base 250 ms, jittered in [0, 250)\n * attempt 1 (2nd retry): base 500 ms, jittered in [0, 500)\n * Total attempts (including initial): 3\n */\nexport const DEFAULT_RETRY_POLICY: Required<RetryPolicy> = {\n maxAttempts: 3,\n baseDelayMs: 250,\n maxDelayMs: 10_000,\n};\n\n/**\n * Caller-tunable retry policy. All fields optional; missing fields\n * fall back to {@link DEFAULT_RETRY_POLICY}.\n */\nexport interface RetryPolicy {\n /**\n * Total attempts including the first try. `1` disables retries\n * entirely. Must be `>= 1`; values below are clamped to `1`.\n */\n maxAttempts?: number;\n /**\n * Initial backoff for `attempt = 0`. Doubles per attempt up to\n * `maxDelayMs`. Must be `>= 0`.\n */\n baseDelayMs?: number;\n /**\n * Hard ceiling on the per-attempt sleep, applied **before** jitter.\n * The actual sleep is uniformly distributed in `[0, ceiling]`.\n */\n maxDelayMs?: number;\n}\n\n/**\n * Error codes the SDK considers transient. A `Set` (rather than a\n * `switch`) keeps callers free to extend the policy in the future\n * without forking this module.\n */\nconst RETRYABLE_CODES: ReadonlySet<AtlaSentErrorCode> = new Set([\n \"network\",\n \"timeout\",\n \"rate_limited\",\n \"server_error\",\n \"bad_response\",\n]);\n\n/**\n * Decide whether `err` is worth a retry. Anything that isn't an\n * {@link AtlaSentError} is treated as non-retryable — the SDK's\n * transport layer always wraps fetch failures in `AtlaSentError`,\n * so a non-AtlaSent throwable is by definition a programmer bug\n * (a bad input, an assertion in user code) and should propagate.\n */\nexport function isRetryable(err: unknown): boolean {\n if (!(err instanceof AtlaSentError)) return false;\n if (err.code === undefined) return false;\n return RETRYABLE_CODES.has(err.code);\n}\n\n/**\n * Compute how long to sleep before retry attempt `attempt`\n * (zero-indexed: `attempt = 0` is the first retry, i.e. the second\n * total request). Uses capped exponential backoff with full jitter.\n *\n * When `err` carries a `retryAfterMs` (server-provided `Retry-After`\n * header), the result is `max(retryAfterMs, jitteredDelay)` — the\n * server's hint is treated as a floor so we never retry sooner than\n * the server asked.\n *\n * @param attempt Zero-indexed retry attempt (0, 1, 2, ...). For\n * the default policy this produces delays drawn from\n * [0, 2 000), [0, 4 000), [0, 8 000), [0, 16 000).\n * @param policy Optional override of {@link DEFAULT_RETRY_POLICY}.\n * @param err Optional error whose `retryAfterMs` is honoured.\n * @param random Injectable RNG, defaults to `Math.random`. Must\n * return values in `[0, 1)` to preserve the\n * distribution.\n */\nexport function computeBackoffMs(\n attempt: number,\n policy: RetryPolicy = {},\n err?: unknown,\n random: () => number = Math.random,\n): number {\n const merged = mergePolicy(policy);\n const safeAttempt = Math.max(0, Math.floor(attempt));\n // 2^attempt grows exponentially; cap before multiplying to keep the\n // intermediate value bounded for very large `attempt`.\n const exp = Math.min(safeAttempt, 30);\n const ceiling = Math.min(merged.maxDelayMs, merged.baseDelayMs * 2 ** exp);\n const jittered = Math.floor(ceiling * clampUnit(random()));\n\n const retryAfterMs =\n err instanceof AtlaSentError && typeof err.retryAfterMs === \"number\"\n ? Math.max(0, err.retryAfterMs)\n : 0;\n\n return Math.max(retryAfterMs, jittered);\n}\n\n/**\n * Returns `true` when `attempt` (zero-indexed) is below the policy's\n * `maxAttempts - 1` ceiling — i.e. when there is still budget for at\n * least one more try after this one. Convenience wrapper so retry\n * loops read top-to-bottom:\n *\n * ```ts\n * for (let attempt = 0; ; attempt++) {\n * try { return await op(); }\n * catch (err) {\n * if (!isRetryable(err) || !hasAttemptsLeft(attempt, policy)) throw err;\n * await sleep(computeBackoffMs(attempt, policy, err));\n * }\n * }\n * ```\n */\nexport function hasAttemptsLeft(\n attempt: number,\n policy: RetryPolicy = {},\n): boolean {\n const merged = mergePolicy(policy);\n return attempt + 1 < merged.maxAttempts;\n}\n\n/**\n * Merge a partial policy with {@link DEFAULT_RETRY_POLICY} and clamp\n * each field into a sensible range. Exported for tests and for\n * callers that want to log the resolved policy.\n */\nexport function mergePolicy(policy: RetryPolicy): Required<RetryPolicy> {\n const maxAttempts = Math.max(\n 1,\n Math.floor(policy.maxAttempts ?? DEFAULT_RETRY_POLICY.maxAttempts),\n );\n const baseDelayMs = Math.max(\n 0,\n policy.baseDelayMs ?? DEFAULT_RETRY_POLICY.baseDelayMs,\n );\n const maxDelayMs = Math.max(\n baseDelayMs,\n policy.maxDelayMs ?? DEFAULT_RETRY_POLICY.maxDelayMs,\n );\n return { maxAttempts, baseDelayMs, maxDelayMs };\n}\n\n/**\n * Clamp `n` into `[0, 1)`. Defends against a misbehaving injected\n * RNG returning `NaN`, `Infinity`, or a negative number.\n */\nfunction clampUnit(n: number): number {\n if (!Number.isFinite(n)) return 0;\n if (n < 0) return 0;\n if (n >= 1) return 0.999_999_999;\n return n;\n}\n","/**\n * SCIM 2.0 provisioning client — user and group lifecycle management.\n *\n * Wire surface: /scim/v2/* endpoints in atlasent-api (RFC 7643/7644).\n *\n * Usage:\n *\n * ```ts\n * import { AtlaSentClient } from \"@atlasent/sdk\";\n *\n * const client = new AtlaSentClient({ apiKey: \"...\" });\n *\n * const page = await client.scim.users.list({ orgId: \"org_abc\" });\n * for (const user of page.Resources) {\n * console.log(user.userName);\n * }\n *\n * const newUser = await client.scim.users.create(\"org_abc\", {\n * userName: \"alice@example.com\",\n * displayName: \"Alice Example\",\n * active: true,\n * emails: [{ value: \"alice@example.com\", primary: true }],\n * });\n * ```\n */\n\n// ─── SCIM schema URNs ─────────────────────────────────────────────────────────\n\nexport const SCIM_USER_SCHEMA =\n \"urn:ietf:params:scim:schemas:core:2.0:User\" as const;\nexport const SCIM_GROUP_SCHEMA =\n \"urn:ietf:params:scim:schemas:core:2.0:Group\" as const;\nexport const SCIM_PATCH_OP_SCHEMA =\n \"urn:ietf:params:scim:api:messages:2.0:PatchOp\" as const;\n\n// ─── SCIM resource types ──────────────────────────────────────────────────────\n\n/** SCIM email value. */\nexport interface ScimEmail {\n value: string;\n type?: string;\n primary?: boolean;\n}\n\n/** SCIM name component. */\nexport interface ScimName {\n formatted?: string;\n givenName?: string;\n familyName?: string;\n}\n\n/** Group reference embedded on a user. */\nexport interface ScimGroupRef {\n value: string;\n display?: string;\n}\n\n/** SCIM metadata block. */\nexport interface ScimMeta {\n resourceType?: string;\n created?: string;\n lastModified?: string;\n location?: string;\n version?: string;\n}\n\n/** SCIM 2.0 User resource. */\nexport interface ScimUser {\n schemas?: string[];\n id?: string;\n userName: string;\n displayName?: string;\n active?: boolean;\n emails?: ScimEmail[];\n name?: ScimName;\n groups?: ScimGroupRef[];\n meta?: ScimMeta;\n [k: string]: unknown;\n}\n\n/** Create payload for a new SCIM user. `schemas` is injected automatically. */\nexport type ScimUserCreate = Omit<ScimUser, \"id\" | \"meta\">;\n\n/** Update payload for an existing SCIM user. */\nexport type ScimUserUpdate = ScimUser;\n\n/** RFC 7644 PatchOp operation. */\nexport interface ScimPatchOp {\n op: \"add\" | \"remove\" | \"replace\";\n path?: string;\n value?: unknown;\n}\n\n/** SCIM 2.0 ListResponse envelope (generic). */\nexport interface ScimListResponse<T = unknown> {\n schemas: string[];\n totalResults: number;\n startIndex: number;\n itemsPerPage: number;\n Resources: T[];\n}\n\n/** Query parameters for SCIM list operations. */\nexport interface ScimListParams {\n /** Organisation ID (required). */\n orgId: string;\n /** SCIM filter expression, e.g. `userName eq \"alice@example.com\"`. */\n filter?: string;\n /** 1-based pagination offset. Defaults to 1 on the server. */\n startIndex?: number;\n /** Maximum results per page. Defaults to 100 on the server. */\n count?: number;\n}\n\n// ─── Sub-client interfaces ───────────────────────────────────────────────────\n\n/** Sub-client for /scim/v2/{orgId}/Users operations. */\nexport interface ScimUsersSubClient {\n /**\n * `GET /scim/v2/{orgId}/Users` — list provisioned users.\n *\n * ```ts\n * const page = await client.scim.users.list({ orgId: \"org_abc\" });\n * ```\n */\n list(params: ScimListParams): Promise<ScimListResponse<ScimUser>>;\n\n /**\n * `POST /scim/v2/{orgId}/Users` — provision a new user.\n *\n * ```ts\n * const user = await client.scim.users.create(\"org_abc\", {\n * userName: \"alice@example.com\",\n * active: true,\n * emails: [{ value: \"alice@example.com\", primary: true }],\n * });\n * ```\n */\n create(orgId: string, user: ScimUserCreate): Promise<ScimUser>;\n\n /**\n * `PUT /scim/v2/{orgId}/Users/{id}` — full replacement.\n *\n * ```ts\n * const updated = await client.scim.users.update(\"org_abc\", \"usr_123\", user);\n * ```\n */\n update(\n orgId: string,\n id: string,\n user: ScimUserUpdate,\n ): Promise<ScimUser>;\n\n /**\n * `DELETE /scim/v2/{orgId}/Users/{id}` — deprovision a user.\n *\n * ```ts\n * await client.scim.users.delete(\"org_abc\", \"usr_123\");\n * ```\n */\n delete(orgId: string, id: string): Promise<void>;\n}\n\n/** Sub-client for /scim/v2/{orgId}/Groups operations. */\nexport interface ScimGroupsSubClient {\n /** `GET /scim/v2/{orgId}/Groups` — list groups. */\n list(params: ScimListParams): Promise<ScimListResponse<Record<string, unknown>>>;\n /** `POST /scim/v2/{orgId}/Groups` — create a group. */\n create(orgId: string, group: Record<string, unknown>): Promise<Record<string, unknown>>;\n /** `DELETE /scim/v2/{orgId}/Groups/{id}` — delete a group. */\n delete(orgId: string, id: string): Promise<void>;\n}\n\n/** Top-level SCIM sub-client exposed as `client.scim`. */\nexport interface ScimSubClient {\n users: ScimUsersSubClient;\n groups: ScimGroupsSubClient;\n}\n\n// ─── Factory ─────────────────────────────────────────────────────────────────\n\ntype PostFn = <T>(\n path: string,\n body: unknown,\n query?: URLSearchParams,\n) => Promise<{ body: T }>;\n\ntype GetFn = <T>(\n path: string,\n query?: URLSearchParams,\n) => Promise<{ body: T }>;\n\ntype PutFn = <T>(\n path: string,\n body: unknown,\n) => Promise<{ body: T }>;\n\ntype DeleteFn = (path: string) => Promise<void>;\n\nfunction scimUsersPath(orgId: string): string {\n return `/scim/v2/${encodeURIComponent(orgId)}/Users`;\n}\n\nfunction scimGroupsPath(orgId: string): string {\n return `/scim/v2/${encodeURIComponent(orgId)}/Groups`;\n}\n\nfunction buildScimQuery(\n filter?: string,\n startIndex?: number,\n count?: number,\n): URLSearchParams | undefined {\n const params = new URLSearchParams();\n if (filter !== undefined) params.set(\"filter\", filter);\n if (startIndex !== undefined) params.set(\"startIndex\", String(startIndex));\n if (count !== undefined) params.set(\"count\", String(count));\n return params.size > 0 ? params : undefined;\n}\n\n/**\n * Factory that returns the SCIM sub-client bound to a host client.\n * Called internally by AtlaSentClient; not part of the public constructor API.\n */\nexport function makeScimClient(\n postFn: PostFn,\n getFn: GetFn,\n putFn: PutFn,\n deleteFn: DeleteFn,\n): ScimSubClient {\n const users: ScimUsersSubClient = {\n async list(params: ScimListParams): Promise<ScimListResponse<ScimUser>> {\n const qs = buildScimQuery(\n params.filter,\n params.startIndex,\n params.count,\n );\n const { body } = await getFn<ScimListResponse<ScimUser>>(\n scimUsersPath(params.orgId),\n qs,\n );\n return body;\n },\n\n async create(orgId: string, user: ScimUserCreate): Promise<ScimUser> {\n const payload = user.schemas\n ? user\n : { ...user, schemas: [SCIM_USER_SCHEMA] };\n const { body } = await postFn<ScimUser>(scimUsersPath(orgId), payload);\n return body;\n },\n\n async update(\n orgId: string,\n id: string,\n user: ScimUserUpdate,\n ): Promise<ScimUser> {\n const payload = user.schemas\n ? user\n : { ...user, schemas: [SCIM_USER_SCHEMA] };\n const { body } = await putFn<ScimUser>(\n `${scimUsersPath(orgId)}/${encodeURIComponent(id)}`,\n payload,\n );\n return body;\n },\n\n async delete(orgId: string, id: string): Promise<void> {\n return deleteFn(\n `${scimUsersPath(orgId)}/${encodeURIComponent(id)}`,\n );\n },\n };\n\n const groups: ScimGroupsSubClient = {\n async list(\n params: ScimListParams,\n ): Promise<ScimListResponse<Record<string, unknown>>> {\n const qs = buildScimQuery(\n params.filter,\n params.startIndex,\n params.count,\n );\n const { body } = await getFn<ScimListResponse<Record<string, unknown>>>(\n scimGroupsPath(params.orgId),\n qs,\n );\n return body;\n },\n\n async create(\n orgId: string,\n group: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n const payload =\n group[\"schemas\"] ? group : { ...group, schemas: [SCIM_GROUP_SCHEMA] };\n const { body } = await postFn<Record<string, unknown>>(\n scimGroupsPath(orgId),\n payload,\n );\n return body;\n },\n\n async delete(orgId: string, id: string): Promise<void> {\n return deleteFn(\n `${scimGroupsPath(orgId)}/${encodeURIComponent(id)}`,\n );\n },\n };\n\n return { users, groups };\n}\n","/**\n * Evidence Bundle helpers — create, retrieve, and download compliance\n * evidence bundles for incident investigations and audit export.\n *\n * Wire surface: POST/GET /v1/evidence-bundles\n *\n * Usage:\n *\n * ```ts\n * import { AtlaSentClient } from \"@atlasent/sdk\";\n *\n * const client = new AtlaSentClient({ apiKey: \"...\" });\n *\n * // Create\n * const bundle = await client.evidenceBundles.create({\n * incidentId: \"inc_abc123\",\n * includeOverrides: true,\n * });\n *\n * // Get\n * const bundle2 = await client.evidenceBundles.get(bundle.bundleId);\n *\n * // Download as JSON or PDF\n * const pdf = await client.evidenceBundles.download(bundle.bundleId, \"pdf\");\n * ```\n */\n\n/** Status of an evidence bundle. */\nexport type EvidenceBundleStatus =\n | \"pending\"\n | \"building\"\n | \"ready\"\n | \"failed\"\n | \"expired\";\n\n/** An evidence bundle record returned by the API. */\nexport interface EvidenceBundle {\n /** Server-assigned bundle identifier. */\n bundleId: string;\n /** Organisation the bundle belongs to. */\n orgId: string;\n /** Incident or investigation ID this bundle was created for. */\n incidentId: string;\n /** Current bundle status. */\n status: EvidenceBundleStatus;\n /** Permit IDs included in the bundle (empty = all permits for the incident). */\n includedPermits: string[];\n /** Whether override events are included. */\n includeOverrides: boolean;\n /** Format used when the bundle was created. */\n format: \"json\" | \"pdf\";\n /** ISO 8601 creation time. */\n createdAt: string;\n /** ISO 8601 expiration time. */\n expiresAt: string;\n /** Pre-signed download URL (populated when status is `ready`). */\n downloadUrl?: string;\n /** Free-form metadata supplied at creation. */\n metadata?: Record<string, unknown>;\n}\n\n/** Input to {@link EvidenceBundlesMixin.create}. */\nexport interface EvidenceBundleCreateParams {\n /** Incident or investigation ID for this bundle. */\n incidentId: string;\n /**\n * Optional list of specific permit IDs to include.\n * When omitted, all permits associated with the incident are included.\n */\n includedPermits?: string[];\n /**\n * When `true`, override events are embedded in the bundle.\n * Defaults to `false`.\n */\n includeOverrides?: boolean;\n}\n\n/** Query parameters for {@link EvidenceBundleSubClient.list}. */\nexport interface EvidenceBundleListParams {\n /** Filter bundles to a specific execution ID. */\n executionId?: string;\n /** Maximum number of bundles to return. */\n limit?: number;\n /** Opaque cursor from a previous list response for pagination. */\n cursor?: string;\n}\n\n/** Paginated response from {@link EvidenceBundleSubClient.list}. */\nexport interface EvidenceBundleListPage {\n /** Evidence bundles for this page. */\n bundles: EvidenceBundle[];\n /** Pass as `cursor` to `list()` to fetch the next page. `null` means no more pages. */\n nextCursor: string | null;\n}\n\n/** Wire shape for the list response. */\ninterface EvidenceBundleListWire {\n bundles: EvidenceBundleWire[];\n next_cursor?: string | null;\n}\n\n/** Wire shape returned by POST /v1/evidence-bundles. */\ninterface EvidenceBundleWire {\n bundle_id: string;\n org_id: string;\n incident_id: string;\n status: EvidenceBundleStatus;\n included_permits: string[];\n include_overrides: boolean;\n format: \"json\" | \"pdf\";\n created_at: string;\n expires_at: string;\n download_url?: string;\n metadata?: Record<string, unknown>;\n}\n\nfunction wireToBundle(w: EvidenceBundleWire): EvidenceBundle {\n return {\n bundleId: w.bundle_id,\n orgId: w.org_id,\n incidentId: w.incident_id,\n status: w.status,\n includedPermits: w.included_permits ?? [],\n includeOverrides: w.include_overrides ?? false,\n format: w.format,\n createdAt: w.created_at,\n expiresAt: w.expires_at,\n ...(w.download_url !== undefined ? { downloadUrl: w.download_url } : {}),\n ...(w.metadata !== undefined ? { metadata: w.metadata } : {}),\n };\n}\n\n/**\n * Sub-client for evidence bundle operations.\n * Accessed as `client.evidenceBundles` on {@link AtlaSentClient}.\n */\nexport interface EvidenceBundleSubClient {\n /**\n * List evidence bundles for the org, with optional filters and pagination.\n *\n * ```ts\n * const page = await client.evidenceBundles.list({ limit: 20 });\n * for (const bundle of page.bundles) { ... }\n * if (page.nextCursor) {\n * const next = await client.evidenceBundles.list({ cursor: page.nextCursor });\n * }\n * ```\n */\n list(params?: EvidenceBundleListParams): Promise<EvidenceBundleListPage>;\n\n /**\n * Create a new evidence bundle.\n *\n * ```ts\n * const bundle = await client.evidenceBundles.create({\n * incidentId: \"inc_abc123\",\n * includeOverrides: true,\n * });\n * ```\n */\n create(params: EvidenceBundleCreateParams): Promise<EvidenceBundle>;\n\n /**\n * Retrieve an evidence bundle by ID.\n *\n * ```ts\n * const bundle = await client.evidenceBundles.get(\"bnd_xyz\");\n * ```\n */\n get(bundleId: string): Promise<EvidenceBundle>;\n\n /**\n * Download the evidence bundle contents.\n *\n * @param bundleId - The bundle to download.\n * @param format - `\"json\"` (default) or `\"pdf\"`.\n * @returns Raw bytes of the downloaded file.\n *\n * ```ts\n * const pdf = await client.evidenceBundles.download(\"bnd_xyz\", \"pdf\");\n * await fs.writeFile(\"bundle.pdf\", pdf);\n * ```\n */\n download(bundleId: string, format?: \"json\" | \"pdf\"): Promise<Buffer>;\n}\n\n/**\n * Factory that returns the evidence-bundles sub-client bound to a host\n * client. Called internally by AtlaSentClient; not part of the public\n * constructor API.\n */\nexport function makeEvidenceBundleClient(\n postFn: <T>(path: string, body: unknown) => Promise<{ body: T }>,\n getFn: <T>(path: string, query?: URLSearchParams) => Promise<{ body: T }>,\n getRawFn: (path: string) => Promise<ArrayBuffer>,\n): EvidenceBundleSubClient {\n return {\n async list(params: EvidenceBundleListParams = {}): Promise<EvidenceBundleListPage> {\n const qs = new URLSearchParams();\n if (params.executionId !== undefined) qs.set(\"execution_id\", params.executionId);\n if (params.limit !== undefined) qs.set(\"limit\", String(params.limit));\n if (params.cursor !== undefined) qs.set(\"cursor\", params.cursor);\n const { body } = await getFn<EvidenceBundleListWire>(\"/v1/evidence-bundles\", qs.size > 0 ? qs : undefined);\n return {\n bundles: (body.bundles ?? []).map(wireToBundle),\n nextCursor: body.next_cursor ?? null,\n };\n },\n\n async create(params: EvidenceBundleCreateParams): Promise<EvidenceBundle> {\n const payload: Record<string, unknown> = {\n incident_id: params.incidentId,\n };\n if (params.includedPermits !== undefined) {\n payload[\"included_permits\"] = params.includedPermits;\n }\n if (params.includeOverrides !== undefined) {\n payload[\"include_overrides\"] = params.includeOverrides;\n }\n const { body } = await postFn<EvidenceBundleWire>(\n \"/v1/evidence-bundles\",\n payload,\n );\n return wireToBundle(body);\n },\n\n async get(bundleId: string): Promise<EvidenceBundle> {\n const { body } = await getFn<EvidenceBundleWire>(\n `/v1/evidence-bundles/${encodeURIComponent(bundleId)}`,\n );\n return wireToBundle(body);\n },\n\n async download(\n bundleId: string,\n format: \"json\" | \"pdf\" = \"json\",\n ): Promise<Buffer> {\n const qs = new URLSearchParams({ format });\n const raw = await getRawFn(\n `/v1/evidence-bundles/${encodeURIComponent(bundleId)}/download?${qs}`,\n );\n return Buffer.from(raw);\n },\n };\n}\n","/**\n * Auth helpers — token management and multi-IdP token refresh.\n *\n * Wire surface: /v1/auth/* endpoints in atlasent-api.\n *\n * Usage:\n *\n * ```ts\n * import { AtlaSentClient } from \"@atlasent/sdk\";\n *\n * const client = new AtlaSentClient({ apiKey: \"...\" });\n *\n * // Refresh using the default IdP\n * const tokens = await client.auth.refresh(currentRefreshToken);\n *\n * // Refresh using a specific IdP (multi-IdP orgs)\n * const tokens = await client.auth.refreshWithIdp(\"idp_okta_prod\", currentRefreshToken);\n *\n * // List IdP connections\n * const connections = await client.auth.listIdpConnections();\n * ```\n */\n\n/** A token response from the auth endpoints. */\nexport interface TokenResponse {\n accessToken: string;\n refreshToken: string;\n tokenType: string;\n expiresIn: number;\n scope?: string;\n /** IdP that issued the token (populated on multi-IdP responses). */\n idpId?: string;\n}\n\n/** Wire shape for token responses. */\ninterface TokenResponseWire {\n access_token: string;\n refresh_token: string;\n token_type: string;\n expires_in: number;\n scope?: string;\n idp_id?: string;\n}\n\nfunction wireToTokenResponse(w: TokenResponseWire): TokenResponse {\n return {\n accessToken: w.access_token,\n refreshToken: w.refresh_token,\n tokenType: w.token_type,\n expiresIn: w.expires_in,\n ...(w.scope !== undefined ? { scope: w.scope } : {}),\n ...(w.idp_id !== undefined ? { idpId: w.idp_id } : {}),\n };\n}\n\n/** An IdP connection record. */\nexport interface IdpConnection {\n id: string;\n name: string;\n provider: string;\n enabled: boolean;\n isDefault: boolean;\n domains?: string[];\n createdAt: string;\n}\n\n/** Wire shape for an IdP connection. */\ninterface IdpConnectionWire {\n id: string;\n name: string;\n provider: string;\n enabled: boolean;\n default: boolean;\n domains?: string[];\n created_at: string;\n}\n\nfunction wireToIdpConnection(w: IdpConnectionWire): IdpConnection {\n return {\n id: w.id,\n name: w.name,\n provider: w.provider,\n enabled: w.enabled,\n isDefault: w.default,\n ...(w.domains !== undefined ? { domains: w.domains } : {}),\n createdAt: w.created_at,\n };\n}\n\n/** Sub-client for token management and multi-IdP auth. */\nexport interface AuthSubClient {\n /**\n * Refresh an access token using the default IdP connection.\n *\n * ```ts\n * const tokens = await client.auth.refresh(currentRefreshToken);\n * ```\n */\n refresh(refreshToken: string): Promise<TokenResponse>;\n\n /**\n * Refresh an access token against a specific IdP connection.\n *\n * Use this in multi-IdP organisations where the caller needs to\n * specify which SSO connection to use for the token exchange.\n *\n * `idpId` corresponds to the connection ID returned by\n * `listIdpConnections()` (e.g. `\"idp_okta_prod\"`, `\"idp_entra\"`).\n *\n * ```ts\n * const tokens = await client.auth.refreshWithIdp(\n * \"idp_okta_prod\",\n * currentRefreshToken,\n * );\n * ```\n */\n refreshWithIdp(idpId: string, refreshToken: string): Promise<TokenResponse>;\n\n /**\n * List IdP connections available for this organisation.\n *\n * ```ts\n * const connections = await client.auth.listIdpConnections();\n * const primary = connections.find(c => c.isDefault);\n * ```\n */\n listIdpConnections(): Promise<IdpConnection[]>;\n}\n\n/**\n * Factory that returns the auth sub-client bound to a host client.\n * Called internally by AtlaSentClient; not part of the public constructor API.\n */\nexport function makeAuthClient(\n postFn: <T>(path: string, body: unknown) => Promise<{ body: T }>,\n getFn: <T>(path: string) => Promise<{ body: T }>,\n): AuthSubClient {\n return {\n async refresh(refreshToken: string): Promise<TokenResponse> {\n const { body } = await postFn<TokenResponseWire>(\n \"/v1/auth/token/refresh\",\n { refresh_token: refreshToken, grant_type: \"refresh_token\" },\n );\n return wireToTokenResponse(body);\n },\n\n async refreshWithIdp(\n idpId: string,\n refreshToken: string,\n ): Promise<TokenResponse> {\n const path = `/v1/auth/idp/${encodeURIComponent(idpId)}/token/refresh`;\n const { body } = await postFn<TokenResponseWire>(path, {\n refresh_token: refreshToken,\n grant_type: \"refresh_token\",\n idp_id: idpId,\n });\n return wireToTokenResponse(body);\n },\n\n async listIdpConnections(): Promise<IdpConnection[]> {\n const { body } = await getFn<{ connections: IdpConnectionWire[] }>(\n \"/v1/auth/idp-connections\",\n );\n return (body.connections ?? []).map(wireToIdpConnection);\n },\n };\n}\n","/**\n * SSO administration — connections, JIT rules, events, enforcement state\n * machine, and the `client.sso` sub-client.\n *\n * Usage:\n *\n * ```ts\n * import { AtlaSentClient } from \"@atlasent/sdk\";\n *\n * const client = new AtlaSentClient({ apiKey: \"...\" });\n *\n * const { connections } = await client.sso.listConnections();\n * const status = await client.sso.getStatus();\n * await client.sso.enforce(\"enable\");\n * ```\n */\n\n// ── Connections ───────────────────────────────────────────────────────────────\n\n/** An SSO connection record (SAML 2.0 or OIDC). */\nexport interface SsoConnection {\n id: string;\n organizationId: string;\n name: string;\n protocol: \"saml\" | \"oidc\";\n idpEntityId: string;\n metadataUrl: string | null;\n metadataXml: string | null;\n emailDomain: string | null;\n enforceForDomain: boolean;\n isActive: boolean;\n supabaseProviderId: string | null;\n createdBy: string;\n createdAt: string;\n updatedAt: string;\n}\n\n/** Wire (snake_case) shape for SSO connection responses. */\nexport interface SsoConnectionWire {\n id: string;\n organization_id: string;\n name: string;\n protocol: \"saml\" | \"oidc\";\n idp_entity_id: string;\n metadata_url: string | null;\n metadata_xml: string | null;\n email_domain: string | null;\n enforce_for_domain: boolean;\n is_active: boolean;\n supabase_provider_id: string | null;\n created_by: string;\n created_at: string;\n updated_at: string;\n}\n\nexport function wireToSsoConnection(w: SsoConnectionWire): SsoConnection {\n return {\n id: w.id,\n organizationId: w.organization_id,\n name: w.name,\n protocol: w.protocol,\n idpEntityId: w.idp_entity_id,\n metadataUrl: w.metadata_url,\n metadataXml: w.metadata_xml,\n emailDomain: w.email_domain,\n enforceForDomain: w.enforce_for_domain,\n isActive: w.is_active,\n supabaseProviderId: w.supabase_provider_id,\n createdBy: w.created_by,\n createdAt: w.created_at,\n updatedAt: w.updated_at,\n };\n}\n\n// ── JIT provisioning rules ───────────────────────────────────────────────────\n\nexport type SsoRole = \"owner\" | \"admin\" | \"approver\" | \"member\" | \"viewer\";\n\n/** A JIT provisioning rule that maps an IdP claim to an org role. */\nexport interface SsoJitRule {\n id: string;\n connectionId: string;\n organizationId: string;\n claimAttribute: string;\n claimValue: string;\n grantedRole: SsoRole;\n precedence: number;\n isActive: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\n/** Wire (snake_case) shape for JIT rule responses. */\nexport interface SsoJitRuleWire {\n id: string;\n connection_id: string;\n organization_id: string;\n claim_attribute: string;\n claim_value: string;\n granted_role: SsoRole;\n precedence: number;\n is_active: boolean;\n created_at: string;\n updated_at: string;\n}\n\nexport function wireToSsoJitRule(w: SsoJitRuleWire): SsoJitRule {\n return {\n id: w.id,\n connectionId: w.connection_id,\n organizationId: w.organization_id,\n claimAttribute: w.claim_attribute,\n claimValue: w.claim_value,\n grantedRole: w.granted_role,\n precedence: w.precedence,\n isActive: w.is_active,\n createdAt: w.created_at,\n updatedAt: w.updated_at,\n };\n}\n\n// ── Events ───────────────────────────────────────────────────────────────────\n\n/**\n * An SSO lifecycle event — login, session, config change, break-glass, or\n * JIT provisioning.\n */\nexport interface SsoEvent {\n id: string;\n organizationId: string;\n connectionId: string | null;\n eventType: string;\n actorEmail: string | null;\n payload: Record<string, unknown>;\n occurredAt: string;\n}\n\n/** Wire (snake_case) shape for SSO event responses. */\nexport interface SsoEventWire {\n id: string;\n organization_id: string;\n connection_id: string | null;\n event_type: string;\n actor_email: string | null;\n payload: Record<string, unknown>;\n occurred_at: string;\n}\n\nexport function wireToSsoEvent(w: SsoEventWire): SsoEvent {\n return {\n id: w.id,\n organizationId: w.organization_id,\n connectionId: w.connection_id,\n eventType: w.event_type,\n actorEmail: w.actor_email,\n payload: w.payload,\n occurredAt: w.occurred_at,\n };\n}\n\n// ── Enforcement state machine ─────────────────────────────────────────────────\n\n/** Action to pass to `POST /v1/sso/enforce`. */\nexport type SsoEnforceAction = \"enable\" | \"enforce\";\n\n/**\n * Four-boolean readiness checklist returned by `GET /v1/sso/status`.\n * All four must be `true` before enforcement is safe to activate.\n */\nexport interface SsoReadiness {\n /** At least one SSO connection row exists for the org. */\n connectionConfigured: boolean;\n /** At least one connection has been activated (registered with the IdP). */\n connectionTested: boolean;\n /** Break-glass access has been configured (non-default settings). */\n breakGlassSet: boolean;\n /** No unreviewed active service API keys exist. */\n serviceApiKeysReviewed: boolean;\n}\n\n/** Wire (snake_case) shape for the readiness response. */\nexport interface SsoReadinessWire {\n connection_configured: boolean;\n connection_tested: boolean;\n break_glass_set: boolean;\n service_api_keys_reviewed: boolean;\n}\n\nexport function wireToSsoReadiness(w: SsoReadinessWire): SsoReadiness {\n return {\n connectionConfigured: w.connection_configured,\n connectionTested: w.connection_tested,\n breakGlassSet: w.break_glass_set,\n serviceApiKeysReviewed: w.service_api_keys_reviewed,\n };\n}\n\n// ── Sub-client ────────────────────────────────────────────────────────────────\n\n/** Input for creating a JIT provisioning rule. */\nexport interface SsoJitRuleInput {\n connectionId: string;\n claimAttribute: string;\n claimValue: string;\n grantedRole: SsoRole;\n precedence?: number;\n}\n\n/** Patchable fields for an existing JIT rule. */\nexport interface SsoJitRulePatch {\n claimAttribute?: string;\n claimValue?: string;\n grantedRole?: SsoRole;\n precedence?: number;\n isActive?: boolean;\n}\n\n/** Input for creating or updating an SSO connection. */\nexport interface SsoConnectionInput {\n name: string;\n protocol: \"saml\" | \"oidc\";\n idpEntityId: string;\n metadataUrl?: string | null;\n metadataXml?: string | null;\n emailDomain?: string | null;\n enforceForDomain?: boolean;\n}\n\n/** Result of `POST /v1/sso/enforce`. */\nexport interface SsoEnforceResult {\n ok: boolean;\n action: SsoEnforceAction;\n enforceSso: boolean;\n enforceSsoAt: string | null;\n}\n\ninterface SsoEnforceResultWire {\n ok: boolean;\n action: SsoEnforceAction;\n enforce_sso: boolean;\n enforce_sso_at: string | null;\n}\n\n/**\n * Sub-client for SSO administration.\n * Accessed as `client.sso` on {@link AtlaSentClient}.\n */\nexport interface SsoSubClient {\n /** List all SSO connections for the org. */\n listConnections(): Promise<{ connections: SsoConnection[] }>;\n\n /** Get a single SSO connection by ID. */\n getConnection(id: string): Promise<SsoConnection>;\n\n /** Create a new SSO connection. */\n createConnection(input: SsoConnectionInput): Promise<SsoConnection>;\n\n /** Update an existing SSO connection. */\n updateConnection(id: string, input: Partial<SsoConnectionInput>): Promise<SsoConnection>;\n\n /** Delete an SSO connection. */\n deleteConnection(id: string): Promise<void>;\n\n /** Activate (register) a connection with the IdP. */\n activateConnection(id: string): Promise<{ ok: boolean; supabaseProviderId: string | null }>;\n\n /**\n * Advance the SSO enforcement state machine.\n * `\"enable\"` → SSO enabled, not yet enforced.\n * `\"enforce\"` → SSO mandatory for all members (requires readiness checklist to pass).\n */\n enforce(action: SsoEnforceAction): Promise<SsoEnforceResult>;\n\n /** Get the four-boolean enforcement readiness checklist. */\n getStatus(): Promise<SsoReadiness>;\n\n // ── JIT provisioning rules ───────────────────────────────────────────────\n\n /** List JIT provisioning rules, optionally filtered to a single connection. */\n listJitRules(connectionId?: string): Promise<{ rules: SsoJitRule[] }>;\n\n /** Create a new JIT provisioning rule. */\n createJitRule(input: SsoJitRuleInput): Promise<SsoJitRule>;\n\n /** Update fields on an existing JIT rule. */\n patchJitRule(id: string, patch: SsoJitRulePatch): Promise<SsoJitRule>;\n\n /** Delete a JIT provisioning rule. */\n deleteJitRule(id: string): Promise<void>;\n}\n\nfunction ssoConnectionInputToWire(input: SsoConnectionInput | Partial<SsoConnectionInput>): Record<string, unknown> {\n const w: Record<string, unknown> = {};\n if (input.name !== undefined) w[\"name\"] = input.name;\n if (input.protocol !== undefined) w[\"protocol\"] = input.protocol;\n if (input.idpEntityId !== undefined) w[\"idp_entity_id\"] = input.idpEntityId;\n if (input.metadataUrl !== undefined) w[\"metadata_url\"] = input.metadataUrl;\n if (input.metadataXml !== undefined) w[\"metadata_xml\"] = input.metadataXml;\n if (input.emailDomain !== undefined) w[\"email_domain\"] = input.emailDomain;\n if (input.enforceForDomain !== undefined) w[\"enforce_for_domain\"] = input.enforceForDomain;\n return w;\n}\n\n/**\n * Factory that returns the SSO sub-client bound to a host client's transport\n * helpers. Called internally by AtlaSentClient; not part of the public API.\n */\nexport function makeSsoClient(\n getFn: <T>(path: string, query?: URLSearchParams) => Promise<{ body: T }>,\n postFn: <T>(path: string, body: unknown) => Promise<{ body: T }>,\n patchFn: <T>(path: string, body: unknown) => Promise<{ body: T }>,\n deleteFn: (path: string) => Promise<void>,\n): SsoSubClient {\n return {\n async listConnections() {\n const { body } = await getFn<{ connections: SsoConnectionWire[] }>(\"/v1/sso/connections\");\n return { connections: (body.connections ?? []).map(wireToSsoConnection) };\n },\n\n async getConnection(id: string) {\n const { body } = await getFn<SsoConnectionWire>(`/v1/sso/connections/${encodeURIComponent(id)}`);\n return wireToSsoConnection(body);\n },\n\n async createConnection(input: SsoConnectionInput) {\n const { body } = await postFn<SsoConnectionWire>(\"/v1/sso/connections\", ssoConnectionInputToWire(input));\n return wireToSsoConnection(body);\n },\n\n async updateConnection(id: string, input: Partial<SsoConnectionInput>) {\n const { body } = await patchFn<SsoConnectionWire>(\n `/v1/sso/connections/${encodeURIComponent(id)}`,\n ssoConnectionInputToWire(input),\n );\n return wireToSsoConnection(body);\n },\n\n async deleteConnection(id: string) {\n await deleteFn(`/v1/sso/connections/${encodeURIComponent(id)}`);\n },\n\n async activateConnection(id: string) {\n const { body } = await postFn<{ ok: boolean; supabase_provider_id: string | null }>(\n `/v1/sso/connections/${encodeURIComponent(id)}/activate`,\n {},\n );\n return { ok: body.ok, supabaseProviderId: body.supabase_provider_id };\n },\n\n async enforce(action: SsoEnforceAction) {\n const { body } = await postFn<SsoEnforceResultWire>(\"/v1/sso/enforce\", { action });\n return {\n ok: body.ok,\n action: body.action,\n enforceSso: body.enforce_sso,\n enforceSsoAt: body.enforce_sso_at,\n };\n },\n\n async getStatus() {\n const { body } = await getFn<{ readiness: SsoReadinessWire }>(\"/v1/sso/status\");\n return wireToSsoReadiness(body.readiness);\n },\n\n async listJitRules(connectionId?: string) {\n const qs = connectionId ? new URLSearchParams({ connection_id: connectionId }) : undefined;\n const { body } = await getFn<{ rules: SsoJitRuleWire[] }>(\"/v1/sso/jit-rules\", qs);\n return { rules: (body.rules ?? []).map(wireToSsoJitRule) };\n },\n\n async createJitRule(input: SsoJitRuleInput) {\n const payload: Record<string, unknown> = {\n connection_id: input.connectionId,\n claim_attribute: input.claimAttribute,\n claim_value: input.claimValue,\n granted_role: input.grantedRole,\n };\n if (input.precedence !== undefined) payload[\"precedence\"] = input.precedence;\n const { body } = await postFn<SsoJitRuleWire>(\"/v1/sso/jit-rules\", payload);\n return wireToSsoJitRule(body);\n },\n\n async patchJitRule(id: string, patch: SsoJitRulePatch) {\n const payload: Record<string, unknown> = {};\n if (patch.claimAttribute !== undefined) payload[\"claim_attribute\"] = patch.claimAttribute;\n if (patch.claimValue !== undefined) payload[\"claim_value\"] = patch.claimValue;\n if (patch.grantedRole !== undefined) payload[\"granted_role\"] = patch.grantedRole;\n if (patch.precedence !== undefined) payload[\"precedence\"] = patch.precedence;\n if (patch.isActive !== undefined) payload[\"is_active\"] = patch.isActive;\n const { body } = await patchFn<SsoJitRuleWire>(\n `/v1/sso/jit-rules/${encodeURIComponent(id)}`,\n payload,\n );\n return wireToSsoJitRule(body);\n },\n\n async deleteJitRule(id: string) {\n await deleteFn(`/v1/sso/jit-rules/${encodeURIComponent(id)}`);\n },\n };\n}\n","/**\n * Access Governance Log sub-client — paginated identity lifecycle events.\n *\n * Wire surface: GET /v1/access-governance-log\n *\n * Usage:\n *\n * ```ts\n * import { AtlaSentClient } from \"@atlasent/sdk\";\n *\n * const client = new AtlaSentClient({ apiKey: \"...\" });\n *\n * const page = await client.accessGovernanceLog.list({ limit: 50 });\n * for (const event of page.events) {\n * console.log(event.eventType, event.actorEmail);\n * }\n * if (page.nextCursor) {\n * const next = await client.accessGovernanceLog.list({ cursor: page.nextCursor });\n * }\n * ```\n */\n\n// ── Wire shape ────────────────────────────────────────────────────────────────\n\ninterface AccessGovernanceEventWire {\n id: string;\n event_type: string;\n org_id: string;\n actor_id: string | null;\n actor_email: string | null;\n ip_address: string | null;\n metadata: Record<string, unknown>;\n created_at: string;\n}\n\ninterface AccessGovernanceLogResponseWire {\n events: AccessGovernanceEventWire[];\n next_cursor: string | null;\n total_count: number;\n}\n\n// ── SDK shape ─────────────────────────────────────────────────────────────────\n\n/** A single identity lifecycle event from the access governance log. */\nexport interface AccessGovernanceEvent {\n id: string;\n eventType: string;\n orgId: string;\n actorId: string | null;\n actorEmail: string | null;\n ipAddress: string | null;\n metadata: Record<string, unknown>;\n createdAt: string;\n}\n\n/** A page of access governance events with cursor for the next page. */\nexport interface AccessGovernanceLogPage {\n events: AccessGovernanceEvent[];\n /** Pass as `cursor` to `list()` to fetch the next page. `null` means no more pages. */\n nextCursor: string | null;\n totalCount: number;\n}\n\n/** Query parameters for `accessGovernanceLog.list()`. */\nexport interface AccessGovernanceLogQuery {\n /** Max events to return. Default 50, max 200. */\n limit?: number;\n /** Cursor from a previous page's `nextCursor`. */\n cursor?: string;\n /** Filter by event type (e.g. `\"sso.login\"`, `\"jit.provisioned\"`). */\n eventType?: string;\n /** Filter by actor email or UUID. */\n actorId?: string;\n /** Lower bound on event timestamp (ISO 8601). */\n from?: string;\n /** Upper bound on event timestamp (ISO 8601). */\n to?: string;\n}\n\n// ── Converter ─────────────────────────────────────────────────────────────────\n\nfunction wireToEvent(w: AccessGovernanceEventWire): AccessGovernanceEvent {\n return {\n id: w.id,\n eventType: w.event_type,\n orgId: w.org_id,\n actorId: w.actor_id,\n actorEmail: w.actor_email,\n ipAddress: w.ip_address,\n metadata: w.metadata ?? {},\n createdAt: w.created_at,\n };\n}\n\n// ── Sub-client ────────────────────────────────────────────────────────────────\n\n/**\n * Sub-client for the access governance log.\n * Accessed as `client.accessGovernanceLog` on {@link AtlaSentClient}.\n */\nexport interface AccessGovernanceLogSubClient {\n /**\n * Fetch a page of identity lifecycle events for the authenticated org.\n *\n * ```ts\n * const { events, nextCursor } = await client.accessGovernanceLog.list({\n * eventType: \"sso.login\",\n * limit: 100,\n * });\n * ```\n */\n list(query?: AccessGovernanceLogQuery): Promise<AccessGovernanceLogPage>;\n}\n\n/**\n * Factory that returns the access-governance-log sub-client bound to a host\n * client's transport helpers. Called internally by AtlaSentClient.\n */\nexport function makeAccessGovernanceLogClient(\n getFn: <T>(path: string, query?: URLSearchParams) => Promise<{ body: T }>,\n): AccessGovernanceLogSubClient {\n return {\n async list(query: AccessGovernanceLogQuery = {}): Promise<AccessGovernanceLogPage> {\n const qs = new URLSearchParams();\n if (query.limit !== undefined) qs.set(\"limit\", String(query.limit));\n if (query.cursor) qs.set(\"cursor\", query.cursor);\n if (query.eventType) qs.set(\"event_type\", query.eventType);\n if (query.actorId) qs.set(\"actor_id\", query.actorId);\n if (query.from) qs.set(\"from\", query.from);\n if (query.to) qs.set(\"to\", query.to);\n\n const { body } = await getFn<AccessGovernanceLogResponseWire>(\n \"/v1/access-governance-log\",\n qs.size > 0 ? qs : undefined,\n );\n\n return {\n events: (body.events ?? []).map(wireToEvent),\n nextCursor: body.next_cursor,\n totalCount: body.total_count ?? 0,\n };\n },\n };\n}\n","/**\n * AtlaSent HTTP client.\n *\n * Two public methods, both backed by native `fetch`:\n * - {@link AtlaSentClient.evaluate} → POST {baseUrl}/v1-evaluate\n * - {@link AtlaSentClient.verifyPermit} → POST {baseUrl}/v1-verify-permit\n *\n * Fail-closed: a clean policy DENY is returned (not thrown), but\n * network, timeout, bad response, 4xx/5xx, and rate-limit conditions\n * all throw {@link AtlaSentError}.\n */\n\nimport type {\n AuditEventsPage,\n AuditEventsQuery,\n AuditExport,\n} from \"./audit.js\";\nimport type { ReplayDecisionResponse } from \"./replay.js\";\nimport type {\n ReplayRequest,\n ReplayResponse,\n ReplayVarianceKind,\n} from \"./replay.js\";\nimport {\n AtlaSentError,\n StreamParseError,\n StreamTimeoutError,\n type AtlaSentErrorCode,\n type AtlaSentErrorInit,\n} from \"./errors.js\";\nimport {\n TrustRootManager,\n getGlobalTrustRootManager,\n type TrustRootSnapshot,\n} from \"./trustRoot.js\";\nimport { PRODUCTION_DEPLOY_ACTION } from \"./types.js\";\nimport type {\n ApiKeySelfResponse,\n AtlaSentClientOptions,\n Decision,\n AuditEventsResult,\n AuditExportRequest,\n AuditExportResult,\n ConstraintTrace,\n DecisionCanonical,\n DecisionStreamEvent,\n DeployGateEvidence,\n DeployGateRequest,\n DeployGateResponse,\n BatchEvalItem,\n BatchEvalResponse,\n EvaluateBatchResultItem,\n EvaluatePreflightResponse,\n SubscribeDecisionsOptions,\n EvaluateRequest,\n EvaluateResponse,\n GetPermitResponse,\n ListPermitsRequest,\n ListPermitsResponse,\n PermitRecord,\n PermitValidResponse,\n RateLimitState,\n RevokePermitByIdInput,\n RevokePermitByIdResponse,\n RevokePermitRequest,\n RevokePermitResponse,\n StreamDecisionEvent,\n StreamEvent,\n StreamOptions,\n StreamProgressEvent,\n VerifyPermitByIdResponse,\n VerifyPermitRequest,\n VerifyPermitResponse,\n} from \"./types.js\";\nimport {\n normalizeEvaluateRequest,\n type LegacyEvaluateRequest,\n type V2EvaluateRequest,\n} from \"./compat.js\";\nimport {\n computeBackoffMs,\n hasAttemptsLeft,\n isRetryable,\n mergePolicy,\n type RetryPolicy,\n} from \"./retry.js\";\nimport type {\n GovernanceAgent,\n GovernanceAgentEvaluation,\n GovernanceAgentFinding,\n ListGovernanceAgentsResponse,\n ListGovernanceEvaluationsQuery,\n ListGovernanceEvaluationsResponse,\n ListGovernanceFindingsQuery,\n ListGovernanceFindingsResponse,\n} from \"./governanceAgents.js\";\nimport type {\n HitlApprovalRecord,\n HitlApproveRequest,\n HitlChainHop,\n HitlCreateRequest,\n HitlEscalateRequest,\n HitlEscalation,\n HitlRejectRequest,\n ListHitlEscalationsRequest,\n ListHitlEscalationsResponse,\n} from \"./hitl.js\";\nimport type {\n GovernanceGraphQueryType,\n GovernanceGraphQueryParams,\n GovernanceGraphQueryResponse,\n GovernanceGraphResultRow,\n} from \"./governanceGraph.js\";\nimport type { IncidentTimelineResponse } from \"./incidentReconstruction.js\";\nimport type {\n ConnectorType,\n InstallConnectorInput,\n AuthenticateConnectorInput,\n UpsertEnforcementPolicyInput,\n ListConnectorsResponse,\n InstallConnectorResponse,\n AuthenticateConnectorResponse,\n SyncConnectorResponse,\n RevokeConnectorResponse,\n RotateCredentialsResponse,\n ListEnforcementPoliciesResponse,\n UpsertEnforcementPolicyResponse,\n} from \"./connectorManagement.js\";\nimport type {\n ComputeOrgRiskOptions,\n ComputeOrgRiskResponse,\n GetLatestOrgRiskResponse,\n ListOrgRiskHistoryResponse,\n} from \"./orgRiskGraph.js\";\nimport type {\n CrossOrgPermissionCheckRequest,\n CrossOrgPermissionCheckResult,\n CrossOrgPermissionCheckListParams,\n} from \"./crossOrgPermission.js\";\nimport type {\n AnomalyResponseRule,\n AnomalyResponseEvent,\n CreateAnomalyResponseRuleRequest,\n TriggerAnomalyResponseRequest,\n} from \"./anomalyResponse.js\";\nimport type {\n BudgetExceptionRequest,\n BudgetExceptionStatus,\n CreateBudgetExceptionRequest,\n ApproveBudgetExceptionRequest,\n} from \"./budgetExceptions.js\";\nimport type {\n RegulatoryAuthorityLevel,\n RegulatoryEscalation,\n RegulatoryEscalationStatus,\n CreateRegulatoryEscalationRequest,\n} from \"./regulatoryEscalation.js\";\nimport type {\n GovernanceSignalAction,\n RecordSignalActionRequest,\n RecordSignalOutcomeRequest,\n SignalActionSummary,\n} from \"./incentiveSignalFeedback.js\";\nimport type {\n CrossOrgImpersonationGrant,\n CreateImpersonationGrantRequest,\n ImpersonationToken,\n ImpersonationValidationResult,\n} from \"./crossOrgImpersonation.js\";\nimport {\n makeScimClient,\n type ScimSubClient,\n} from \"./scim.js\";\nimport {\n makeEvidenceBundleClient,\n type EvidenceBundleSubClient,\n} from \"./evidence-bundle.js\";\nimport {\n makeAuthClient,\n type AuthSubClient,\n} from \"./auth.js\";\nimport {\n makeSsoClient,\n type SsoSubClient,\n} from \"./sso.js\";\nimport {\n makeAccessGovernanceLogClient,\n type AccessGovernanceLogSubClient,\n} from \"./access-governance-log.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.atlasent.io\";\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst SDK_VERSION = \"2.10.0\";\n\n/**\n * Guard flag: emit the browser-environment warning at most once per\n * module-load lifetime. Prevents console spam when many client\n * instances are constructed in the same bundle.\n */\nlet warnedBrowser = false;\nconst V1_EVALUATE_BATCH_PATH = \"/v1/evaluate/batch\";\nconst V1_EVALUATE_BATCH_LEGACY_PATH = \"/v1-evaluate-batch\";\nconst V1_EVALUATE_STREAM_PATH = \"/v1/evaluate/stream\";\nconst V1_EVALUATE_STREAM_LEGACY_PATH = \"/v1-evaluate-stream\";\n\nfunction _buildUserAgent(): string {\n const isNode =\n typeof process !== \"undefined\" &&\n typeof process?.versions?.node === \"string\";\n return isNode\n ? `@atlasent/sdk/${SDK_VERSION} node/${process.version}`\n : `@atlasent/sdk/${SDK_VERSION} browser`;\n}\n\n// Soft cap on top-level context properties. Mirrors the Python SDK\n// (atlasent.models._CONTEXT_PROPERTIES_SOFT_CAP) and the OpenAPI\n// `maxProperties: 64` declaration. The hosted API is the canonical\n// enforcer; this helper warns the developer in dev rather than\n// raising, so production traffic isn't broken on the day this ships.\nconst CONTEXT_PROPERTIES_SOFT_CAP = 64;\n\nfunction _warnOversizeContext(\n context: Record<string, unknown> | undefined,\n): void {\n if (context && Object.keys(context).length > CONTEXT_PROPERTIES_SOFT_CAP) {\n // eslint-disable-next-line no-console\n console.warn(\n `[atlasent] context has ${Object.keys(context).length} top-level keys ` +\n `(soft cap ${CONTEXT_PROPERTIES_SOFT_CAP}); the server may reject this. ` +\n \"Pack richer payloads under a single top-level key.\",\n );\n }\n}\n\n/**\n * Reject non-TLS base URLs unless the dev escape hatch is set.\n *\n * `ATLASENT_ALLOW_INSECURE_HTTP=1` (Node) or\n * `globalThis.ATLASENT_ALLOW_INSECURE_HTTP === \"1\"` (browser dev) permits\n * `http://` for local fixtures — production callers never set this.\n * Non-`http(s)` schemes (data:, file:, ...) are rejected unconditionally.\n *\n * Guards `process.env` access with an explicit `typeof` check so this\n * function is safe in browser and edge-runtime environments where\n * `process` is not defined as a global.\n */\nfunction _enforceTls(baseUrl: string): string {\n const nodeEnvValue =\n typeof process !== \"undefined\" && process.env\n ? process.env.ATLASENT_ALLOW_INSECURE_HTTP\n : undefined;\n const allow =\n nodeEnvValue === \"1\" ||\n (globalThis as { ATLASENT_ALLOW_INSECURE_HTTP?: string })\n .ATLASENT_ALLOW_INSECURE_HTTP === \"1\";\n if (allow) return baseUrl;\n let parsed: URL;\n try {\n parsed = new URL(baseUrl);\n } catch {\n throw new AtlaSentError(`Invalid baseUrl: ${baseUrl}`, {\n code: \"bad_request\",\n });\n }\n if (parsed.protocol !== \"https:\") {\n throw new AtlaSentError(\n `AtlaSent baseUrl must use https:// (got ${parsed.protocol}). ` +\n `For local development, set ATLASENT_ALLOW_INSECURE_HTTP=1.`,\n { code: \"bad_request\" },\n );\n }\n return baseUrl;\n}\n\n// API-key prefix contract per atlasent-api/_shared/auth.ts:\n// \"ask_live_<entropy>\" — production\n// \"ask_test_<entropy>\" — non-production\n// Validated client-side so a mis-pasted key (with whitespace, quotes,\n// or a leftover wrapping char) trips loudly at construction rather\n// than yielding a 401 mid-conversation.\nconst API_KEY_PATTERN = /^ask_(?:live|test)_[A-Za-z0-9_-]+$/;\n\nfunction _validateApiKey(apiKey: string): string {\n if (typeof apiKey !== \"string\" || apiKey.length === 0) {\n throw new AtlaSentError(\"apiKey is required\", { code: \"invalid_api_key\" });\n }\n if (!API_KEY_PATTERN.test(apiKey)) {\n const head = apiKey.slice(0, 8);\n throw new AtlaSentError(\n `AtlaSent apiKey does not match expected shape ` +\n `\\`ask_(live|test)_<entropy>\\` (got prefix=${JSON.stringify(head)}). ` +\n \"Check for whitespace, quotes, or trailing characters.\",\n { code: \"invalid_api_key\" },\n );\n }\n return apiKey;\n}\n\n/**\n * True when running in Node.js (or a Node-compatible server runtime that\n * exposes `process.versions.node`). False in browsers and browser-like\n * environments such as jsdom / Cloudflare Workers.\n */\nconst isNode =\n typeof process !== \"undefined\" && typeof process.versions?.node === \"string\";\n\n/**\n * Node.js version string captured at module-load time so request code\n * never accesses `process` lazily — safe even if `process` is absent\n * (browsers) or replaced after load (bundlers, test environments).\n * `null` in every non-Node runtime.\n */\nconst NODE_VERSION: string | null = isNode ? process.version : null;\n\n/**\n * Raw JSON shape received from `POST /v1-evaluate`.\n *\n * Canonical fields (per `atlasent-api/.../v1-evaluate/handler.ts`):\n * decision: \"allow\" | \"deny\" | \"hold\" | \"escalate\"\n * permit_token: string (present iff decision === \"allow\")\n * request_id: string\n * expires_at?: string\n * denial?: { reason, code }\n *\n * Legacy fields kept on the type so older atlasent-api deployments\n * (pre-handler.ts entry swap) still parse cleanly. The client below\n * checks canonical first and falls back to legacy.\n */\ninterface EvaluateWire {\n decision: \"allow\" | \"deny\" | \"hold\" | \"escalate\";\n permit_token?: string;\n request_id?: string;\n expires_at?: string;\n denial?: { reason?: string; code?: string };\n /**\n * Optional sub-object — present iff the request URL carried\n * `?include=constraint_trace`. Older atlasent-api deployments\n * omit this even when `include` was requested; the preflight\n * helper degrades to `null` in that case.\n */\n constraint_trace?: unknown;\n // Legacy passthrough.\n permitted?: boolean;\n decision_id?: string;\n reason?: string;\n audit_hash?: string;\n timestamp?: string;\n risk_envelope?: {\n weighted_score: number;\n engine_decision: string;\n envelope_decision: string;\n promoted: boolean;\n hard_blocks: string[];\n factors?: Array<{ factor: string; value: number; weight: number; reason: string }>;\n };\n // State-context response fields (control-plane v2+).\n risk_class?: string;\n authority_basis?: {\n kind: string;\n reference?: string;\n granted_by?: string;\n rationale?: string;\n expires_at?: string;\n };\n escalation_id?: string;\n}\n\ninterface EvaluateBatchWireItem {\n index: number;\n decision?: string;\n decision_id?: string;\n permit_token?: string | null;\n reason?: string | null;\n audit_entry_hash?: string;\n timestamp?: string;\n error?: string;\n message?: string;\n status?: number;\n}\n\ninterface EvaluateBatchWire {\n batch_id: string;\n items: EvaluateBatchWireItem[];\n partial?: boolean;\n replayed?: boolean;\n}\n\nfunction deployGateEvidence(input: {\n permitId?: string;\n permitHash?: string;\n auditHash?: string;\n verifiedAt?: string;\n}): DeployGateEvidence {\n const evidence: DeployGateEvidence = {};\n if (input.permitId) evidence.permitId = input.permitId;\n if (input.permitHash) evidence.permitHash = input.permitHash;\n if (input.auditHash) evidence.auditHash = input.auditHash;\n if (input.verifiedAt) evidence.verifiedAt = input.verifiedAt;\n return evidence;\n}\n\n/** Raw JSON shape received from `GET /v1-api-key-self`. */\ninterface ApiKeySelfWire {\n key_id: string;\n org_id: string;\n environment: string;\n scopes?: string[];\n allowed_cidrs?: string[] | null;\n rate_limit_per_minute: number;\n client_ip?: string | null;\n expires_at?: string | null;\n}\n\n/**\n * Raw JSON shape received from `POST /v1-verify-permit`.\n *\n * Canonical fields:\n * valid: boolean\n * outcome: \"allow\" | \"deny\"\n * verify_error_code?: string (populated on outcome === \"deny\")\n * reason?: string\n *\n * Legacy `verified` kept for backward-compat with older deployments.\n */\ninterface VerifyPermitWire {\n valid: boolean;\n outcome: \"allow\" | \"deny\";\n verify_error_code?: string;\n reason?: string;\n expires_at?: string | null;\n // Legacy passthrough.\n verified?: boolean;\n permit_hash?: string;\n timestamp?: string;\n}\n\nexport class AtlaSentClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly timeoutMs: number;\n private readonly fetchImpl: typeof fetch;\n private readonly userAgent: string;\n private readonly retryPolicy: Required<RetryPolicy>;\n\n /** SCIM 2.0 provisioning sub-client. Access as `client.scim`. */\n readonly scim: ScimSubClient;\n /** Evidence bundle sub-client. Access as `client.evidenceBundles`. */\n readonly evidenceBundles: EvidenceBundleSubClient;\n /** Auth / token management sub-client. Access as `client.auth`. */\n readonly auth: AuthSubClient;\n /** SSO administration sub-client. Access as `client.sso`. */\n readonly sso: SsoSubClient;\n /** Access governance log sub-client. Access as `client.accessGovernanceLog`. */\n readonly accessGovernanceLog: AccessGovernanceLogSubClient;\n /** Trust-root snapshot manager for this client instance. */\n readonly trustRoot: TrustRootManager;\n\n constructor(options: AtlaSentClientOptions) {\n if (!options.apiKey || typeof options.apiKey !== \"string\") {\n throw new AtlaSentError(\"apiKey is required\", {\n code: \"invalid_api_key\",\n });\n }\n if (typeof AbortSignal.timeout !== \"function\") {\n throw new AtlaSentError(\n \"@atlasent/sdk requires AbortSignal.timeout, which is not available in this runtime. \" +\n \"Minimum supported browsers: Chrome 103+, Firefox 100+, Safari 16+. \" +\n \"Upgrade your browser or add an AbortSignal.timeout polyfill.\",\n { code: \"network\" },\n );\n }\n if (\n !warnedBrowser &&\n typeof (globalThis as Record<string, unknown>)[\"window\"] !== \"undefined\" &&\n typeof process === \"undefined\"\n ) {\n warnedBrowser = true;\n // eslint-disable-next-line no-console\n console.warn(\n \"[@atlasent/sdk] Running in a browser environment. \" +\n \"API keys should not be exposed in client-side bundles. \" +\n \"Use a server-side proxy instead.\",\n );\n }\n this.apiKey = _validateApiKey(options.apiKey);\n this.baseUrl = _enforceTls(options.baseUrl ?? DEFAULT_BASE_URL).replace(\n /\\/+$/,\n \"\",\n );\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);\n this.userAgent = _buildUserAgent();\n this.retryPolicy = mergePolicy(options.retryPolicy ?? {});\n this.scim = makeScimClient(\n (path, body, query) => this._post(path, body, query),\n (path, query) => this._get(path, query),\n (path, body) => this._put(path, body),\n (path) => this._delete(path),\n );\n this.evidenceBundles = makeEvidenceBundleClient(\n (path, body) => this._post(path, body),\n (path, query) => this._get(path, query),\n (path) => this._getRaw(path),\n );\n this.auth = makeAuthClient(\n (path, body) => this._post(path, body),\n (path) => this._get(path),\n );\n this.sso = makeSsoClient(\n (path, query) => this._get(path, query),\n (path, body) => this._post(path, body),\n (path, body) => this._patch(path, body),\n (path) => this._delete(path),\n );\n this.accessGovernanceLog = makeAccessGovernanceLogClient(\n (path, query) => this._get(path, query),\n );\n // Wire trust-root manager. Prefer custom options over the global manager\n // so clients with custom trustRootUrl or trustSnapshotRefreshMs get their\n // own manager; otherwise share the process-global singleton.\n if (options.trustRootUrl !== undefined || options.trustSnapshotRefreshMs !== undefined) {\n const globalSnap = getGlobalTrustRootManager({ disableRefresh: true }).getSnapshot();\n this.trustRoot = new TrustRootManager(globalSnap, {\n ...(options.trustRootUrl !== undefined && { refreshBaseUrl: options.trustRootUrl }),\n ...(options.trustSnapshotRefreshMs !== undefined && { refreshIntervalMs: options.trustSnapshotRefreshMs }),\n });\n } else {\n this.trustRoot = getGlobalTrustRootManager();\n }\n // Emit expiry warning once at construction time.\n this.trustRoot.checkExpiry();\n }\n\n /** Return the current trust-root snapshot (pinned or last successful refresh). */\n getTrustSnapshot(): TrustRootSnapshot {\n return this.trustRoot.getSnapshot();\n }\n\n /**\n * Ask the policy engine whether an agent action is permitted.\n *\n * Accepts either the current v2.0 shape (`action_type` / `actor_id`)\n * or the legacy v1.x shape (`action` / `agent`). Legacy callers\n * receive a deprecation warning via `console.warn`; the shim is\n * handled by {@link normalizeEvaluateRequest} and will be removed\n * in v3.0.0.\n *\n * A \"deny\" is **not** thrown — it is returned in\n * `response.decision`. Network errors, invalid API key, rate\n * limits, timeouts, and malformed responses throw\n * {@link AtlaSentError}.\n */\n async evaluate(\n input: EvaluateRequest | LegacyEvaluateRequest,\n ): Promise<EvaluateResponse> {\n _warnOversizeContext(input.context);\n\n // Run the dual-shape bridge: legacy {action, agent} → {action_type, actor_id}.\n // For callers already on the current EvaluateRequest shape the bridge is a\n // transparent pass-through (no warn, no allocation).\n const normalized = normalizeEvaluateRequest(\n input as LegacyEvaluateRequest | V2EvaluateRequest,\n );\n\n const body: Record<string, unknown> = {\n action_type: normalized.action_type,\n actor_id: normalized.actor_id,\n context: normalized.context ?? {},\n };\n if (normalized.explain !== undefined) body.explain = normalized.explain;\n if (normalized.environment !== undefined) body.environment = normalized.environment;\n if (normalized.resource !== undefined) body.resource = normalized.resource;\n if (normalized.current_state !== undefined) body.current_state = normalized.current_state;\n if (normalized.proposed_state !== undefined) body.proposed_state = normalized.proposed_state;\n if (normalized.execution_binding !== undefined) body.execution_binding = normalized.execution_binding;\n const { body: wire, rateLimit } = await this.post<EvaluateWire>(\n \"/v1-evaluate\",\n body,\n );\n\n // Normalise decision to lowercase canonical form. API responses may\n // arrive as uppercase (legacy deployments) or lowercase (canonical);\n // we always emit lowercase so callers can rely on a stable vocabulary.\n let decision = (\n typeof wire.decision === \"string\"\n ? wire.decision.toLowerCase()\n : wire.decision\n ) as EvaluateWire[\"decision\"] | undefined;\n\n // Tolerate both canonical {decision, permit_token} and legacy\n // {permitted, decision_id} server responses.\n if (decision === undefined && typeof wire.permitted === \"boolean\") {\n decision = wire.permitted ? \"allow\" : \"deny\";\n }\n const permitToken = wire.permit_token ?? wire.decision_id;\n\n if (\n decision !== \"allow\" &&\n decision !== \"deny\" &&\n decision !== \"hold\" &&\n decision !== \"escalate\"\n ) {\n throw new AtlaSentError(\n \"Malformed response from /v1-evaluate: missing `decision` (or legacy `permitted`)\",\n { code: \"bad_response\" },\n );\n }\n if (\n decision === \"allow\" &&\n (typeof permitToken !== \"string\" || permitToken.length === 0)\n ) {\n throw new AtlaSentError(\n \"Malformed response from /v1-evaluate: decision='allow' but no `permit_token` (or legacy `decision_id`)\",\n { code: \"bad_response\" },\n );\n }\n\n const reason = wire.denial?.reason ?? wire.reason ?? \"\";\n const permitId = permitToken ?? \"\";\n return {\n decision,\n decision_canonical: decision,\n evaluationId: permitId,\n permitId,\n // /v1-evaluate does not return a control-plane-shaped Permit body;\n // callers needing the full record fetch GET /v1/permits/:id.\n permit: null,\n permitToken: decision === \"allow\" ? (permitToken ?? null) : null,\n reasons: reason ? [reason] : [],\n reason,\n auditHash: wire.audit_hash ?? \"\",\n timestamp: wire.timestamp ?? \"\",\n rateLimit,\n ...(wire.risk_envelope && {\n riskEnvelope: {\n weightedScore: wire.risk_envelope.weighted_score,\n engineDecision: wire.risk_envelope.engine_decision as Decision,\n envelopeDecision: wire.risk_envelope.envelope_decision as Decision,\n promoted: wire.risk_envelope.promoted,\n hardBlocks: wire.risk_envelope.hard_blocks ?? [],\n ...(wire.risk_envelope.factors && { factors: wire.risk_envelope.factors }),\n },\n }),\n ...(wire.risk_class !== undefined && { riskClass: wire.risk_class }),\n ...(wire.authority_basis && {\n authorityBasis: {\n kind: wire.authority_basis.kind as NonNullable<EvaluateResponse[\"authorityBasis\"]>[\"kind\"],\n ...(wire.authority_basis.reference !== undefined && { reference: wire.authority_basis.reference }),\n ...(wire.authority_basis.granted_by !== undefined && { grantedBy: wire.authority_basis.granted_by }),\n ...(wire.authority_basis.rationale !== undefined && { rationale: wire.authority_basis.rationale }),\n ...(wire.authority_basis.expires_at !== undefined && { expiresAt: wire.authority_basis.expires_at }),\n },\n }),\n ...(wire.escalation_id !== undefined && { escalationId: wire.escalation_id }),\n };\n }\n\n /**\n * Batch evaluate — send up to 100 decisions in a single round-trip.\n *\n * Wraps `POST /v1/evaluate/batch` (with fallback to\n * `POST /v1-evaluate-batch` on older runtimes). The server evaluates each item\n * against the active policy bundle and returns results in the same\n * order as the input. One rate-limit token is consumed for the\n * whole batch, and one audit-chain entry lists every included\n * decision id.\n *\n * A per-item policy `deny` is **not** thrown — it appears as\n * `item.decision === \"deny\"` in the returned items. A whole-batch\n * network error, 4xx, or 5xx throws {@link AtlaSentError}.\n *\n * Requires the `v2_batch` tenant feature flag to be enabled on the\n * org (returns 404 when off). Requires scope `evaluate:write`.\n *\n * @param requests - 1–100 evaluate items.\n * @param batchId - Optional caller-supplied UUID for idempotency.\n * A retried call with the same `batchId` and identical items\n * returns the cached response within 24 h (`replayed: true`).\n */\n async evaluateBatch(\n requests: BatchEvalItem[],\n batchId?: string,\n ): Promise<BatchEvalResponse> {\n if (!Array.isArray(requests) || requests.length === 0) {\n throw new AtlaSentError(\n \"evaluateBatch: requests must be a non-empty array\",\n { code: \"bad_request\" },\n );\n }\n if (requests.length > 100) {\n throw new AtlaSentError(\n `evaluateBatch: requests.length ${requests.length} exceeds the 100-item cap`,\n { code: \"bad_request\" },\n );\n }\n\n const wireItems = requests.map((r) => ({\n action_type: r.action,\n actor_id: r.agent,\n context: r.context ?? {},\n }));\n\n const wireBody: Record<string, unknown> = { items: wireItems };\n if (batchId) wireBody.batch_id = batchId;\n\n const { body: wire, rateLimit } = await this.postWithPathFallback<EvaluateBatchWire>(\n V1_EVALUATE_BATCH_PATH,\n V1_EVALUATE_BATCH_LEGACY_PATH,\n wireBody,\n );\n\n const items: EvaluateBatchResultItem[] = (wire.items ?? []).map(\n (item: EvaluateBatchWireItem) => {\n const rawDecision = typeof item.decision === \"string\"\n ? item.decision.toLowerCase()\n : undefined;\n const decision = (\n rawDecision === \"allow\" ||\n rawDecision === \"deny\" ||\n rawDecision === \"hold\" ||\n rawDecision === \"escalate\"\n ? rawDecision\n : undefined\n ) as DecisionCanonical | undefined;\n\n return {\n index: item.index,\n ...(decision !== undefined ? { decision } : {}),\n ...(item.decision_id ? { decisionId: item.decision_id } : {}),\n ...(item.permit_token != null ? { permitToken: item.permit_token } : {}),\n ...(item.reason != null ? { reason: item.reason } : {}),\n ...(item.audit_entry_hash ? { auditHash: item.audit_entry_hash } : {}),\n ...(item.timestamp ? { timestamp: item.timestamp } : {}),\n ...(item.error ? { error: item.error } : {}),\n ...(item.message ? { message: item.message } : {}),\n } satisfies EvaluateBatchResultItem;\n },\n );\n\n return {\n batchId: wire.batch_id,\n items,\n partial: wire.partial ?? false,\n ...(wire.replayed ? { replayed: wire.replayed } : {}),\n rateLimit,\n };\n }\n\n /**\n * Subscribe to a live stream of decisions for this org.\n *\n * Wraps `GET /v1-decisions-stream`. The server emits one SSE frame\n * per audit event and sends a heartbeat every 15 s. The session\n * auto-closes after `maxSeconds` (default 30 min); reconnect with\n * the last received `event.id` to resume without replaying history.\n *\n * ```ts\n * const controller = new AbortController();\n * for await (const event of client.subscribeDecisions({ signal: controller.signal })) {\n * if (event.type === \"heartbeat\") continue;\n * console.log(event.type, event.decision, event.actorId);\n * if (event.type === \"session_end\") break; // reconnect\n * }\n * ```\n *\n * Requires scope `audit:read`. Requires the `v2_decisions_stream`\n * tenant feature flag (returns 404 when off).\n */\n async *subscribeDecisions(\n opts: SubscribeDecisionsOptions = {},\n ): AsyncGenerator<DecisionStreamEvent> {\n const url = new URL(`${this.baseUrl}/v1-decisions-stream`);\n if (opts.types?.length) url.searchParams.set(\"types\", opts.types.join(\",\"));\n if (opts.actorId) url.searchParams.set(\"actor_id\", opts.actorId);\n if (opts.maxSeconds !== undefined) url.searchParams.set(\"max_seconds\", String(opts.maxSeconds));\n\n const headers: Record<string, string> = {\n Accept: \"text/event-stream\",\n Authorization: `Bearer ${this.apiKey}`,\n \"User-Agent\": this.userAgent,\n // ADR-025: declare the wire-protocol version we were built\n // against. Runtime serves this version's response shape; older\n // versions outside the compatibility window get 426.\n \"X-AtlaSent-Protocol-Version\": \"1\",\n };\n if (opts.lastEventId) headers[\"Last-Event-ID\"] = opts.lastEventId;\n\n let response: Response;\n try {\n response = await this.fetchImpl(url.toString(), {\n method: \"GET\",\n headers,\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") return;\n throw new AtlaSentError(\n `Failed to connect to decisions stream: ${err instanceof Error ? err.message : String(err)}`,\n { code: \"network\" },\n );\n }\n\n if (!response.ok) {\n const code = response.status === 401 ? \"invalid_api_key\" : \"server_error\";\n throw new AtlaSentError(\n `Decisions stream returned ${response.status}`,\n { code, status: response.status },\n );\n }\n\n if (!response.body) {\n throw new AtlaSentError(\"Decisions stream response has no body\", { code: \"bad_response\" });\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder(\"utf-8\");\n let buf = \"\";\n\n try {\n while (true) {\n let chunk: Awaited<ReturnType<typeof reader.read>>;\n try {\n chunk = await reader.read();\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") return;\n throw new AtlaSentError(\n `Decisions stream read error: ${err instanceof Error ? err.message : String(err)}`,\n { code: \"network\" },\n );\n }\n if (chunk.done) break;\n\n buf += decoder.decode(chunk.value, { stream: true });\n const rawBlocks = buf.split(\"\\n\\n\");\n buf = rawBlocks.pop() ?? \"\";\n\n for (const block of rawBlocks) {\n if (!block.trim()) continue;\n\n // SSE comment / heartbeat line (\": …\")\n if (block.trimStart().startsWith(\":\")) {\n yield { type: \"heartbeat\" };\n continue;\n }\n\n let id: string | undefined;\n let eventType = \"audit_event\";\n let dataLine = \"\";\n\n for (const line of block.split(\"\\n\")) {\n if (line.startsWith(\"id:\")) id = line.slice(3).trim();\n else if (line.startsWith(\"event:\")) eventType = line.slice(6).trim();\n else if (line.startsWith(\"data:\")) dataLine = line.slice(5).trim();\n }\n\n if (!dataLine) continue;\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(dataLine) as Record<string, unknown>;\n } catch {\n continue;\n }\n\n if (eventType === \"session_end\") {\n yield { ...(id !== undefined ? { id } : {}), type: \"session_end\", payload: parsed };\n return;\n }\n\n const decision = typeof parsed.decision === \"string\"\n ? parsed.decision.toLowerCase() as DecisionCanonical\n : undefined;\n\n yield {\n ...(id !== undefined ? { id } : {}),\n type: eventType,\n ...(decision ? { decision } : {}),\n ...(typeof parsed.actor_id === \"string\" ? { actorId: parsed.actor_id } : {}),\n ...(typeof parsed.resource_type === \"string\" ? { resourceType: parsed.resource_type } : {}),\n ...(typeof parsed.resource_id === \"string\" ? { resourceId: parsed.resource_id } : {}),\n ...(parsed.payload && typeof parsed.payload === \"object\" ? { payload: parsed.payload as Record<string, unknown> } : {}),\n ...(typeof parsed.hash === \"string\" ? { hash: parsed.hash } : {}),\n ...(typeof parsed.previous_hash === \"string\" ? { previousHash: parsed.previous_hash } : {}),\n ...(typeof parsed.occurred_at === \"string\" ? { occurredAt: parsed.occurred_at } : {}),\n } satisfies DecisionStreamEvent;\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Pre-flight evaluation that always returns the constraint trace.\n *\n * Wraps `POST /v1-evaluate?include=constraint_trace`. Use this from\n * a workflow's submission step to surface trivial defects (missing\n * fields, wrong roles, mis-set context) BEFORE pushing the request\n * onto an approval queue — only requests that would actually pass\n * make it through to a human reviewer.\n *\n * Returns an {@link EvaluatePreflightResponse} carrying the regular\n * {@link EvaluateResponse} plus the {@link ConstraintTrace}. Unlike\n * {@link evaluate}, this method does NOT mark a non-allow as a\n * thrown condition — the whole point is to inspect both the outcome\n * AND the per-policy trace, so the caller branches on\n * `result.evaluation.decision` and reads `result.constraintTrace`\n * to render the failing stages.\n *\n * The constraint-trace shape mirrors `ConstraintTraceResponse` in\n * atlasent-api (`packages/types/src/index.ts`). On older\n * atlasent-api deployments that omit the trace, `constraintTrace`\n * is `null` rather than throwing — forward-compatible degradation.\n *\n * Performance: one extra round-trip on submission. Latency is\n * comparable to {@link evaluate}; the response body is fuller\n * (includes the per-stage trace) so the wire payload is larger.\n * If the caller does not need the trace, prefer {@link evaluate}.\n */\n async evaluatePreflight(\n input: EvaluateRequest,\n ): Promise<EvaluatePreflightResponse> {\n _warnOversizeContext(input.context);\n const body = {\n action_type: input.action,\n actor_id: input.agent,\n context: input.context ?? {},\n };\n const query = new URLSearchParams({ include: \"constraint_trace\" });\n const { body: wire, rateLimit } = await this.post<EvaluateWire>(\n \"/v1-evaluate\",\n body,\n query,\n );\n\n // Normalise decision to lowercase canonical form.\n let decision = (\n typeof wire.decision === \"string\"\n ? wire.decision.toLowerCase()\n : wire.decision\n ) as EvaluateWire[\"decision\"] | undefined;\n\n if (decision === undefined && typeof wire.permitted === \"boolean\") {\n decision = wire.permitted ? \"allow\" : \"deny\";\n }\n if (\n decision !== \"allow\" &&\n decision !== \"deny\" &&\n decision !== \"hold\" &&\n decision !== \"escalate\"\n ) {\n throw new AtlaSentError(\n \"Malformed response from /v1-evaluate: missing `decision` (or legacy `permitted`)\",\n { code: \"bad_response\" },\n );\n }\n const permitToken = wire.permit_token ?? wire.decision_id;\n\n const reason = wire.denial?.reason ?? wire.reason ?? \"\";\n const permitId = permitToken ?? \"\";\n const evaluation: EvaluateResponse = {\n decision,\n decision_canonical: decision,\n evaluationId: permitId,\n permitId,\n // /v1-evaluate does not return a control-plane-shaped Permit body;\n // callers needing the full record fetch GET /v1/permits/:id.\n permit: null,\n permitToken: decision === \"allow\" ? (permitToken ?? null) : null,\n reasons: reason ? [reason] : [],\n reason,\n auditHash: wire.audit_hash ?? \"\",\n timestamp: wire.timestamp ?? \"\",\n rateLimit,\n ...(wire.risk_envelope && {\n riskEnvelope: {\n weightedScore: wire.risk_envelope.weighted_score,\n engineDecision: wire.risk_envelope.engine_decision as Decision,\n envelopeDecision: wire.risk_envelope.envelope_decision as Decision,\n promoted: wire.risk_envelope.promoted,\n hardBlocks: wire.risk_envelope.hard_blocks ?? [],\n ...(wire.risk_envelope.factors && { factors: wire.risk_envelope.factors }),\n },\n }),\n };\n\n // Forward-compat: if the server omits `constraint_trace` (older\n // atlasent-api version), surface trace=null rather than throwing.\n // Unknown engine-side keys inside the trace are tolerated by the\n // ConstraintTrace interface's index signature.\n let constraintTrace: ConstraintTrace | null = null;\n if (\n wire.constraint_trace !== undefined &&\n wire.constraint_trace !== null &&\n typeof wire.constraint_trace === \"object\"\n ) {\n constraintTrace = wire.constraint_trace as ConstraintTrace;\n }\n\n return { evaluation, constraintTrace };\n }\n\n /**\n * Verify that a previously issued permit is still valid.\n *\n * @deprecated Use {@link verifyPermitById} — the canonical REST\n * surface (`POST /v1/permits/{id}/verify`) returns the unified\n * verification envelope plus the full {@link PermitRecord}, instead\n * of the legacy `{verified, outcome, permitHash}` shape this method\n * emits. Will be removed in `@atlasent/sdk@3`.\n *\n * A `verified: false` response is **not** thrown — inspect the\n * returned object. Only transport / server errors throw.\n */\n async verifyPermit(\n input: VerifyPermitRequest,\n ): Promise<VerifyPermitResponse> {\n _warnOversizeContext(input.context);\n // Canonical wire shape per handler.ts: only permit_token is required.\n // action_type / actor_id are optional cross-checks; context / api_key\n // are NOT consulted by the verify handler.\n const body: Record<string, unknown> = {\n permit_token: input.permitId,\n action_type: input.action ?? \"\",\n actor_id: input.agent ?? \"\",\n };\n if (input.environment !== undefined) {\n body.environment = input.environment;\n }\n if (input.execution_hash !== undefined) {\n body.execution_hash = input.execution_hash;\n }\n const { body: wire, rateLimit } = await this.post<VerifyPermitWire>(\n \"/v1-verify-permit\",\n body,\n );\n\n // Tolerate both canonical {valid, outcome} and legacy {verified} server\n // responses.\n const valid = typeof wire.valid === \"boolean\" ? wire.valid : wire.verified;\n if (typeof valid !== \"boolean\") {\n throw new AtlaSentError(\n \"Malformed response from /v1-verify-permit: missing `valid` (or legacy `verified`)\",\n { code: \"bad_response\" },\n );\n }\n\n return {\n verified: valid,\n outcome: wire.outcome ?? \"\",\n permitHash: wire.permit_hash ?? \"\",\n timestamp: wire.timestamp ?? \"\",\n expiresAt: wire.expires_at ?? null,\n rateLimit,\n };\n }\n\n /**\n * Run the canonical Deploy Gate V1 flow:\n * evaluate `production.deploy`, verify the issued permit server-side,\n * and return allow/block plus audit/evidence metadata.\n *\n * This helper never treats a signed/offline permit artifact as sufficient\n * authorization. Execution is allowed only when `POST /v1-evaluate` returns\n * `decision: \"allow\"` with a permit AND `POST /v1-verify-permit` returns\n * `verified: true` / `valid: true`.\n */\n async deployGate(input: DeployGateRequest = {}): Promise<DeployGateResponse> {\n const agent = input.agent ?? \"ci-deploy-bot\";\n const action = input.action ?? PRODUCTION_DEPLOY_ACTION;\n const context = input.context ?? {};\n const environment =\n typeof (context as Record<string, unknown>).environment === \"string\"\n ? ((context as Record<string, unknown>).environment as string)\n : typeof (context as Record<string, unknown>).environment_name === \"string\"\n ? ((context as Record<string, unknown>).environment_name as string)\n : undefined;\n\n const evaluation = await this.evaluate({ agent, action, context });\n if (evaluation.decision !== \"allow\") {\n return {\n allowed: false,\n evaluation,\n reason:\n evaluation.reason ||\n `Deploy Gate blocked by decision=${evaluation.decision}`,\n evidence: deployGateEvidence({\n permitId: evaluation.permitId,\n auditHash: evaluation.auditHash,\n }),\n };\n }\n\n const verification = await this.verifyPermit({\n permitId: evaluation.permitId,\n agent,\n action,\n context,\n ...(environment !== undefined ? { environment } : {}),\n });\n\n if (!verification.verified) {\n return {\n allowed: false,\n evaluation,\n verification,\n reason: verification.outcome\n ? `Deploy Gate blocked by permit verification outcome=${verification.outcome}`\n : \"Deploy Gate blocked because permit verification failed\",\n evidence: deployGateEvidence({\n permitId: evaluation.permitId,\n permitHash: verification.permitHash,\n auditHash: evaluation.auditHash,\n verifiedAt: verification.timestamp,\n }),\n };\n }\n\n return {\n allowed: true,\n evaluation,\n verification,\n reason: evaluation.reason || \"Deploy Gate permit verified\",\n evidence: deployGateEvidence({\n permitId: evaluation.permitId,\n permitHash: verification.permitHash,\n auditHash: evaluation.auditHash,\n verifiedAt: verification.timestamp,\n }),\n };\n }\n\n /**\n * Revoke a previously-issued permit so it can no longer pass\n * {@link verifyPermit}.\n *\n * @deprecated Use {@link revokePermitById} — the canonical REST\n * surface (`POST /v1/permits/{id}/revoke`) returns the full updated\n * {@link PermitRecord} with `revoked_at`/`revoked_by`/`revoke_reason`\n * populated, instead of the legacy `{revoked, permitId}` envelope\n * this method emits. Will be removed in `@atlasent/sdk@3`.\n *\n * Use this when an agent's action is cancelled, superseded, or\n * determined to be unauthorized after the fact. The revocation is\n * recorded in the audit log with the optional `reason`.\n *\n * Throws {@link AtlaSentError} on transport / auth failures.\n */\n async revokePermit(\n input: RevokePermitRequest,\n ): Promise<RevokePermitResponse> {\n const body = {\n decision_id: input.permitId,\n reason: input.reason ?? \"\",\n api_key: this.apiKey,\n };\n const { body: wire, rateLimit } = await this.post<{\n revoked: boolean;\n decision_id: string;\n revoked_at?: string;\n audit_hash?: string;\n }>(\"/v1-revoke-permit\", body);\n\n if (\n typeof wire.revoked !== \"boolean\" ||\n typeof wire.decision_id !== \"string\"\n ) {\n throw new AtlaSentError(\n \"Malformed response from /v1-revoke-permit: missing `revoked` or `decision_id`\",\n { code: \"bad_response\" },\n );\n }\n\n return {\n revoked: wire.revoked,\n permitId: wire.decision_id,\n revokedAt: wire.revoked_at,\n auditHash: wire.audit_hash,\n rateLimit,\n };\n }\n\n /**\n * Revoke a permit through the canonical REST surface\n * (`POST /v1/permits/{permitId}/revoke`).\n *\n * Returns the full updated {@link PermitRecord} with `status === 'revoked'`\n * and `revoked_at` / `revoked_by` / `revoke_reason` populated. After\n * revocation, subsequent verify calls return `410 PERMIT_REVOKED`.\n *\n * Idempotent on `409 permit_revoked` for already-revoked permits;\n * server returns the existing revoked row in that case.\n *\n * Throws {@link AtlaSentError} on `404` (permit not in calling org),\n * `409` (already in a terminal state), `410` (expired before revoke),\n * or `429` (rate limited).\n */\n async revokePermitById(\n permitId: string,\n input: RevokePermitByIdInput = {},\n ): Promise<RevokePermitByIdResponse> {\n if (!permitId) {\n throw new AtlaSentError(\"permitId is required\", { code: \"bad_request\" });\n }\n const body: { reason?: string } = {};\n if (input.reason !== undefined) body.reason = input.reason;\n const { body: wire, rateLimit } = await this.post<PermitRecord>(\n `/v1/permits/${encodeURIComponent(permitId)}/revoke`,\n body,\n );\n return { permit: wire, rateLimit };\n }\n\n /**\n * Verify a permit through the canonical REST surface\n * (`POST /v1/permits/{permitId}/verify`).\n *\n * Returns the unified verification envelope (`valid`,\n * `verification_type: 'permit'`, `reason`, `verified_at`, `evidence`)\n * plus the full {@link PermitRecord} fields preserved at the top\n * level. The `valid` field is the contract — pin to it.\n *\n * A `valid: false` is **not** thrown when the server returns 200 with\n * a denial reason (matches the verify-shape unification on the wire);\n * it is thrown on 4xx (`404` not found, `410` expired/consumed).\n */\n async verifyPermitById(permitId: string): Promise<VerifyPermitByIdResponse> {\n if (!permitId) {\n throw new AtlaSentError(\"permitId is required\", { code: \"bad_request\" });\n }\n const { body: wire, rateLimit } = await this.post<\n VerifyPermitByIdResponse & PermitRecord\n >(`/v1/permits/${encodeURIComponent(permitId)}/verify`, {});\n // Server returns the canonical envelope merged with the Permit row\n // (allOf in openapi). Pull out the legacy permit row into `permit`\n // for callers that want it as a sub-object too.\n const { valid, verification_type, reason, verified_at, evidence, ...row } =\n wire as VerifyPermitByIdResponse & PermitRecord;\n return {\n valid,\n verification_type,\n reason,\n verified_at,\n evidence,\n permit: row as PermitRecord,\n rateLimit,\n };\n }\n\n /**\n * Get a single permit's full lifecycle state.\n *\n * Calls `GET /v1/permits/{permitId}` (the canonical REST surface).\n * Returns `status`, all timestamps, `revoked_at` / `revoked_by` /\n * `revoke_reason` (when applicable), and the bound `payload_hash`\n * / `decision_id`.\n *\n * Operator-facing introspection — answers \"what state is this permit\n * in, and why?\" without reading audit logs.\n *\n * Throws {@link AtlaSentError} on `404` (permit not in calling org)\n * or `410` (expired before retrieval).\n */\n async getPermit(permitId: string): Promise<GetPermitResponse> {\n if (!permitId) {\n throw new AtlaSentError(\"permitId is required\", { code: \"bad_request\" });\n }\n const { body: wire, rateLimit } = await this.get<PermitRecord>(\n `/v1/permits/${encodeURIComponent(permitId)}`,\n );\n return { permit: wire, rateLimit };\n }\n\n /**\n * Poll whether a permit is currently valid.\n *\n * Calls `GET /v1/permits/{permitId}/valid` — a lightweight read\n * returning only the status snapshot optimised for guard heartbeat\n * polling. Guards with `permitRevalidationIntervalMs` set race this\n * against `tool.execute()` and throw {@link PermitRevoked} when\n * `status === \"revoked\"` arrives.\n *\n * Throws {@link AtlaSentError} on transport / auth failures.\n */\n async checkPermitValid(permitId: string): Promise<PermitValidResponse> {\n if (!permitId) {\n throw new AtlaSentError(\"permitId is required\", { code: \"bad_request\" });\n }\n const { body } = await this.get<PermitValidResponse>(\n `/v1/permits/${encodeURIComponent(permitId)}/valid`,\n );\n return body;\n }\n\n /**\n * List permits issued to the calling org, most-recently-issued first.\n *\n * Calls `GET /v1/permits` (the canonical REST surface). Cursor-paged.\n * Filters narrow on server side; pagination uses the `created_at`\n * timestamp opaquely (`nextCursor`).\n *\n * Designed for incident review, debugging, and compliance\n * reconstruction.\n */\n async listPermits(\n input: ListPermitsRequest = {},\n ): Promise<ListPermitsResponse> {\n const params = new URLSearchParams();\n if (input.status) params.set(\"status\", input.status);\n if (input.actorId) params.set(\"actor_id\", input.actorId);\n if (input.actionType) params.set(\"action_type\", input.actionType);\n if (input.from) params.set(\"from\", input.from);\n if (input.to) params.set(\"to\", input.to);\n if (input.limit !== undefined) params.set(\"limit\", String(input.limit));\n if (input.cursor) params.set(\"cursor\", input.cursor);\n\n const { body: wire, rateLimit } = await this.get<{\n permits?: PermitRecord[];\n total?: number;\n next_cursor?: string;\n }>(\"/v1/permits\", params);\n\n if (!Array.isArray(wire.permits)) {\n throw new AtlaSentError(\n \"Malformed response from /v1/permits: missing `permits` array\",\n { code: \"bad_response\" },\n );\n }\n const result: ListPermitsResponse = {\n permits: wire.permits,\n total: typeof wire.total === \"number\" ? wire.total : wire.permits.length,\n rateLimit,\n };\n if (wire.next_cursor !== undefined) result.nextCursor = wire.next_cursor;\n return result;\n }\n\n /**\n * Self-introspection: ask the server to describe the API key this\n * client was constructed with. Returns the key's ID, organization,\n * environment, scopes, IP allowlist, per-minute rate limit, the\n * client IP the server observed, and the expiry (if any).\n *\n * Never includes the raw key or its hash. Safe to surface in operator\n * dashboards. Useful for `IP_NOT_ALLOWED` debugging (the server tells\n * you exactly which IP it saw) and for proactive expiry warnings.\n *\n * Throws {@link AtlaSentError} on transport / auth failures — same\n * taxonomy as {@link AtlaSentClient.evaluate}.\n */\n async keySelf(): Promise<ApiKeySelfResponse> {\n const { body: wire, rateLimit } =\n await this.get<ApiKeySelfWire>(\"/v1-api-key-self\");\n\n if (\n typeof wire.key_id !== \"string\" ||\n typeof wire.org_id !== \"string\"\n ) {\n throw new AtlaSentError(\n \"Malformed response from /v1-api-key-self: missing `key_id` or `org_id`\",\n { code: \"bad_response\" },\n );\n }\n\n return {\n keyId: wire.key_id,\n orgId: wire.org_id,\n environment: wire.environment,\n scopes: wire.scopes ?? [],\n allowedCidrs: wire.allowed_cidrs ?? null,\n rateLimitPerMinute: wire.rate_limit_per_minute,\n clientIp: wire.client_ip ?? null,\n expiresAt: wire.expires_at ?? null,\n rateLimit,\n };\n }\n\n /**\n * List persisted audit events for the authenticated organization\n * (`GET /v1-audit/events`). Returned rows are wire-identical with\n * the server: snake_case field names, including `previous_hash` and\n * the `hash` chain, so the response can be fed straight into the\n * offline verifier when paired with a signed export.\n *\n * `query.types` is a comma-joined list (e.g.\n * `\"evaluate.allow,policy.updated\"`). `cursor` is the opaque\n * `next_cursor` from the prior page. All fields are optional; the\n * server defaults `limit` to 50 (capped at 500).\n *\n * Throws {@link AtlaSentError} on transport / auth failures — same\n * taxonomy as {@link AtlaSentClient.evaluate}.\n */\n async listAuditEvents(\n query: AuditEventsQuery = {},\n ): Promise<AuditEventsResult> {\n const { body: wire, rateLimit } = await this.get<AuditEventsPage>(\n \"/v1-audit/events\",\n buildAuditEventsQuery(query),\n );\n\n if (!Array.isArray(wire.events) || typeof wire.total !== \"number\") {\n throw new AtlaSentError(\n \"Malformed response from /v1-audit/events: missing `events` or `total`\",\n { code: \"bad_response\" },\n );\n }\n\n return { ...wire, rateLimit };\n }\n\n /**\n * Request a signed audit export bundle\n * (`POST /v1-audit/exports`). The returned object is wire-identical\n * with the server — `signature`, `chain_head_hash`, `events`, and\n * friends survive untouched so the bundle can be persisted to disk\n * and handed to the offline verifier (`verifyBundle` /\n * `verifyAuditBundle`) without any reshaping.\n *\n * Pass `filter.types`, `filter.from`, `filter.to`, or `filter.actor_id`\n * to narrow the export; omit for a full-org bundle. `rateLimit` is\n * attached alongside the wire fields for observability.\n *\n * Throws {@link AtlaSentError} on transport / auth failures — same\n * taxonomy as {@link AtlaSentClient.evaluate}.\n */\n async createAuditExport(\n filter: AuditExportRequest = {},\n ): Promise<AuditExportResult> {\n const { body: wire, rateLimit } = await this.post<AuditExport>(\n \"/v1-audit/exports\",\n filter,\n );\n\n if (\n typeof wire.export_id !== \"string\" ||\n typeof wire.chain_head_hash !== \"string\" ||\n !Array.isArray(wire.events)\n ) {\n throw new AtlaSentError(\n \"Malformed response from /v1-audit/exports: missing `export_id`, `chain_head_hash`, or `events`\",\n { code: \"bad_response\" },\n );\n }\n\n return { ...wire, rateLimit };\n }\n\n /**\n * Re-evaluate a recorded decision against its originally-pinned policy\n * bundle and engine version, and report whether the result agrees with\n * what was recorded.\n *\n * Wraps `POST /v1-decisions-replay/:id/replay`. **Side-effect-free** — no\n * audit chain row is written and no permit is issued (per ADR-016).\n * Useful for compliance review, regression testing of bundle changes,\n * and post-incident investigation.\n *\n * Outcomes encoded in the response:\n * - `variance: \"NONE\"` — replay agrees with the original decision.\n * - `variance: \"DECISION_CHANGED\"` — same envelope, same bundle, different\n * decision. Almost always indicates non-determinism in a rule\n * (e.g. wall-clock comparison) and warrants investigation.\n * - `variance: \"ENVELOPE_DRIFT\"` — the recorded request envelope no longer\n * hashes to the recorded value. The replay short-circuits without\n * running the engine; `replay_decision` is absent. Treat as evidence\n * of substrate tamper or a recorder bug.\n *\n * Server-side 409 responses (replay refused because the engine version\n * does not accept replay, or because no bundle was pinned) surface as\n * `AtlaSentError` with `code: \"replay_not_eligible\"` — callers should\n * treat them as expected for old / un-pinned decisions, not as bugs.\n *\n * Requires the `evaluate:write` API key scope.\n *\n * @param decisionId The UUID of the recorded decision to replay.\n * Matches `execution_evaluations.request_id`.\n *\n * @example\n * ```ts\n * const result = await client.replayDecision(\"dec_abc123\");\n * if (result.variance === \"DECISION_CHANGED\") {\n * console.warn(\n * `Decision ${result.decision_id} changed on replay: ` +\n * `${result.original_decision} → ${result.replay_decision}`,\n * );\n * }\n * ```\n */\n async replayDecision(\n decisionId: string,\n ): Promise<ReplayDecisionResponse & { rateLimit: RateLimitState | null }> {\n if (typeof decisionId !== \"string\" || decisionId.length === 0) {\n throw new AtlaSentError(\"decisionId is required\", {\n code: \"bad_request\",\n });\n }\n\n const path = `/v1-decisions-replay/${encodeURIComponent(decisionId)}/replay`;\n const { body: wire, rateLimit } = await this.post<ReplayDecisionResponse>(\n path,\n {},\n );\n\n // Defensive validation. The replay endpoint is alpha (see\n // STABLE_V2_PROMOTION.md) — wire shapes can shift without a\n // deprecation cycle, so guard the contract fields callers will\n // branch on rather than trusting the cast.\n if (\n typeof wire.decision_id !== \"string\" ||\n typeof wire.original_decision !== \"string\" ||\n typeof wire.engine_version_kind !== \"string\" ||\n typeof wire.accepts_replay !== \"boolean\" ||\n typeof wire.variance !== \"string\" ||\n typeof wire.envelope_verification !== \"string\" ||\n typeof wire.replayed_at !== \"string\"\n ) {\n throw new AtlaSentError(\n \"Malformed response from /v1-decisions-replay/:id/replay: missing required fields\",\n { code: \"bad_response\" },\n );\n }\n\n return { ...wire, rateLimit };\n }\n\n /**\n * ADR-015 Phase C — SDK-canonical replay runtime.\n *\n * Re-evaluates a recorded decision against its originally-pinned policy\n * bundle and engine version via `POST /v1/decisions/:id/replay`.\n * Side-effect-free server-side: no audit chain row is written and no\n * permit is issued (ADR-016 `mode: \"replay\"` sentinel).\n *\n * Differences from {@link replayDecision} (the 2.7.0 raw-wire surface):\n *\n * | | `replayDecision()` | `replay()` |\n * | --- | --- | --- |\n * | Path | `/v1-decisions-replay/:id/replay` | `/v1/decisions/:id/replay` |\n * | Variance | raw wire (`DECISION_CHANGED`) | SDK-canonical (`POLICY_DRIFT`) |\n * | 409 handling | throws `AtlaSentError` | returns `ENGINE_DRIFT` / `BUNDLE_MISSING` |\n * | Input shape | `decisionId: string` | `{ evaluationId }` |\n *\n * **Never throws on `409 replay_not_eligible`** — instead returns a\n * `ReplayResponse` with `varianceKind: \"ENGINE_DRIFT\"` (engine retired\n * beyond archival window) or `\"BUNDLE_MISSING\"` (no bundle pinned on\n * the original evaluation). Callers can always `switch` on\n * `result.varianceKind` without a try/catch.\n *\n * Fix-forward note: this method was originally landed in PR #275 but\n * dropped from the squash merge. The TS types (`ReplayResponse`,\n * `ReplayRequest`) and CHANGELOG made it through; the method itself\n * did not. Restored here to match the Python {@link\n * AtlaSentClient}.replay() that landed in atlasent-sdk@2.6.0 (Python).\n */\n async replay(input: ReplayRequest): Promise<ReplayResponse> {\n if (!input || typeof input.evaluationId !== \"string\" || input.evaluationId.length === 0) {\n throw new AtlaSentError(\"evaluationId is required\", {\n code: \"bad_request\",\n });\n }\n\n const path = `/v1/decisions/${encodeURIComponent(input.evaluationId)}/replay`;\n let wire: Record<string, unknown>;\n let rateLimit: RateLimitState | null;\n try {\n const result = await this.post<Record<string, unknown>>(path, {});\n wire = result.body;\n rateLimit = result.rateLimit;\n } catch (err) {\n if (err instanceof AtlaSentError && err.status === 409) {\n const msg = (err.message ?? \"\").toLowerCase();\n const varianceKind: ReplayVarianceKind = msg.includes(\"bundle\")\n ? \"BUNDLE_MISSING\"\n : \"ENGINE_DRIFT\";\n return {\n decisionId: input.evaluationId,\n varianceKind,\n originalDecision: \"deny\",\n acceptsReplay: false,\n replayedAt: new Date().toISOString(),\n rateLimit: null,\n };\n }\n throw err;\n }\n\n // Map raw wire variance → SDK-canonical. Unknown values default to\n // NONE per the additive-contract policy (the SDK never breaks on a\n // forward-introduced wire kind).\n const VARIANCE_MAP: Record<string, ReplayVarianceKind> = {\n NONE: \"NONE\",\n DECISION_CHANGED: \"POLICY_DRIFT\",\n ENVELOPE_DRIFT: \"ENVELOPE_DRIFT\",\n CHAIN_TAMPER: \"CHAIN_TAMPER\",\n BUNDLE_MISSING: \"BUNDLE_MISSING\",\n ENGINE_DRIFT: \"ENGINE_DRIFT\",\n };\n const rawVariance = typeof wire.variance === \"string\" ? wire.variance : \"\";\n const varianceKind: ReplayVarianceKind = VARIANCE_MAP[rawVariance] ?? \"NONE\";\n\n const replayDec = typeof wire.replay_decision === \"string\"\n ? (wire.replay_decision.toLowerCase() as DecisionCanonical)\n : undefined;\n const originalDec = (\n typeof wire.original_decision === \"string\"\n ? wire.original_decision.toLowerCase()\n : \"deny\"\n ) as DecisionCanonical;\n\n const response: ReplayResponse = {\n decisionId: typeof wire.decision_id === \"string\" ? wire.decision_id : input.evaluationId,\n varianceKind,\n originalDecision: originalDec,\n acceptsReplay: typeof wire.accepts_replay === \"boolean\" ? wire.accepts_replay : true,\n replayedAt: typeof wire.replayed_at === \"string\" ? wire.replayed_at : new Date().toISOString(),\n rateLimit,\n };\n if (typeof wire.original_deny_code === \"string\") response.originalDenyCode = wire.original_deny_code;\n if (replayDec !== undefined) response.replayedDecision = replayDec;\n if (typeof wire.replay_deny_code === \"string\") response.replayedDenyCode = wire.replay_deny_code;\n if (typeof wire.engine_version === \"string\") response.engineVersion = wire.engine_version;\n if (typeof wire.engine_version_kind === \"string\") response.engineVersionKind = wire.engine_version_kind;\n if (typeof wire.envelope_verification === \"string\") response.envelopeVerification = wire.envelope_verification;\n return response;\n }\n\n /**\n * Open a streaming evaluation session against `POST /v1/evaluate/stream`\n * (with fallback to `POST /v1-evaluate-stream` on older runtimes).\n *\n * Yields {@link StreamDecisionEvent} and {@link StreamProgressEvent} objects\n * as the server emits them. The iterator ends cleanly when the server sends\n * `event: done`; it throws {@link AtlaSentError} on transport errors or when\n * the server sends `event: error`.\n *\n * The final {@link StreamDecisionEvent} (isFinal: true) carries a `permitId`\n * suitable for passing to {@link verifyPermit} after the stream closes.\n *\n * Hardening:\n * - Throws {@link StreamTimeoutError} when no event arrives within\n * `opts.timeoutMs` (default 30 s). Pass `0` to disable.\n * - Retries up to `opts.maxRetries` times (default 3) with 1 s / 2 s / 4 s\n * delays on network drop (before a terminal event). Sends `Last-Event-ID`\n * on reconnect when the server has emitted event IDs.\n * - Throws {@link StreamParseError} on partial / malformed JSON rather than\n * crashing with a raw `SyntaxError`.\n * - Closes cleanly on `event: done` or a decision event with `done: true`.\n *\n * ```ts\n * for await (const event of client.protectStream({ agent, action })) {\n * if (event.type === \"decision\" && event.isFinal) {\n * await client.verifyPermit({ permitId: event.permitId });\n * }\n * }\n * ```\n */\n async *protectStream(\n input: EvaluateRequest,\n opts: StreamOptions = {},\n ): AsyncIterable<StreamEvent> {\n const streamTimeoutMs = opts.timeoutMs ?? 30_000;\n const maxRetries = opts.maxRetries ?? 3;\n\n const body = {\n action: input.action,\n agent: input.agent,\n context: input.context ?? {},\n api_key: this.apiKey,\n };\n\n const requestId = globalThis.crypto.randomUUID();\n let streamPath = V1_EVALUATE_STREAM_PATH;\n\n let lastEventId: string | undefined;\n let retryCount = 0;\n\n while (true) {\n const headers: Record<string, string> = {\n Accept: \"text/event-stream\",\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n \"User-Agent\": this.userAgent,\n // ADR-025: wire-protocol version declared on every request.\n \"X-AtlaSent-Protocol-Version\": \"1\",\n \"X-Request-ID\": requestId,\n };\n if (lastEventId !== undefined) {\n headers[\"Last-Event-ID\"] = lastEventId;\n }\n\n const connectionTimeoutSignal = AbortSignal.timeout(this.timeoutMs);\n const signal = opts.signal\n ? (\n AbortSignal as unknown as { any(s: AbortSignal[]): AbortSignal }\n ).any([connectionTimeoutSignal, opts.signal])\n : connectionTimeoutSignal;\n\n let response: Response;\n try {\n response = await this.fetchImpl(`${this.baseUrl}${streamPath}`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal,\n });\n } catch (err) {\n const mapped = mapFetchError(err, requestId);\n if (mapped.code === \"network\" && retryCount < maxRetries) {\n retryCount++;\n await sleep(1_000 * Math.pow(2, retryCount - 1)); // 1s, 2s, 4s\n continue;\n }\n throw mapped;\n }\n\n if (!response.ok) {\n if (\n streamPath === V1_EVALUATE_STREAM_PATH &&\n (response.status === 404 || response.status === 405)\n ) {\n streamPath = V1_EVALUATE_STREAM_LEGACY_PATH;\n continue;\n }\n throw await buildHttpError(response, requestId);\n }\n\n if (!response.body) {\n throw new AtlaSentError(\"Expected streaming body from AtlaSent API\", {\n code: \"bad_response\",\n status: response.status,\n requestId,\n });\n }\n\n let streamDone = false;\n let networkDrop = false;\n\n try {\n for await (const event of parseSseStream(\n response.body,\n requestId,\n streamTimeoutMs,\n (id) => {\n lastEventId = id;\n },\n )) {\n yield event;\n if (event.type === \"decision\" && event.isFinal) {\n streamDone = true;\n }\n }\n // parseSseStream returned normally (saw event: done or stream ended)\n streamDone = true;\n } catch (err) {\n if (err instanceof AtlaSentError && err.code === \"network\") {\n networkDrop = true;\n } else {\n throw err;\n }\n }\n\n if (streamDone) break;\n\n // Network drop before terminal event — attempt reconnect\n if (networkDrop && retryCount < maxRetries) {\n retryCount++;\n await sleep(1_000 * Math.pow(2, retryCount - 1)); // 1s, 2s, 4s\n continue;\n }\n if (networkDrop) {\n throw new AtlaSentError(\n `AtlaSent stream dropped after ${retryCount} reconnection attempts`,\n { code: \"network\", requestId },\n );\n }\n break;\n }\n }\n\n private async post<T>(\n path: string,\n body: unknown,\n query?: URLSearchParams,\n ): Promise<{ body: T; rateLimit: RateLimitState | null }> {\n return this.request<T>(path, \"POST\", body, query);\n }\n\n private async postWithPathFallback<T>(\n primaryPath: string,\n fallbackPath: string,\n body: unknown,\n query?: URLSearchParams,\n ): Promise<{ body: T; rateLimit: RateLimitState | null }> {\n try {\n return await this.post<T>(primaryPath, body, query);\n } catch (err) {\n if (\n err instanceof AtlaSentError &&\n (err.status === 404 || err.status === 405)\n ) {\n return this.post<T>(fallbackPath, body, query);\n }\n throw err;\n }\n }\n\n private async get<T>(\n path: string,\n query?: URLSearchParams,\n ): Promise<{ body: T; rateLimit: RateLimitState | null }> {\n return this.request<T>(path, \"GET\", undefined, query);\n }\n\n private async request<T>(\n path: string,\n method: \"GET\" | \"POST\",\n body: unknown,\n query: URLSearchParams | undefined,\n ): Promise<{ body: T; rateLimit: RateLimitState | null }> {\n const qs =\n query && Array.from(query).length > 0 ? `?${query.toString()}` : \"\";\n const url = `${this.baseUrl}${path}${qs}`;\n const requestId = globalThis.crypto.randomUUID();\n\n /**\n * Canonical auth header. The API also accepts X-AtlaSent-Key for legacy\n * compatibility but that path is deprecated and will be removed in a future\n * version. Always use Authorization: Bearer <api_key>.\n */\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n \"User-Agent\": this.userAgent,\n \"X-Request-ID\": requestId,\n // ADR-025: wire-protocol version declared on every request.\n \"X-AtlaSent-Protocol-Version\": \"1\",\n };\n if (method === \"POST\") headers[\"Content-Type\"] = \"application/json\";\n\n const bodyStr = method === \"POST\" ? JSON.stringify(body) : undefined;\n\n for (let attempt = 0; ; attempt++) {\n const init: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(this.timeoutMs),\n };\n if (bodyStr !== undefined) init.body = bodyStr;\n\n let response: Response;\n try {\n response = await this.fetchImpl(url, init);\n } catch (err) {\n const mapped = mapFetchError(err, requestId);\n if (isRetryable(mapped) && hasAttemptsLeft(attempt, this.retryPolicy)) {\n await sleep(computeBackoffMs(attempt, this.retryPolicy, mapped));\n continue;\n }\n throw mapped;\n }\n\n if (!response.ok) {\n const httpErr = await buildHttpError(response, requestId);\n if (\n isRetryable(httpErr) &&\n hasAttemptsLeft(attempt, this.retryPolicy)\n ) {\n await sleep(computeBackoffMs(attempt, this.retryPolicy, httpErr));\n continue;\n }\n throw httpErr;\n }\n\n let parsed: unknown;\n try {\n parsed = await response.json();\n } catch (err) {\n const jsonErr = new AtlaSentError(\n \"Invalid JSON response from AtlaSent API\",\n {\n code: \"bad_response\",\n status: response.status,\n requestId,\n cause: err,\n },\n );\n if (\n isRetryable(jsonErr) &&\n hasAttemptsLeft(attempt, this.retryPolicy)\n ) {\n await sleep(computeBackoffMs(attempt, this.retryPolicy, jsonErr));\n continue;\n }\n throw jsonErr;\n }\n\n if (parsed === null || typeof parsed !== \"object\") {\n const shapeErr = new AtlaSentError(\n \"Expected a JSON object from AtlaSent API\",\n {\n code: \"bad_response\",\n status: response.status,\n requestId,\n },\n );\n if (\n isRetryable(shapeErr) &&\n hasAttemptsLeft(attempt, this.retryPolicy)\n ) {\n await sleep(computeBackoffMs(attempt, this.retryPolicy, shapeErr));\n continue;\n }\n throw shapeErr;\n }\n\n return {\n body: parsed as T,\n rateLimit: parseRateLimitHeaders(response.headers),\n };\n }\n }\n\n /**\n * Open a new HITL escalation. Bridges a `hold` outcome from\n * `protect()` to the approval queue: an agent that receives a\n * `hold` decision calls this to enroll the proposed action for\n * human review. The returned escalation can then be polled with\n * `getHitlEscalation()` or driven to terminal by\n * `approveHitlEscalation()` / `rejectHitlEscalation()`.\n *\n * Quorum, pool size, fallback decision and routing inherit from\n * the server-side policy when omitted from `input`.\n *\n * Calls `POST /v1/hitl`.\n */\n async createHitlEscalation(\n input: HitlCreateRequest,\n ): Promise<{ escalation: HitlEscalation; rateLimit: RateLimitState | null }> {\n const { body, rateLimit } = await this.post<HitlEscalation>(\n \"/v1/hitl\",\n input,\n );\n return { escalation: body, rateLimit };\n }\n\n /**\n * List HITL escalations for the calling org. Defaults to\n * `status=pending`; pass `status` to query other queues\n * (`escalated`, `approved`, `rejected`, `auto_approved`,\n * `timed_out`).\n *\n * Calls `GET /v1/hitl`.\n */\n async listHitlEscalations(input: ListHitlEscalationsRequest = {}): Promise<{\n data: ListHitlEscalationsResponse;\n rateLimit: RateLimitState | null;\n }> {\n const params = new URLSearchParams();\n if (input.status) params.set(\"status\", input.status);\n if (input.agentId) params.set(\"agent_id\", input.agentId);\n if (input.assignedToUserId)\n params.set(\"assigned_to_user_id\", input.assignedToUserId);\n if (input.limit !== undefined) params.set(\"limit\", String(input.limit));\n if (input.cursor) params.set(\"cursor\", input.cursor);\n const { body, rateLimit } = await this.get<ListHitlEscalationsResponse>(\n \"/v1/hitl\",\n params,\n );\n return { data: body, rateLimit };\n }\n\n /**\n * Get a HITL escalation. The server payload includes a live\n * `quorum_progress` snapshot when the escalation is still open.\n *\n * Calls `GET /v1/hitl/:id`.\n */\n async getHitlEscalation(\n escalationId: string,\n ): Promise<{ escalation: HitlEscalation; rateLimit: RateLimitState | null }> {\n if (!escalationId) {\n throw new AtlaSentError(\"escalationId is required\", {\n code: \"bad_request\",\n });\n }\n const { body, rateLimit } = await this.get<HitlEscalation>(\n `/v1/hitl/${encodeURIComponent(escalationId)}`,\n );\n return { escalation: body, rateLimit };\n }\n\n /**\n * List per-approver vote rows for an escalation.\n * Calls `GET /v1/hitl/:id/approvals`.\n */\n async listHitlApprovals(escalationId: string): Promise<{\n approvals: HitlApprovalRecord[];\n rateLimit: RateLimitState | null;\n }> {\n const { body, rateLimit } = await this.get<{\n approvals: HitlApprovalRecord[];\n }>(`/v1/hitl/${encodeURIComponent(escalationId)}/approvals`);\n return { approvals: body.approvals ?? [], rateLimit };\n }\n\n /**\n * List the escalation chain hops for an escalation. Each `/escalate`\n * call appends one row.\n * Calls `GET /v1/hitl/:id/chain`.\n */\n async getHitlChain(\n escalationId: string,\n ): Promise<{ chain: HitlChainHop[]; rateLimit: RateLimitState | null }> {\n const { body, rateLimit } = await this.get<{ chain: HitlChainHop[] }>(\n `/v1/hitl/${encodeURIComponent(escalationId)}/chain`,\n );\n return { chain: body.chain ?? [], rateLimit };\n }\n\n /**\n * Record an approve vote. Resolves the escalation only once the\n * server-side quorum count is satisfied; before that the response\n * carries a refreshed escalation row with the latest\n * `quorum_progress`.\n *\n * Calls `POST /v1/hitl/:id/approve`. The server returns 409\n * `duplicate_vote` if the same principal has already voted, and\n * 409 `already_rejected` if a concurrent reject crossed the line.\n */\n async approveHitlEscalation(\n escalationId: string,\n input: HitlApproveRequest = {},\n ): Promise<{ escalation: HitlEscalation; rateLimit: RateLimitState | null }> {\n const { body, rateLimit } = await this.post<HitlEscalation>(\n `/v1/hitl/${encodeURIComponent(escalationId)}/approve`,\n input,\n );\n return { escalation: body, rateLimit };\n }\n\n /**\n * Record a reject vote. Reject is short-circuit terminal — a single\n * reject closes the escalation regardless of how many approves have\n * accumulated.\n *\n * Calls `POST /v1/hitl/:id/reject`.\n */\n async rejectHitlEscalation(\n escalationId: string,\n input: HitlRejectRequest = {},\n ): Promise<{ escalation: HitlEscalation; rateLimit: RateLimitState | null }> {\n const { body, rateLimit } = await this.post<HitlEscalation>(\n `/v1/hitl/${encodeURIComponent(escalationId)}/reject`,\n input,\n );\n return { escalation: body, rateLimit };\n }\n\n /**\n * Re-route an open escalation to a higher tier. Bounded by the\n * escalation's `max_escalation_depth` — the server returns 409\n * `chain_exhausted` and applies the configured fallback decision\n * once the ceiling is hit.\n *\n * Calls `POST /v1/hitl/:id/escalate`.\n */\n async escalateHitlEscalation(\n escalationId: string,\n input: HitlEscalateRequest,\n ): Promise<{ escalation: HitlEscalation; rateLimit: RateLimitState | null }> {\n const { body, rateLimit } = await this.post<HitlEscalation>(\n `/v1/hitl/${encodeURIComponent(escalationId)}/escalate`,\n input,\n );\n return { escalation: body, rateLimit };\n }\n\n /**\n * Manually apply the escalation's `fallback_decision`. Useful for\n * admin recovery of a hung escalation when the cron sweeper hasn't\n * run yet, or to short-circuit a stuck flow during incident\n * response.\n *\n * Calls `POST /v1/hitl/:id/timeout`.\n */\n async timeoutHitlEscalation(\n escalationId: string,\n ): Promise<{ escalation: HitlEscalation; rateLimit: RateLimitState | null }> {\n const { body, rateLimit } = await this.post<HitlEscalation>(\n `/v1/hitl/${encodeURIComponent(escalationId)}/timeout`,\n {},\n );\n return { escalation: body, rateLimit };\n }\n\n /**\n * Run a named governance graph traversal query.\n *\n * Dispatches to `GET /v1/governance/graph/query?type=<queryType>`.\n * Each query type returns a different row shape — the return type\n * narrows automatically based on the literal `queryType` argument.\n *\n * `\"user_approvals\"` requires `params.actor_id` — the server returns\n * a 400 if it is absent.\n */\n async queryGovernanceGraph<T extends GovernanceGraphQueryType>(\n queryType: T,\n params: GovernanceGraphQueryParams = {},\n ): Promise<GovernanceGraphQueryResponse<T>> {\n const qs = new URLSearchParams({ type: queryType });\n if (params.actor_id) qs.set(\"actor_id\", params.actor_id);\n const { body, rateLimit } = await this.get<{\n query_type: T;\n results: GovernanceGraphResultRow<T>[];\n org_id: string;\n }>(\"/v1/governance/graph/query\", qs);\n return { ...body, rateLimit };\n }\n\n /**\n * Reconstruct the multi-system execution timeline for a specific incident.\n *\n * Calls `GET /v1/governance/timeline/incident/{incidentId}`. Backed\n * server-side by `reconstruct_incident_chains_v2()`, which fixes the\n * `executor_id → actor_id` bug that silently produced empty timelines\n * in the original function.\n *\n * Returns full execution rows including the §13.1 columns\n * (`delegation_chain_id`, `replay_of_execution_id`, `incident_id`,\n * `policy_version_id`, `bundle_version_id`) alongside the actor\n * timeline and evidence rows.\n */\n async getIncidentTimeline(\n incidentId: string,\n ): Promise<IncidentTimelineResponse> {\n if (!incidentId) {\n throw new AtlaSentError(\"incidentId is required\", {\n code: \"bad_request\",\n });\n }\n const { body, rateLimit } = await this.get<\n Omit<IncidentTimelineResponse, \"rateLimit\">\n >(`/v1/governance/timeline/incident/${encodeURIComponent(incidentId)}`);\n return { ...body, rateLimit };\n }\n\n // ── Connector Management ─────────────────────────────────────────────────\n\n /**\n * List connectors registered for the calling org.\n * Calls `GET /v1/governance/connectors`.\n */\n async listConnectors(\n options: { cursor?: string; limit?: number } = {},\n ): Promise<ListConnectorsResponse> {\n const params = new URLSearchParams();\n if (options.cursor) params.set(\"cursor\", options.cursor);\n if (options.limit !== undefined) params.set(\"limit\", String(options.limit));\n const { body, rateLimit } = await this.get<{\n connectors: ListConnectorsResponse[\"connectors\"];\n total: number;\n next_cursor?: string;\n }>(\"/v1/governance/connectors\", params);\n const result: ListConnectorsResponse = {\n connectors: body.connectors ?? [],\n total: body.total,\n rateLimit,\n };\n if (body.next_cursor) result.nextCursor = body.next_cursor;\n return result;\n }\n\n /**\n * Register and install a new connector for the calling org.\n * Calls `POST /v1/governance/connectors`.\n */\n async installConnector(\n input: InstallConnectorInput,\n ): Promise<InstallConnectorResponse> {\n const { body, rateLimit } = await this.post<\n InstallConnectorResponse[\"connector\"]\n >(\"/v1/governance/connectors\", input);\n return { connector: body, rateLimit };\n }\n\n /**\n * Store encrypted credentials for a connector.\n * Calls `POST /v1/governance/connectors/{id}/authenticate`.\n */\n async authenticateConnector(\n connectorId: string,\n input: AuthenticateConnectorInput,\n ): Promise<AuthenticateConnectorResponse> {\n if (!connectorId) {\n throw new AtlaSentError(\"connectorId is required\", {\n code: \"bad_request\",\n });\n }\n const { body, rateLimit } = await this.post<{\n credential_id: string;\n version: number;\n }>(\n `/v1/governance/connectors/${encodeURIComponent(connectorId)}/authenticate`,\n input,\n );\n return {\n credential_id: body.credential_id,\n version: body.version,\n rateLimit,\n };\n }\n\n /**\n * Trigger an incremental sync for a connector.\n * Calls `POST /v1/governance/connectors/{id}/sync`.\n */\n async syncConnector(connectorId: string): Promise<SyncConnectorResponse> {\n if (!connectorId) {\n throw new AtlaSentError(\"connectorId is required\", {\n code: \"bad_request\",\n });\n }\n const { body, rateLimit } = await this.post<{\n connector_id: string;\n status: SyncConnectorResponse[\"status\"];\n sync_started_at: string;\n }>(`/v1/governance/connectors/${encodeURIComponent(connectorId)}/sync`, {});\n return { ...body, rateLimit };\n }\n\n /**\n * Revoke a connector and all its associated credentials.\n * Calls `POST /v1/governance/connectors/{id}/revoke`.\n */\n async revokeConnector(\n connectorId: string,\n reason?: string,\n ): Promise<RevokeConnectorResponse> {\n if (!connectorId) {\n throw new AtlaSentError(\"connectorId is required\", {\n code: \"bad_request\",\n });\n }\n const body: { reason?: string } = {};\n if (reason !== undefined) body.reason = reason;\n const { body: wire, rateLimit } = await this.post<{\n connector_id: string;\n revoked_at: string;\n }>(\n `/v1/governance/connectors/${encodeURIComponent(connectorId)}/revoke`,\n body,\n );\n return { ...wire, rateLimit };\n }\n\n /**\n * Rotate the credentials for a connector.\n * Calls `POST /v1/governance/connectors/{id}/rotate-credentials`.\n */\n async rotateConnectorCredentials(\n connectorId: string,\n ): Promise<RotateCredentialsResponse> {\n if (!connectorId) {\n throw new AtlaSentError(\"connectorId is required\", {\n code: \"bad_request\",\n });\n }\n const { body, rateLimit } = await this.post<{\n connector_id: string;\n new_version: number;\n rotated_at: string;\n }>(\n `/v1/governance/connectors/${encodeURIComponent(connectorId)}/rotate-credentials`,\n {},\n );\n return { ...body, rateLimit };\n }\n\n /**\n * List enforcement policies for the calling org, optionally filtered by connector type.\n * Calls `GET /v1/governance/enforcement-policies`.\n */\n async listEnforcementPolicies(\n connectorType?: ConnectorType,\n ): Promise<ListEnforcementPoliciesResponse> {\n const params = new URLSearchParams();\n if (connectorType) params.set(\"connector_type\", connectorType);\n const { body, rateLimit } = await this.get<{\n policies: ListEnforcementPoliciesResponse[\"policies\"];\n total: number;\n }>(\"/v1/governance/enforcement-policies\", params);\n return { policies: body.policies ?? [], total: body.total, rateLimit };\n }\n\n /**\n * Create or update a connector enforcement policy.\n * Calls `POST /v1/governance/enforcement-policies`.\n */\n async upsertEnforcementPolicy(\n input: UpsertEnforcementPolicyInput,\n ): Promise<UpsertEnforcementPolicyResponse> {\n const { body, rateLimit } = await this.post<\n UpsertEnforcementPolicyResponse[\"policy\"]\n >(\"/v1/governance/enforcement-policies\", input);\n return { policy: body, rateLimit };\n }\n\n // ── Organizational Risk Graph ─────────────────────────────────────────────\n\n /**\n * Trigger a fresh org-level risk score computation.\n * Calls `POST /v1/governance/risk/compute`.\n */\n async computeOrgRisk(\n options: ComputeOrgRiskOptions = {},\n ): Promise<ComputeOrgRiskResponse> {\n const { body, rateLimit } = await this.post<\n ComputeOrgRiskResponse[\"score\"]\n >(\"/v1/governance/risk/compute\", options);\n return { score: body, rateLimit };\n }\n\n /**\n * Retrieve the most recently computed risk score for the calling org.\n * Calls `GET /v1/governance/risk/latest`.\n */\n async getLatestOrgRisk(): Promise<GetLatestOrgRiskResponse> {\n const { body, rateLimit } = await this.get<{\n score: GetLatestOrgRiskResponse[\"score\"];\n }>(\"/v1/governance/risk/latest\");\n return { score: body.score ?? null, rateLimit };\n }\n\n /**\n * Page through historical org risk scores, most-recent first.\n * Calls `GET /v1/governance/risk/history`.\n */\n async listOrgRiskHistory(\n options: { cursor?: string; limit?: number } = {},\n ): Promise<ListOrgRiskHistoryResponse> {\n const params = new URLSearchParams();\n if (options.cursor) params.set(\"cursor\", options.cursor);\n if (options.limit !== undefined) params.set(\"limit\", String(options.limit));\n const { body, rateLimit } = await this.get<{\n scores: ListOrgRiskHistoryResponse[\"scores\"];\n total: number;\n next_cursor?: string;\n }>(\"/v1/governance/risk/history\", params);\n const result: ListOrgRiskHistoryResponse = {\n scores: body.scores ?? [],\n total: body.total,\n rateLimit,\n };\n if (body.next_cursor) result.nextCursor = body.next_cursor;\n return result;\n }\n // ── Cross-Org Permission Negotiation ──────────────────────────────────────\n\n async checkCrossOrgPermission(\n req: CrossOrgPermissionCheckRequest,\n ): Promise<CrossOrgPermissionCheckResult> {\n const { body } = await this.post<CrossOrgPermissionCheckResult>(\n \"/v1/cross-org/permissions/check\",\n req,\n );\n return body;\n }\n\n async listCrossOrgPermissionChecks(\n params?: CrossOrgPermissionCheckListParams,\n ): Promise<CrossOrgPermissionCheckResult[]> {\n const qs = new URLSearchParams();\n if (params?.source_org_id) qs.set(\"source_org_id\", params.source_org_id);\n if (params?.target_org_id) qs.set(\"target_org_id\", params.target_org_id);\n if (params?.allowed !== undefined)\n qs.set(\"allowed\", String(params.allowed));\n if (params?.limit !== undefined) qs.set(\"limit\", String(params.limit));\n const { body } = await this.get<{\n checks: CrossOrgPermissionCheckResult[];\n }>(\"/v1/cross-org/permissions/checks\", qs);\n return body.checks ?? [];\n }\n\n // ── Anomaly Response Automation ───────────────────────────────────────────\n\n async listAnomalyResponseRules(): Promise<AnomalyResponseRule[]> {\n const { body } = await this.get<{ rules: AnomalyResponseRule[] }>(\n \"/v1/anomaly-response/rules\",\n );\n return body.rules ?? [];\n }\n\n async createAnomalyResponseRule(\n req: CreateAnomalyResponseRuleRequest,\n ): Promise<AnomalyResponseRule> {\n const { body } = await this.post<AnomalyResponseRule>(\n \"/v1/anomaly-response/rules\",\n req,\n );\n return body;\n }\n\n async updateAnomalyResponseRule(\n id: string,\n updates: Partial<CreateAnomalyResponseRuleRequest>,\n ): Promise<AnomalyResponseRule> {\n const { body } = await this.post<AnomalyResponseRule>(\n `/v1/anomaly-response/rules/${encodeURIComponent(id)}/update`,\n updates,\n );\n return body;\n }\n\n async deleteAnomalyResponseRule(id: string): Promise<void> {\n await this.post<Record<string, unknown>>(\n `/v1/anomaly-response/rules/${encodeURIComponent(id)}/delete`,\n {},\n );\n }\n\n async triggerAnomalyResponse(\n req: TriggerAnomalyResponseRequest,\n ): Promise<AnomalyResponseEvent[]> {\n const { body } = await this.post<{ events: AnomalyResponseEvent[] }>(\n \"/v1/anomaly-response/trigger\",\n req,\n );\n return body.events ?? [];\n }\n\n async listAnomalyResponseEvents(params?: {\n limit?: number;\n execution_id?: string;\n }): Promise<AnomalyResponseEvent[]> {\n const qs = new URLSearchParams();\n if (params?.execution_id) qs.set(\"execution_id\", params.execution_id);\n if (params?.limit !== undefined) qs.set(\"limit\", String(params.limit));\n const { body } = await this.get<{ events: AnomalyResponseEvent[] }>(\n \"/v1/anomaly-response/events\",\n qs,\n );\n return body.events ?? [];\n }\n\n // ── Budget Exception Workflows ────────────────────────────────────────────\n\n async listBudgetExceptions(params?: {\n status?: BudgetExceptionStatus;\n budget_policy_id?: string;\n limit?: number;\n offset?: number;\n }): Promise<BudgetExceptionRequest[]> {\n const qs = new URLSearchParams();\n if (params?.status) qs.set(\"status\", params.status);\n if (params?.budget_policy_id)\n qs.set(\"budget_policy_id\", params.budget_policy_id);\n if (params?.limit !== undefined) qs.set(\"limit\", String(params.limit));\n if (params?.offset !== undefined) qs.set(\"offset\", String(params.offset));\n const { body } = await this.get<{ exceptions: BudgetExceptionRequest[] }>(\n \"/v1/budget-exceptions\",\n qs,\n );\n return body.exceptions ?? [];\n }\n\n async getBudgetException(id: string): Promise<BudgetExceptionRequest> {\n const { body } = await this.get<BudgetExceptionRequest>(\n `/v1/budget-exceptions/${encodeURIComponent(id)}`,\n );\n return body;\n }\n\n async createBudgetException(\n req: CreateBudgetExceptionRequest,\n ): Promise<BudgetExceptionRequest> {\n const { body } = await this.post<BudgetExceptionRequest>(\n \"/v1/budget-exceptions\",\n req,\n );\n return body;\n }\n\n async approveBudgetException(\n id: string,\n req: ApproveBudgetExceptionRequest,\n ): Promise<BudgetExceptionRequest> {\n const { body } = await this.post<BudgetExceptionRequest>(\n `/v1/budget-exceptions/${encodeURIComponent(id)}/approve`,\n req,\n );\n return body;\n }\n\n async rejectBudgetException(\n id: string,\n review_notes?: string,\n ): Promise<BudgetExceptionRequest> {\n const { body } = await this.post<BudgetExceptionRequest>(\n `/v1/budget-exceptions/${encodeURIComponent(id)}/reject`,\n { review_notes },\n );\n return body;\n }\n\n async cancelBudgetException(id: string): Promise<BudgetExceptionRequest> {\n const { body } = await this.post<BudgetExceptionRequest>(\n `/v1/budget-exceptions/${encodeURIComponent(id)}/cancel`,\n {},\n );\n return body;\n }\n\n // ── Regulatory Escalation Chain ───────────────────────────────────────────\n\n async listRegulatoryAuthorityLevels(): Promise<RegulatoryAuthorityLevel[]> {\n const { body } = await this.get<{ levels: RegulatoryAuthorityLevel[] }>(\n \"/v1/regulatory/authority-levels\",\n );\n return body.levels ?? [];\n }\n\n async createRegulatoryAuthorityLevel(\n req: Omit<RegulatoryAuthorityLevel, \"id\" | \"org_id\" | \"created_at\">,\n ): Promise<RegulatoryAuthorityLevel> {\n const { body } = await this.post<RegulatoryAuthorityLevel>(\n \"/v1/regulatory/authority-levels\",\n req,\n );\n return body;\n }\n\n async listRegulatoryEscalations(params?: {\n status?: RegulatoryEscalationStatus;\n subject_type?: string;\n subject_id?: string;\n }): Promise<RegulatoryEscalation[]> {\n const qs = new URLSearchParams();\n if (params?.status) qs.set(\"status\", params.status);\n if (params?.subject_type) qs.set(\"subject_type\", params.subject_type);\n if (params?.subject_id) qs.set(\"subject_id\", params.subject_id);\n const { body } = await this.get<{ escalations: RegulatoryEscalation[] }>(\n \"/v1/regulatory/escalations\",\n qs,\n );\n return body.escalations ?? [];\n }\n\n async createRegulatoryEscalation(\n req: CreateRegulatoryEscalationRequest,\n ): Promise<RegulatoryEscalation> {\n const { body } = await this.post<RegulatoryEscalation>(\n \"/v1/regulatory/escalations\",\n req,\n );\n return body;\n }\n\n async acknowledgeRegulatoryEscalation(\n id: string,\n ): Promise<RegulatoryEscalation> {\n const { body } = await this.post<RegulatoryEscalation>(\n `/v1/regulatory/escalations/${encodeURIComponent(id)}/acknowledge`,\n {},\n );\n return body;\n }\n\n async resolveRegulatoryEscalation(\n id: string,\n resolution: string,\n resolution_details?: Record<string, unknown>,\n ): Promise<RegulatoryEscalation> {\n const { body } = await this.post<RegulatoryEscalation>(\n `/v1/regulatory/escalations/${encodeURIComponent(id)}/resolve`,\n { resolution, resolution_details },\n );\n return body;\n }\n\n async overrideRegulatoryEscalation(\n id: string,\n reason: string,\n ): Promise<RegulatoryEscalation> {\n const { body } = await this.post<RegulatoryEscalation>(\n `/v1/regulatory/escalations/${encodeURIComponent(id)}/override`,\n { reason },\n );\n return body;\n }\n\n // ── Incentive Signal Feedback Loop ────────────────────────────────────────\n\n async listSignalActions(\n signal_id: string,\n ): Promise<GovernanceSignalAction[]> {\n const { body } = await this.get<{ actions: GovernanceSignalAction[] }>(\n `/v1/governance/signals/${encodeURIComponent(signal_id)}/actions`,\n );\n return body.actions ?? [];\n }\n\n async recordSignalAction(\n signal_id: string,\n req: RecordSignalActionRequest,\n ): Promise<GovernanceSignalAction> {\n const { body } = await this.post<GovernanceSignalAction>(\n `/v1/governance/signals/${encodeURIComponent(signal_id)}/actions`,\n req,\n );\n return body;\n }\n\n async recordSignalOutcome(\n signal_id: string,\n action_id: string,\n req: RecordSignalOutcomeRequest,\n ): Promise<GovernanceSignalAction> {\n const { body } = await this.post<GovernanceSignalAction>(\n `/v1/governance/signals/${encodeURIComponent(signal_id)}/actions/${encodeURIComponent(action_id)}/outcome`,\n req,\n );\n return body;\n }\n\n async getSignalActionSummary(): Promise<SignalActionSummary> {\n const { body } = await this.get<SignalActionSummary>(\n \"/v1/governance/signals/actions/summary\",\n );\n return body;\n }\n\n // ── Cross-Org Impersonation ───────────────────────────────────────────────\n\n async listImpersonationGrants(): Promise<CrossOrgImpersonationGrant[]> {\n const { body } = await this.get<{ grants: CrossOrgImpersonationGrant[] }>(\n \"/v1/cross-org/impersonation/grants\",\n );\n return body.grants ?? [];\n }\n\n async createImpersonationGrant(\n req: CreateImpersonationGrantRequest,\n ): Promise<CrossOrgImpersonationGrant> {\n const { body } = await this.post<CrossOrgImpersonationGrant>(\n \"/v1/cross-org/impersonation/grants\",\n req,\n );\n return body;\n }\n\n async revokeImpersonationGrant(id: string): Promise<void> {\n await this.post<Record<string, unknown>>(\n `/v1/cross-org/impersonation/grants/${encodeURIComponent(id)}/revoke`,\n {},\n );\n }\n\n async issueImpersonationToken(\n grant_id: string,\n requested_duration_seconds?: number,\n ): Promise<ImpersonationToken> {\n const { body } = await this.post<ImpersonationToken>(\n `/v1/cross-org/impersonation/grants/${encodeURIComponent(grant_id)}/token`,\n { requested_duration_seconds },\n );\n return body;\n }\n\n async validateImpersonationToken(\n token: string,\n ): Promise<ImpersonationValidationResult> {\n const { body } = await this.post<ImpersonationValidationResult>(\n \"/v1/cross-org/impersonation/validate\",\n { token },\n );\n return body;\n }\n\n // ── Constrained governance agents (read surface) ──────────────────────────\n //\n // Three GETs onto the v1-governance-agents edge function. Doctrine:\n // findings produced by these endpoints are advisory signal, never\n // authority. There is no `runGovernanceAgent` method on this client —\n // invocation belongs in CI (atlasent-action `governance-agents` mode),\n // not in application code.\n\n /**\n * List the advisory governance-agent registry for the calling org.\n *\n * Calls `GET /v1/governance/agents`. The registry is reference data\n * seeded at runtime-DB migration time; every row has\n * `authority_class = \"advisory\"` and `can_authorize = false` —\n * structural invariants enforced by the schema, not policy.\n */\n async listGovernanceAgents(): Promise<GovernanceAgent[]> {\n const { body } = await this.get<ListGovernanceAgentsResponse>(\n \"/v1/governance/agents\",\n );\n return [...(body.agents ?? [])];\n }\n\n /**\n * List advisory findings emitted against one governed change.\n *\n * Calls `GET /v1/governance/findings?change_id=…[&agent_slug=…]`.\n * Returns the typed-finding rows in `created_at DESC` order, including\n * `routed_gate_id` when the finding→gate trigger linked them. Findings\n * with `can_authorize === false` (always) are advisory; rendering them\n * never satisfies a gate.\n */\n async listGovernanceFindings(\n query: ListGovernanceFindingsQuery,\n ): Promise<GovernanceAgentFinding[]> {\n if (!query?.change_id) {\n throw new AtlaSentError(\"change_id is required\", { code: \"bad_request\" });\n }\n const params = new URLSearchParams({ change_id: query.change_id });\n if (query.agent_slug) params.set(\"agent_slug\", query.agent_slug);\n const { body } = await this.get<ListGovernanceFindingsResponse>(\n \"/v1/governance/findings\",\n params,\n );\n return [...(body.findings ?? [])];\n }\n\n /**\n * List agent run records against one governed change.\n *\n * Calls `GET /v1/governance/evaluations?change_id=…[&agent_slug=…]`.\n * Returns every persisted evaluation, including `failed` / `timeout`\n * runs and `completed` runs with zero findings — the latter is the\n * positive signal \"the agent ran and found nothing\", which the UI\n * surfaces as `clear`.\n */\n async listGovernanceEvaluations(\n query: ListGovernanceEvaluationsQuery,\n ): Promise<GovernanceAgentEvaluation[]> {\n if (!query?.change_id) {\n throw new AtlaSentError(\"change_id is required\", { code: \"bad_request\" });\n }\n const params = new URLSearchParams({ change_id: query.change_id });\n if (query.agent_slug) params.set(\"agent_slug\", query.agent_slug);\n const { body } = await this.get<ListGovernanceEvaluationsResponse>(\n \"/v1/governance/evaluations\",\n params,\n );\n return [...(body.evaluations ?? [])];\n }\n\n // ── Private adapters for sub-client factories ──────────────────────────────\n // Thin wrappers that expose the private request infrastructure to sub-client\n // factories (scim, evidenceBundles, auth) without widening the public API.\n\n private async _post<T>(\n path: string,\n body: unknown,\n query?: URLSearchParams,\n ): Promise<{ body: T }> {\n const { body: b } = await this.post<T>(path, body, query);\n return { body: b };\n }\n\n private async _get<T>(\n path: string,\n query?: URLSearchParams,\n ): Promise<{ body: T }> {\n const { body: b } = await this.get<T>(path, query);\n return { body: b };\n }\n\n private async _put<T>(path: string, body: unknown): Promise<{ body: T }> {\n return this._requestRaw<T>(path, \"PUT\", body, undefined);\n }\n\n private async _patch<T>(path: string, body: unknown): Promise<{ body: T }> {\n return this._requestRaw<T>(path, \"PATCH\", body, undefined);\n }\n\n private async _delete(path: string): Promise<void> {\n await this._requestRaw<Record<string, unknown>>(path, \"DELETE\", undefined, undefined);\n }\n\n private async _getRaw(path: string): Promise<ArrayBuffer> {\n const url = `${this.baseUrl}${path}`;\n const requestId = globalThis.crypto.randomUUID();\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n \"User-Agent\": this.userAgent,\n \"X-Request-ID\": requestId,\n \"X-AtlaSent-Protocol-Version\": \"1\",\n };\n const response = await this.fetchImpl(url, {\n method: \"GET\",\n headers,\n signal: AbortSignal.timeout(this.timeoutMs),\n });\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new AtlaSentError(`GET ${path} returned ${response.status}`, {\n code: response.status >= 500 ? \"server_error\" : \"bad_request\",\n status: response.status,\n requestId,\n });\n }\n return response.arrayBuffer();\n }\n\n private async _requestRaw<T>(\n path: string,\n method: \"PUT\" | \"PATCH\" | \"DELETE\",\n body: unknown,\n query: URLSearchParams | undefined,\n ): Promise<{ body: T }> {\n const qs =\n query && Array.from(query).length > 0 ? `?${query.toString()}` : \"\";\n const url = `${this.baseUrl}${path}${qs}`;\n const requestId = globalThis.crypto.randomUUID();\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n \"User-Agent\": this.userAgent,\n \"X-Request-ID\": requestId,\n \"X-AtlaSent-Protocol-Version\": \"1\",\n };\n if (method === \"PUT\" && body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n const init: RequestInit = { method, headers, signal: AbortSignal.timeout(this.timeoutMs) };\n if (method === \"PUT\" && body !== undefined) {\n init.body = JSON.stringify(body);\n }\n const response = await this.fetchImpl(url, init);\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new AtlaSentError(`${method} ${path} returned ${response.status}`, {\n code: response.status >= 500 ? \"server_error\" : \"bad_request\",\n status: response.status,\n requestId,\n });\n }\n if (method === \"DELETE\") {\n return { body: {} as T };\n }\n return { body: (await response.json()) as T };\n }\n}\n\n/**\n * Parse the server's `X-RateLimit-*` header triple into a typed\n * {@link RateLimitState}. Returns `null` when any of the three headers\n * is missing or unparseable — callers treat that as \"the server didn't\n * emit rate-limit state\" rather than \"the window is empty\".\n *\n * `X-RateLimit-Reset` is accepted as either unix-seconds (what the\n * AtlaSent edge functions emit today) or an ISO 8601 timestamp.\n */\nfunction parseRateLimitHeaders(headers: Headers): RateLimitState | null {\n const rawLimit = headers.get(\"x-ratelimit-limit\");\n const rawRemaining = headers.get(\"x-ratelimit-remaining\");\n const rawReset = headers.get(\"x-ratelimit-reset\");\n if (rawLimit === null || rawRemaining === null || rawReset === null) {\n return null;\n }\n const limit = Number(rawLimit);\n const remaining = Number(rawRemaining);\n if (!Number.isFinite(limit) || !Number.isFinite(remaining)) {\n return null;\n }\n const resetAt = parseResetHeader(rawReset);\n if (resetAt === null) {\n return null;\n }\n return { limit, remaining, resetAt };\n}\n\nfunction parseResetHeader(raw: string): Date | null {\n const seconds = Number(raw);\n if (Number.isFinite(seconds)) {\n // Standard shape: unix seconds. 10-digit values are in the valid\n // range ~2001–2286 so this heuristic won't confuse a tiny\n // `remaining`-like number for an epoch.\n return new Date(seconds * 1000);\n }\n const ms = Date.parse(raw);\n if (Number.isFinite(ms)) {\n return new Date(ms);\n }\n return null;\n}\n\nfunction mapFetchError(err: unknown, requestId: string): AtlaSentError {\n if (err instanceof AtlaSentError) return err;\n if (err instanceof DOMException && err.name === \"TimeoutError\") {\n return new AtlaSentError(\"Request to AtlaSent API timed out\", {\n code: \"timeout\",\n requestId,\n cause: err,\n });\n }\n if (err instanceof Error && err.name === \"AbortError\") {\n return new AtlaSentError(\"Request to AtlaSent API timed out\", {\n code: \"timeout\",\n requestId,\n cause: err,\n });\n }\n const message = err instanceof Error ? err.message : \"network error\";\n return new AtlaSentError(`Failed to reach AtlaSent API: ${message}`, {\n code: \"network\",\n requestId,\n cause: err,\n });\n}\n\nasync function buildHttpError(\n response: Response,\n requestId: string,\n): Promise<AtlaSentError> {\n const status = response.status;\n const classified = await classifyHttpStatus(response);\n const init: AtlaSentErrorInit = {\n status,\n code: classified.code,\n requestId,\n };\n if (classified.retryAfterMs !== undefined) {\n init.retryAfterMs = classified.retryAfterMs;\n }\n return new AtlaSentError(classified.message, init);\n}\n\nasync function classifyHttpStatus(response: Response): Promise<{\n message: string;\n code: AtlaSentErrorCode;\n retryAfterMs: number | undefined;\n}> {\n const status = response.status;\n const serverMessage = await readServerMessage(response);\n\n if (status === 401) {\n return {\n message: serverMessage ?? \"Invalid API key\",\n code: \"invalid_api_key\",\n retryAfterMs: undefined,\n };\n }\n if (status === 403) {\n return {\n message:\n serverMessage ?? \"Access forbidden — check your API key permissions\",\n code: \"forbidden\",\n retryAfterMs: undefined,\n };\n }\n if (status === 429) {\n return {\n message: serverMessage ?? \"Rate limited by AtlaSent API\",\n code: \"rate_limited\",\n retryAfterMs: parseRetryAfter(response.headers.get(\"retry-after\")),\n };\n }\n if (status >= 500) {\n return {\n message: serverMessage ?? `AtlaSent API returned HTTP ${status}`,\n code: \"server_error\",\n retryAfterMs: undefined,\n };\n }\n return {\n message: serverMessage ?? `AtlaSent API returned HTTP ${status}`,\n code: \"bad_request\",\n retryAfterMs: undefined,\n };\n}\n\nasync function readServerMessage(response: Response): Promise<string | null> {\n try {\n const text = await response.text();\n if (!text) return null;\n try {\n const parsed = JSON.parse(text);\n if (parsed && typeof parsed === \"object\") {\n const msg = (parsed as Record<string, unknown>).message;\n const reason = (parsed as Record<string, unknown>).reason;\n if (typeof msg === \"string\" && msg.length > 0) return msg;\n if (typeof reason === \"string\" && reason.length > 0) return reason;\n }\n } catch {\n // Fall through — treat as plain text.\n }\n return text.length > 500 ? `${text.slice(0, 500)}…` : text;\n } catch {\n return null;\n }\n}\n\n/**\n * Translate an {@link AuditEventsQuery} into `URLSearchParams`. The\n * server expects snake_case keys (`actor_id`) and accepts\n * comma-joined values for `types`; numeric `limit` serializes via\n * `String(n)`. Undefined / empty fields are dropped so the query\n * string stays minimal.\n */\nfunction buildAuditEventsQuery(query: AuditEventsQuery): URLSearchParams {\n const params = new URLSearchParams();\n if (query.types !== undefined && query.types !== \"\") {\n params.set(\"types\", query.types);\n }\n if (query.actor_id !== undefined && query.actor_id !== \"\") {\n params.set(\"actor_id\", query.actor_id);\n }\n if (query.from !== undefined && query.from !== \"\") {\n params.set(\"from\", query.from);\n }\n if (query.to !== undefined && query.to !== \"\") {\n params.set(\"to\", query.to);\n }\n if (query.limit !== undefined) {\n params.set(\"limit\", String(query.limit));\n }\n if (query.cursor !== undefined && query.cursor !== \"\") {\n params.set(\"cursor\", query.cursor);\n }\n return params;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction parseRetryAfter(raw: string | null): number | undefined {\n if (!raw) return undefined;\n const seconds = Number(raw);\n if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);\n const date = Date.parse(raw);\n if (Number.isFinite(date)) {\n const delta = date - Date.now();\n return delta > 0 ? delta : 0;\n }\n return undefined;\n}\n\n// ── SSE stream parser ─────────────────────────────────────────────────────────\n\n/**\n * Parse an SSE `ReadableStream<Uint8Array>` into typed {@link StreamEvent}s.\n *\n * Hardening additions over the original:\n * - Per-event timeout: if no chunk arrives within `timeoutMs` (0 = disabled),\n * throws {@link StreamTimeoutError}.\n * - Partial-JSON guard: wraps `JSON.parse` failures in {@link StreamParseError}\n * rather than letting the raw `SyntaxError` escape.\n * - Calls `onEventId` whenever the server emits an `id:` field so the caller\n * can track the `Last-Event-ID` for reconnection.\n * - Terminal detection: returns on `event: done` OR when a `decision` event\n * carries `done: true` at the top level (server-side terminal signal).\n */\nasync function* parseSseStream(\n body: ReadableStream<Uint8Array>,\n requestId: string,\n timeoutMs: number,\n onEventId: (id: string) => void,\n): AsyncIterable<StreamEvent> {\n const reader = body.getReader();\n const decoder = new TextDecoder(\"utf-8\");\n let buf = \"\";\n\n type ChunkResult =\n | { done: true; value?: undefined }\n | { done: false; value: Uint8Array };\n\n /**\n * Read the next chunk from the reader, applying a per-read timeout when\n * `timeoutMs > 0`. Returns `{ done: true }` when the stream ends, throws\n * {@link StreamTimeoutError} on timeout.\n */\n async function readChunk(): Promise<ChunkResult> {\n if (timeoutMs <= 0) {\n return reader.read() as Promise<ChunkResult>;\n }\n return new Promise<ChunkResult>((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(new StreamTimeoutError(timeoutMs));\n }, timeoutMs);\n (reader.read() as Promise<ChunkResult>).then(\n (result) => {\n clearTimeout(timer);\n resolve(result);\n },\n (err: unknown) => {\n clearTimeout(timer);\n reject(err);\n },\n );\n });\n }\n\n try {\n for (;;) {\n let done: boolean;\n let value: Uint8Array | undefined;\n try {\n const result = await readChunk();\n done = result.done;\n value = result.value;\n } catch (err) {\n if (err instanceof StreamTimeoutError) throw err;\n // Network error mid-stream: surface as AtlaSentError(network) so the\n // caller's reconnection loop can catch and retry.\n throw new AtlaSentError(\n `AtlaSent stream read failed: ${err instanceof Error ? err.message : String(err)}`,\n { code: \"network\", requestId, cause: err },\n );\n }\n\n if (done) break;\n buf += decoder.decode(value, { stream: true });\n\n let boundary: number;\n while ((boundary = buf.indexOf(\"\\n\\n\")) !== -1) {\n const block = buf.slice(0, boundary);\n buf = buf.slice(boundary + 2);\n\n let eventType = \"message\";\n let data = \"\";\n let eventId: string | undefined;\n for (const line of block.split(\"\\n\")) {\n if (line.startsWith(\"event: \")) eventType = line.slice(7).trim();\n else if (line.startsWith(\"data: \")) data = line.slice(6);\n else if (line.startsWith(\"id: \")) eventId = line.slice(4).trim();\n else if (line.startsWith(\"id:\")) eventId = line.slice(3).trim();\n }\n\n if (eventId !== undefined) onEventId(eventId);\n\n if (!data) continue;\n if (eventType === \"done\") return;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(data);\n } catch (err) {\n throw new StreamParseError(data, err);\n }\n\n if (eventType === \"error\") {\n const e = parsed as {\n code?: string;\n message?: string;\n request_id?: string;\n };\n throw new AtlaSentError(\n e.message ?? \"Stream error from AtlaSent API\",\n {\n code: (e.code as AtlaSentErrorCode | undefined) ?? \"server_error\",\n requestId: e.request_id ?? requestId,\n },\n );\n }\n\n if (eventType === \"decision\") {\n const d = parsed as {\n permitted?: boolean;\n decision_id?: string;\n reason?: string;\n audit_hash?: string;\n timestamp?: string;\n is_final?: boolean;\n done?: boolean;\n };\n if (\n typeof d.permitted !== \"boolean\" ||\n typeof d.decision_id !== \"string\"\n ) {\n throw new AtlaSentError(\n \"Malformed decision event from AtlaSent API\",\n {\n code: \"bad_response\",\n requestId,\n },\n );\n }\n // Streaming wire uses legacy {permitted, decision_id} shape;\n // normalise to canonical lowercase decision vocabulary.\n const streamDecision = d.permitted ? \"allow\" : \"deny\";\n const isFinal = d.is_final ?? false;\n yield {\n type: \"decision\",\n decision: streamDecision,\n decision_canonical: streamDecision,\n permitId: d.decision_id,\n reason: d.reason ?? \"\",\n auditHash: d.audit_hash ?? \"\",\n timestamp: d.timestamp ?? \"\",\n isFinal,\n } satisfies StreamDecisionEvent;\n\n // Terminal: final decision OR inline done: true closes the stream.\n if (isFinal || d.done === true) return;\n } else if (eventType === \"progress\") {\n const p = parsed as Record<string, unknown>;\n yield {\n type: \"progress\",\n stage: String(p[\"stage\"] ?? \"\"),\n ...p,\n } satisfies StreamProgressEvent;\n // Server may signal terminal state via done: true on any event type.\n if ((p as Record<string, unknown>).done === true) return;\n } else {\n // Unknown event type: check for done: true as a terminal signal.\n if (\n parsed !== null &&\n typeof parsed === \"object\" &&\n (parsed as Record<string, unknown>).done === true\n ) {\n return;\n }\n }\n // Unknown event types skipped for forward compatibility.\n }\n }\n\n // Stream closed before an explicit `event: done`. If there's leftover\n // partial data in the buffer, it means the stream was cut mid-event.\n if (buf.trim().length > 0) {\n throw new StreamParseError(buf);\n }\n } finally {\n reader.releaseLock();\n }\n}\n","/**\n * Offline verification for audit export bundles.\n *\n * Mirrors `atlasent-api/supabase/functions/v1-audit/verify.ts`. The\n * reference verifier there is the source of truth; this module must\n * stay byte-identical with it on the canonicalization + signing path\n * so a bundle that verifies in the backend verifies here (and vice\n * versa).\n *\n * Primary entry point:\n *\n * ```ts\n * import { verifyBundle } from \"@atlasent/sdk\";\n * const result = await verifyBundle(\"export.json\", { publicKeysPem: [pem] });\n * ```\n *\n * Node 20+ ships Ed25519 in `crypto.webcrypto.subtle`, so no extra\n * dependencies are required.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { webcrypto } from \"node:crypto\";\nimport type { TrustRootSnapshot } from \"./trustRoot.js\";\nimport { getGlobalTrustRootManager } from \"./trustRoot.js\";\nimport { BundleVerificationError } from \"./errors.js\";\n\nconst GENESIS_HASH = \"0\".repeat(64);\n\nconst subtle = webcrypto.subtle;\n\n/** Node's webcrypto CryptoKey — kept local so the module doesn't depend on DOM types. */\ntype WebCryptoKey = webcrypto.CryptoKey;\n\n/** Public key candidate the verifier will try, tagged with its registry id. */\nexport interface VerifyKey {\n keyId: string;\n publicKey: WebCryptoKey;\n}\n\nexport interface BundleVerificationResult {\n /**\n * AND of three checks: adjacency (each event's `previous_hash`\n * equals the prior event's `hash`), per-event hash recomputation\n * from the canonical payload, and `chain_head_hash` matching the\n * last event's stored hash.\n */\n chainIntegrityOk: boolean;\n /** Ed25519 signature verified against one of the supplied public keys. */\n signatureValid: boolean;\n /** `chain_head_hash` equals the last event's stored `hash`. */\n headHashMatches: boolean;\n /** Event ids whose recomputed hash != stored hash. */\n tamperedEventIds: string[];\n /** Which registry key id matched, when `signatureValid` is true. */\n matchedKeyId?: string | undefined;\n /** Non-fatal explanation when a flag is false. */\n reason?: string | undefined;\n /** Convenience: `chainIntegrityOk && signatureValid`. */\n verified: boolean;\n}\n\n/** Parsed bundle shape the verifier consumes. Fields beyond these are ignored. */\nexport interface AuditBundle {\n export_id?: unknown;\n org_id?: unknown;\n chain_head_hash?: unknown;\n event_count?: unknown;\n signed_at?: unknown;\n events?: unknown;\n signature?: unknown;\n signing_key_id?: unknown;\n [k: string]: unknown;\n}\n\nexport interface VerifyBundleOptions {\n /** SPKI-PEM strings (one per key in the active trust set). */\n publicKeysPem?: readonly string[];\n /** Already-imported keys, paired with registry ids (rotation hint). */\n keys?: readonly VerifyKey[];\n /** Trust-root snapshot for revocation + expiry checks. */\n trustRoot?: TrustRootSnapshot;\n /**\n * Opt out of fail-closed snapshot expiry check (ADR-005 D3).\n * Intended for air-gap / offline use cases.\n * Emits a one-time warning per process start.\n */\n allowExpiredSnapshot?: boolean;\n}\n\n// ─── Canonicalization ─────────────────────────────────────────────────────────\n\n/**\n * Reproduces `_shared/rules.ts::canonicalJSON` byte-for-byte:\n * - object keys sorted at every depth\n * - no whitespace\n * - `null`, `undefined`, `NaN`, `±Infinity` all render as `\"null\"`\n * - strings use standard `JSON.stringify` escapes\n */\nexport function canonicalJSON(value: unknown): string {\n if (value === null || value === undefined) return \"null\";\n if (typeof value === \"number\") return Number.isFinite(value) ? String(value) : \"null\";\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n if (typeof value === \"string\") return JSON.stringify(value);\n if (Array.isArray(value)) return \"[\" + value.map(canonicalJSON).join(\",\") + \"]\";\n if (typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n return \"{\" + keys.map((k) => JSON.stringify(k) + \":\" + canonicalJSON(obj[k])).join(\",\") + \"}\";\n }\n return \"null\";\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n const buf = await subtle.digest(\"SHA-256\", new TextEncoder().encode(input));\n return Array.from(new Uint8Array(buf))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n// ─── Envelope reconstruction ──────────────────────────────────────────────────\n\n/**\n * Recreate the exact bytes `handleExport` signed. Key order is\n * load-bearing — must match the object literal in\n * `v1-audit/index.ts::handleExport`. V8 preserves insertion order, so\n * the literal below is byte-identical with what the backend signs.\n */\nexport function signedBytesFor(bundle: AuditBundle): Uint8Array<ArrayBuffer> {\n const envelope = {\n export_id: bundle.export_id,\n org_id: bundle.org_id,\n chain_head_hash: bundle.chain_head_hash,\n event_count: bundle.event_count,\n signed_at: bundle.signed_at,\n events: bundle.events,\n };\n return new TextEncoder().encode(JSON.stringify(envelope));\n}\n\n// ─── Chain verification ───────────────────────────────────────────────────────\n\ninterface ChainEvent {\n id?: unknown;\n hash?: unknown;\n previous_hash?: unknown;\n payload?: unknown;\n}\n\nasync function verifyChainEvents(\n events: ChainEvent[],\n): Promise<{ adjacencyOk: boolean; tamperedIds: string[] }> {\n const tamperedIds: string[] = [];\n let adjacencyOk = true;\n const first = events[0];\n let prevHash =\n first && typeof first.previous_hash === \"string\" ? first.previous_hash : GENESIS_HASH;\n\n for (let i = 0; i < events.length; i++) {\n const e = events[i];\n if (!e || typeof e.hash !== \"string\" || typeof e.previous_hash !== \"string\") {\n tamperedIds.push(String(e?.id ?? `index_${i}`));\n adjacencyOk = false;\n continue;\n }\n if (e.previous_hash !== prevHash) adjacencyOk = false;\n\n const canonical = canonicalJSON(e.payload ?? {});\n const recomputed = await sha256Hex(prevHash + canonical);\n if (recomputed !== e.hash) tamperedIds.push(String(e.id));\n\n prevHash = e.hash;\n }\n\n return { adjacencyOk, tamperedIds };\n}\n\n// ─── Signature verification ───────────────────────────────────────────────────\n\nfunction base64UrlDecode(s: string): Uint8Array<ArrayBuffer> {\n const pad = s.length % 4 === 0 ? \"\" : \"=\".repeat(4 - (s.length % 4));\n const b64 = s.replace(/-/g, \"+\").replace(/_/g, \"/\") + pad;\n const bin = Buffer.from(b64, \"base64\");\n const out = new Uint8Array(bin.byteLength);\n out.set(bin);\n return out;\n}\n\nasync function importSpkiPem(pem: string): Promise<WebCryptoKey> {\n const b64 = pem\n .replace(/-----BEGIN PUBLIC KEY-----/, \"\")\n .replace(/-----END PUBLIC KEY-----/, \"\")\n .replace(/\\s+/g, \"\");\n const bytes = Uint8Array.from(Buffer.from(b64, \"base64\"));\n return subtle.importKey(\"spki\", bytes, { name: \"Ed25519\" }, false, [\"verify\"]);\n}\n\nasync function resolveKeys(options: VerifyBundleOptions | undefined): Promise<VerifyKey[]> {\n const out: VerifyKey[] = [];\n if (options?.keys) out.push(...options.keys);\n if (options?.publicKeysPem) {\n for (let i = 0; i < options.publicKeysPem.length; i++) {\n const pem = options.publicKeysPem[i];\n if (!pem) continue;\n try {\n const pk = await importSpkiPem(pem);\n out.push({ keyId: `pem_${i}`, publicKey: pk });\n } catch {\n // Malformed PEM — skip it, try the rest.\n }\n }\n }\n return out;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\nexport async function verifyAuditBundle(\n bundle: AuditBundle,\n keys: readonly VerifyKey[],\n trustRootOpts?: {\n trustRoot?: TrustRootSnapshot;\n allowExpiredSnapshot?: boolean;\n },\n): Promise<BundleVerificationResult> {\n // ── ADR-005 D3: fail-closed snapshot expiry check ──────────────────\n if (trustRootOpts?.trustRoot) {\n const snap = trustRootOpts.trustRoot;\n const now = Date.now();\n const validUntil = new Date(snap.valid_until).getTime();\n if (now > validUntil && !trustRootOpts.allowExpiredSnapshot) {\n throw new BundleVerificationError({\n reason: \"trust_snapshot_expired\",\n snapshotValidUntil: snap.valid_until,\n snapshotFetchedAt: snap.issued_at,\n });\n }\n }\n\n const events: ChainEvent[] = Array.isArray(bundle.events) ? (bundle.events as ChainEvent[]) : [];\n\n const { adjacencyOk, tamperedIds } = await verifyChainEvents(events);\n\n const last = events[events.length - 1];\n const lastHash = last && typeof last.hash === \"string\" ? last.hash : GENESIS_HASH;\n const headHashMatches =\n typeof bundle.chain_head_hash === \"string\" ? bundle.chain_head_hash === lastHash : false;\n\n const chainIntegrityOk = adjacencyOk && tamperedIds.length === 0 && headHashMatches;\n\n let signatureValid = false;\n let matchedKeyId: string | undefined;\n let reason: string | undefined;\n\n if (keys.length === 0) {\n reason =\n \"no signing keys configured (signing_keys table empty and ATLASENT_EXPORT_SIGNING_KEY_PUBLIC unset)\";\n } else if (typeof bundle.signature !== \"string\" || bundle.signature.length === 0) {\n reason = \"bundle carries no signature\";\n } else {\n try {\n const sigBytes = base64UrlDecode(bundle.signature);\n const envelopeBytes = signedBytesFor(bundle);\n const hint = typeof bundle.signing_key_id === \"string\" ? bundle.signing_key_id : null;\n const ordered = hint\n ? [\n ...keys.filter((k) => k.keyId === hint),\n ...keys.filter((k) => k.keyId !== hint),\n ]\n : Array.from(keys);\n for (const k of ordered) {\n const ok = await subtle.verify(\"Ed25519\", k.publicKey, sigBytes, envelopeBytes);\n if (ok) {\n signatureValid = true;\n matchedKeyId = k.keyId;\n break;\n }\n }\n if (!signatureValid) {\n reason = `signature did not verify under any of ${keys.length} configured public key(s)`;\n }\n } catch (err) {\n reason = `signature check failed: ${err instanceof Error ? err.message : String(err)}`;\n }\n }\n\n // ── ADR-005: revocation check (after signature, before returning) ──\n if (signatureValid && trustRootOpts?.trustRoot) {\n const snap = trustRootOpts.trustRoot;\n const kid = typeof bundle.signing_key_id === \"string\" ? bundle.signing_key_id : null;\n if (kid !== null) {\n const isRevoked = snap.revoked_keys.some((r) => r.kid === kid);\n if (isRevoked) {\n throw new BundleVerificationError({\n reason: \"key_revoked\",\n snapshotValidUntil: snap.valid_until,\n snapshotFetchedAt: snap.issued_at,\n kid,\n });\n }\n // Check role: audit bundles must be signed by R3_audit\n const keyEntry = snap.keys.find((k) => k.kid === kid);\n if (keyEntry && keyEntry.role !== \"R3_audit\") {\n throw new BundleVerificationError({\n reason: \"key_role_mismatch\",\n snapshotValidUntil: snap.valid_until,\n snapshotFetchedAt: snap.issued_at,\n kid,\n });\n }\n }\n }\n\n if (!chainIntegrityOk && reason === undefined) {\n if (tamperedIds.length > 0) reason = `hash mismatch for ${tamperedIds.length} event(s)`;\n else if (!adjacencyOk) reason = \"chain adjacency broken\";\n else if (!headHashMatches) reason = \"chain_head_hash does not match last event\";\n }\n\n return {\n chainIntegrityOk,\n signatureValid,\n headHashMatches,\n tamperedEventIds: tamperedIds,\n matchedKeyId,\n reason,\n verified: chainIntegrityOk && signatureValid,\n };\n}\n\n/**\n * Load a bundle from disk (or a parsed object) and verify it.\n *\n * `publicKeysPem` is the active SPKI-PEM set from\n * `GET /v1-signing-keys`. When omitted, the chain check still runs\n * but `signatureValid` will be false with an explanatory `reason` —\n * callers that want a complete offline check MUST supply the trust\n * set.\n *\n * When `trustRoot` is not supplied, the global trust-root manager's\n * current snapshot is used automatically (B2.3 bootstrap wire-in).\n * Pass `allowExpiredSnapshot: true` to disable fail-closed expiry\n * for air-gap environments.\n */\nexport async function verifyBundle(\n pathOrBundle: string | AuditBundle,\n options?: VerifyBundleOptions,\n): Promise<BundleVerificationResult> {\n let bundle: AuditBundle;\n if (typeof pathOrBundle === \"string\") {\n const raw = await readFile(pathOrBundle, \"utf8\");\n const parsed = JSON.parse(raw);\n // Fixture wrapper shape: { description, bundle }. Accepted for ergonomics.\n bundle =\n parsed && typeof parsed === \"object\" && \"bundle\" in parsed && typeof parsed.bundle === \"object\"\n ? (parsed.bundle as AuditBundle)\n : (parsed as AuditBundle);\n } else {\n bundle = pathOrBundle;\n }\n const keys = await resolveKeys(options);\n // Auto-inject the global trust-root snapshot when none is explicitly provided.\n const effectiveTrustRoot =\n options?.trustRoot ?? getGlobalTrustRootManager().getSnapshot();\n return verifyAuditBundle(bundle, keys, {\n trustRoot: effectiveTrustRoot,\n ...(options?.allowExpiredSnapshot !== undefined && {\n allowExpiredSnapshot: options.allowExpiredSnapshot,\n }),\n });\n}\n","/**\n * Evidence Engine — per-decision proof artifacts, \"why\" traces, and\n * compliance-ready bundles.\n *\n * Turn every AtlaSent decision into tamper-evident proof that buyers\n * can hand to auditors, compliance teams, and regulators.\n *\n * Primary entry points:\n *\n * 1. `buildWhyTrace(decision, reasons, constraintTrace)` — converts\n * the ConstraintTrace from `?include=constraint_trace` into a\n * structured human/machine-readable \"why allowed / why denied\" trace.\n *\n * 2. `buildDecisionReceiptPayload(args)` — assembles the canonical\n * signable payload for a per-decision receipt.\n *\n * 3. `signDecisionReceiptHmac(payload, secret)` — HMAC-SHA256 sign.\n *\n * 4. `verifyDecisionReceiptHmac(receipt, secret)` — offline verify.\n *\n * 5. `computeBundleHash(bundle)` — SHA-256 of an ActionEvidenceBundle.\n *\n * 6. `soc2ControlCoverageForDecision(opts)` — map a decision to SOC 2\n * control coverage.\n *\n * The {@link DecisionReceipt} is the category-defining artifact: a\n * self-contained, signed, human-readable proof that a specific action\n * was (or was not) authorized at a specific moment. Every enforcement\n * adapter produces one; every compliance bundle includes one.\n */\n\nimport type {\n ConstraintTrace,\n ConstraintTracePolicy,\n ConstraintTraceStage,\n DecisionCanonical,\n PermitRecord,\n} from \"./types.js\";\nimport type { AuditEvent } from \"./audit.js\";\nimport type { OverrideV1 } from \"./overrides.js\";\nimport type { ComplianceFramework } from \"./complianceEvidence.js\";\n\n// ── Why Trace ─────────────────────────────────────────────────────────────────\n\n/**\n * One evaluated stage within a policy, in the order the engine ran it.\n */\nexport interface WhyStage {\n /** Engine stage name (e.g. `\"role_check\"`, `\"context\"`). */\n stage: string;\n /** Rule identifier, if the stage is rule-bound. */\n rule?: string;\n /** Whether this stage's predicate fired / matched. */\n matched: boolean;\n /** Non-obvious detail from the engine. */\n detail?: string;\n /**\n * Impact classification:\n * - `\"terminal\"` — this stage caused the outer decision.\n * - `\"contributing\"` — matched but was not the decisive stage.\n * - `\"passing\"` — did not match; execution continued.\n */\n impact: \"terminal\" | \"contributing\" | \"passing\";\n}\n\n/** Per-policy evaluation block within a WhyTrace. */\nexport interface WhyPolicyEvaluation {\n policy_id: string;\n /** Policy-level decision. */\n decision: string;\n /** Engine-side fingerprint of the policy bundle row. */\n fingerprint: string;\n /** Optional risk score from a `risk` rule clause. */\n risk_score?: number;\n /** Stages evaluated for this policy, in order. */\n stages: WhyStage[];\n /** `true` iff this policy's decision drove the outer envelope decision. */\n was_decisive: boolean;\n}\n\n/**\n * Structured \"why allowed / why denied\" trace.\n *\n * Produced by `buildWhyTrace()` from the `ConstraintTrace` returned\n * by `/v1-evaluate?include=constraint_trace`. Suitable for:\n *\n * - UI display (\"Why was this denied?\")\n * - Email / Slack notifications\n * - Compliance-bundle human-readable section\n * - Machine-readable policy audit by external verifiers\n *\n * `summary` is a one-sentence plain-English explanation.\n */\nexport interface WhyTrace {\n decision: DecisionCanonical;\n /** One-sentence human-readable explanation. */\n summary: string;\n /** Policy whose decision drove the outer result. Absent on clean allow. */\n matched_policy_id?: string;\n /** Per-policy evaluation blocks in evaluation order. */\n policy_evaluations: WhyPolicyEvaluation[];\n /**\n * The single stage that caused the terminal outcome, extracted for\n * quick access. `undefined` on a clean allow (no blocking stage).\n */\n terminal_stage?: WhyStage;\n /** Total stages evaluated across all policies. */\n total_stages_evaluated: number;\n}\n\n// ── Decision Receipt ──────────────────────────────────────────────────────────\n\n/** Signing algorithm tag on a {@link DecisionReceipt}. */\nexport type DecisionReceiptAlgorithm = \"hmac-sha256\" | \"ed25519\" | \"none\";\n\n/**\n * The canonical signed payload of a {@link DecisionReceipt}.\n *\n * Field order is load-bearing: HMAC and chain verifiers stringify\n * this object and must reproduce byte-identical output. Never reorder\n * the fields; add new optional fields at the end only.\n */\nexport interface DecisionReceiptPayload {\n receipt_id: string;\n evaluation_id: string;\n org_id: string;\n decision: DecisionCanonical;\n action: string;\n actor: string;\n resource_type: string | null;\n resource_id: string | null;\n reasons: string[];\n /** One-sentence human-readable summary from the WhyTrace. */\n why_summary: string;\n /** Permit ID when the decision was `\"allow\"`. */\n permit_id: string | null;\n /** Permit verification hash when the decision was `\"allow\"`. */\n permit_hash: string | null;\n /** Hash-chained audit-trail entry from the evaluate response. */\n audit_hash: string;\n /** SHA-256 hex of canonical JSON of the evaluate context. */\n context_hash: string;\n /** ISO-8601 when this receipt was issued. */\n issued_at: string;\n /** ISO-8601 TTL, or `null` for non-expiring receipts. */\n expires_at: string | null;\n}\n\n/**\n * A signed, tamper-evident record of a single AtlaSent authorization\n * decision. Self-contained: contains everything an auditor needs to\n * verify the decision without querying the API.\n *\n * **Signature semantics (HMAC-SHA256):**\n *\n * `HMAC-SHA256(secret,\n * receipt_id + \"\\\\n\" + issued_at + \"\\\\n\" + JSON.stringify(payload))`\n *\n * When `algorithm === \"ed25519\"`, `signature` is hex-encoded Ed25519\n * over the same input string encoded as UTF-8.\n *\n * Offline verification: `verifyDecisionReceiptHmac(receipt, secret)`.\n *\n * Callers MUST reject receipts where `algorithm === \"none\"` in any\n * context requiring tamper-evidence.\n */\nexport interface DecisionReceipt {\n receipt_id: string;\n evaluation_id: string;\n org_id: string;\n decision: DecisionCanonical;\n action: string;\n actor: string;\n resource_type: string | null;\n resource_id: string | null;\n reasons: string[];\n /**\n * Full structured \"why\" trace. `null` when the evaluation was\n * performed without `?include=constraint_trace`.\n */\n why_trace: WhyTrace | null;\n permit_id: string | null;\n permit_hash: string | null;\n audit_hash: string;\n /** SHA-256 hex of canonical JSON of the evaluate context. */\n context_hash: string;\n issued_at: string;\n expires_at: string | null;\n algorithm: DecisionReceiptAlgorithm;\n /**\n * Hex (HMAC-SHA256 or Ed25519) signature, or `null` when\n * `algorithm === \"none\"`.\n */\n signature: string | null;\n /** Registry key ID that signed, when `algorithm !== \"none\"`. */\n signing_key_id: string | null;\n /**\n * Full payload that was signed. Pass to `verifyDecisionReceiptHmac`\n * or reconstruct independently for external verification.\n */\n payload: DecisionReceiptPayload;\n}\n\n// ── Action Evidence Bundle ────────────────────────────────────────────────────\n\n/** Coverage summary for one compliance control within a bundle. */\nexport interface ComplianceControlCoverage {\n framework: ComplianceFramework;\n control_id: string;\n title: string;\n /** `true` when this bundle provides sufficient evidence for the control. */\n covered: boolean;\n /** Evidence kinds present in the bundle that map to this control. */\n evidence_kinds: string[];\n}\n\n/**\n * A compliance-ready evidence bundle for a single protected action.\n *\n * Contains everything an auditor needs to verify the authorization\n * decision without querying the API:\n *\n * - The signed {@link DecisionReceipt}\n * - The \"why\" trace (why allowed / why denied)\n * - Audit events from the decision window\n * - Permit chain (when the decision was `\"allow\"`)\n * - Active overrides that influenced the decision\n * - Per-control SOC 2 / compliance coverage map\n *\n * `bundle_hash` is SHA-256 of `JSON.stringify(bundle)` with\n * `bundle_hash` omitted, computed by `computeBundleHash()`. Use it\n * to verify the bundle was not modified after assembly.\n */\nexport interface ActionEvidenceBundle {\n /** Wire format version. */\n v: 1;\n bundle_id: string;\n evaluation_id: string;\n org_id: string;\n action: string;\n actor: string;\n decision: DecisionCanonical;\n receipt: DecisionReceipt;\n why_trace: WhyTrace | null;\n /** Audit events from the evaluation window related to this action. */\n audit_events: AuditEvent[];\n /** Permit chain when the decision was `\"allow\"`. */\n permit_chain: PermitRecord[];\n /** Active overrides that influenced the decision. */\n overrides: OverrideV1[];\n compliance_controls: ComplianceControlCoverage[];\n generated_at: string;\n /** SHA-256 hex of canonical JSON of this bundle (sans this field). */\n bundle_hash: string;\n}\n\n// ── buildWhyTrace ─────────────────────────────────────────────────────────────\n\n/**\n * Convert a raw `ConstraintTrace` (from `?include=constraint_trace`)\n * into a structured {@link WhyTrace} with a human-readable summary.\n *\n * Safe to call with `trace === null` — returns a minimal trace with\n * the decision and a generic summary derived from `reasons`.\n *\n * ```ts\n * import { buildWhyTrace } from \"@atlasent/sdk\";\n *\n * const preflight = await client.evaluatePreflight({ agent, action, context });\n * const why = buildWhyTrace(\n * preflight.evaluation.decision_canonical,\n * preflight.evaluation.reasons,\n * preflight.constraintTrace,\n * );\n * console.log(why.summary);\n * // \"Denied at stage 'role_check': actor lacks deploy role\"\n * ```\n */\nexport function buildWhyTrace(\n decision: DecisionCanonical,\n reasons: readonly string[],\n trace: ConstraintTrace | null,\n): WhyTrace {\n if (!trace) {\n return {\n decision,\n summary: formatSummary(decision, reasons, undefined, undefined),\n policy_evaluations: [],\n total_stages_evaluated: 0,\n };\n }\n\n const matchedPolicyId: string | undefined =\n typeof trace.matching_policy_id === \"string\"\n ? trace.matching_policy_id\n : undefined;\n\n let terminalStage: WhyStage | undefined;\n let totalStages = 0;\n\n const policyEvaluations: WhyPolicyEvaluation[] = (\n trace.rules_evaluated ?? []\n ).map((policy: ConstraintTracePolicy) => {\n const wasDecisive = matchedPolicyId === policy.policy_id;\n let foundTerminal = false;\n\n const stages: WhyStage[] = (policy.stages ?? []).map(\n (s: ConstraintTraceStage, idx: number) => {\n totalStages++;\n const isLast = idx === (policy.stages?.length ?? 1) - 1;\n const candidateForTerminal =\n wasDecisive && !foundTerminal && (s.matched || isLast);\n\n let impact: WhyStage[\"impact\"] = \"passing\";\n\n if (candidateForTerminal) {\n impact = \"terminal\";\n foundTerminal = true;\n terminalStage = {\n stage: s.stage,\n ...(s.rule !== undefined ? { rule: s.rule } : {}),\n matched: s.matched,\n ...(s.detail !== undefined ? { detail: s.detail } : {}),\n impact: \"terminal\",\n };\n } else if (s.matched) {\n impact = \"contributing\";\n }\n\n return {\n stage: s.stage,\n ...(s.rule !== undefined ? { rule: s.rule } : {}),\n matched: s.matched,\n ...(s.detail !== undefined ? { detail: s.detail } : {}),\n impact,\n };\n },\n );\n\n return {\n policy_id: policy.policy_id,\n decision: policy.decision,\n fingerprint: policy.fingerprint,\n ...(policy.risk_score !== undefined ? { risk_score: policy.risk_score } : {}),\n stages,\n was_decisive: wasDecisive,\n };\n });\n\n return {\n decision,\n summary: formatSummary(decision, reasons, matchedPolicyId, terminalStage),\n ...(matchedPolicyId !== undefined ? { matched_policy_id: matchedPolicyId } : {}),\n policy_evaluations: policyEvaluations,\n ...(terminalStage !== undefined ? { terminal_stage: terminalStage } : {}),\n total_stages_evaluated: totalStages,\n };\n}\n\nfunction formatSummary(\n decision: DecisionCanonical,\n reasons: readonly string[],\n matchedPolicyId: string | undefined,\n terminalStage: WhyStage | undefined,\n): string {\n const reason0 = reasons.length > 0 ? reasons[0] : undefined;\n switch (decision) {\n case \"allow\":\n return reason0\n ? `Allowed: ${reason0}`\n : \"Allowed: all policy checks passed.\";\n case \"deny\":\n if (reason0) return `Denied: ${reason0}`;\n if (terminalStage?.detail)\n return `Denied at stage \"${terminalStage.stage}\": ${terminalStage.detail}`;\n if (terminalStage)\n return `Denied at stage \"${terminalStage.stage}\".`;\n if (matchedPolicyId)\n return `Denied by policy ${matchedPolicyId}.`;\n return \"Denied: policy check failed.\";\n case \"hold\":\n return reason0\n ? `Held for review: ${reason0}`\n : \"Held pending human review.\";\n case \"escalate\":\n return reason0\n ? `Escalated: ${reason0}`\n : \"Escalated to a human reviewer.\";\n }\n}\n\n// ── Crypto helpers ────────────────────────────────────────────────────────────\n\nfunction sortedJSON(val: unknown): string {\n if (val === null || val === undefined) return \"null\";\n if (typeof val === \"number\")\n return Number.isFinite(val) ? String(val) : \"null\";\n if (typeof val === \"boolean\") return val ? \"true\" : \"false\";\n if (typeof val === \"string\") return JSON.stringify(val);\n if (Array.isArray(val)) return \"[\" + val.map(sortedJSON).join(\",\") + \"]\";\n if (typeof val === \"object\") {\n const obj = val as Record<string, unknown>;\n return (\n \"{\" +\n Object.keys(obj)\n .sort()\n .map((k) => JSON.stringify(k) + \":\" + sortedJSON(obj[k]))\n .join(\",\") +\n \"}\"\n );\n }\n return \"null\";\n}\n\nfunction hexEncode(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n const bytes = new TextEncoder().encode(input);\n if (\n typeof globalThis !== \"undefined\" &&\n globalThis.crypto?.subtle?.digest\n ) {\n const buf = await globalThis.crypto.subtle.digest(\"SHA-256\", bytes);\n return hexEncode(new Uint8Array(buf));\n }\n try {\n const { createHash } = await import(\n /* @vite-ignore */ /* webpackIgnore: true */ \"node:crypto\"\n );\n return createHash(\"sha256\").update(input, \"utf8\").digest(\"hex\");\n } catch {\n return \"\";\n }\n}\n\n// ── Context hash ──────────────────────────────────────────────────────────────\n\n/**\n * Compute SHA-256 hex of the recursively key-sorted canonical JSON of\n * `context`. Used as `context_hash` on a `DecisionReceipt` so the\n * original evaluate context can be independently verified offline.\n */\nexport async function computeContextHash(\n context: Record<string, unknown>,\n): Promise<string> {\n return sha256Hex(sortedJSON(context));\n}\n\n// ── Receipt payload builder ───────────────────────────────────────────────────\n\n/**\n * Assemble a {@link DecisionReceiptPayload} — the canonical object\n * that is serialised and signed. Field insertion order is fixed;\n * do NOT reorder the fields below.\n */\nexport function buildDecisionReceiptPayload(args: {\n receipt_id: string;\n evaluation_id: string;\n org_id: string;\n decision: DecisionCanonical;\n action: string;\n actor: string;\n resource_type?: string | null;\n resource_id?: string | null;\n reasons: readonly string[];\n why_summary: string;\n permit_id?: string | null;\n permit_hash?: string | null;\n audit_hash: string;\n context_hash: string;\n issued_at: string;\n expires_at?: string | null;\n}): DecisionReceiptPayload {\n return {\n receipt_id: args.receipt_id,\n evaluation_id: args.evaluation_id,\n org_id: args.org_id,\n decision: args.decision,\n action: args.action,\n actor: args.actor,\n resource_type: args.resource_type ?? null,\n resource_id: args.resource_id ?? null,\n reasons: Array.from(args.reasons),\n why_summary: args.why_summary,\n permit_id: args.permit_id ?? null,\n permit_hash: args.permit_hash ?? null,\n audit_hash: args.audit_hash,\n context_hash: args.context_hash,\n issued_at: args.issued_at,\n expires_at: args.expires_at ?? null,\n };\n}\n\n/**\n * Canonical input string signed by both HMAC-SHA256 and Ed25519\n * receipt signers.\n *\n * Format: `receipt_id + \"\\n\" + issued_at + \"\\n\" + JSON.stringify(payload)`\n */\nexport function receiptSigningInput(payload: DecisionReceiptPayload): string {\n return (\n payload.receipt_id +\n \"\\n\" +\n payload.issued_at +\n \"\\n\" +\n JSON.stringify(payload)\n );\n}\n\n// ── HMAC-SHA256 sign / verify ─────────────────────────────────────────────────\n\n/**\n * HMAC-SHA256 sign a {@link DecisionReceiptPayload}. Returns the\n * hex-encoded MAC. Store as `receipt.signature` with\n * `algorithm: \"hmac-sha256\"`.\n *\n * Uses `crypto.subtle` (browser / Node 20+ / Cloudflare) or falls\n * back to `node:crypto` on older Node runtimes.\n */\nexport async function signDecisionReceiptHmac(\n payload: DecisionReceiptPayload,\n secret: string,\n): Promise<string> {\n const input = receiptSigningInput(payload);\n const keyBytes = new TextEncoder().encode(secret);\n const msgBytes = new TextEncoder().encode(input);\n\n if (typeof globalThis !== \"undefined\" && globalThis.crypto?.subtle) {\n const key = await globalThis.crypto.subtle.importKey(\n \"raw\",\n keyBytes,\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n const sig = await globalThis.crypto.subtle.sign(\"HMAC\", key, msgBytes);\n return hexEncode(new Uint8Array(sig));\n }\n\n try {\n const { createHmac } = await import(\n /* @vite-ignore */ /* webpackIgnore: true */ \"node:crypto\"\n );\n return createHmac(\"sha256\", secret).update(input).digest(\"hex\");\n } catch {\n return \"\";\n }\n}\n\n/**\n * Verify an HMAC-SHA256-signed {@link DecisionReceipt} offline.\n * Returns `false` (does not throw) on any verification failure.\n *\n * Callers MUST reject receipts where `receipt.algorithm !== \"hmac-sha256\"`.\n */\nexport async function verifyDecisionReceiptHmac(\n receipt: DecisionReceipt,\n secret: string,\n): Promise<boolean> {\n if (receipt.algorithm !== \"hmac-sha256\" || !receipt.signature) return false;\n const expected = await signDecisionReceiptHmac(receipt.payload, secret);\n return timingSafeEqual(expected, receipt.signature);\n}\n\nfunction timingSafeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let result = 0;\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return result === 0;\n}\n\n// ── Bundle hash ───────────────────────────────────────────────────────────────\n\n/**\n * Compute SHA-256 hex of `JSON.stringify(bundle)` with `bundle_hash`\n * omitted. Store as `bundle.bundle_hash` after assembly.\n *\n * An external verifier can reproduce this value independently to\n * confirm the bundle was not modified after export.\n */\nexport async function computeBundleHash(\n bundle: Omit<ActionEvidenceBundle, \"bundle_hash\">,\n): Promise<string> {\n return sha256Hex(JSON.stringify(bundle));\n}\n\n// ── Compliance control coverage ───────────────────────────────────────────────\n\n/**\n * Return the SOC 2 controls covered by a single authorization decision,\n * given what the bundle contains. Suitable for populating\n * `ActionEvidenceBundle.compliance_controls`.\n *\n * For ISO 27001 / GDPR / HIPAA coverage use the `@atlasent/evidence-bundle`\n * package's `buildEvidenceBundle()` which handles multi-framework mapping.\n */\nexport function soc2ControlCoverageForDecision(opts: {\n decision: DecisionCanonical;\n hasPermitChain: boolean;\n hasAuditEvents: boolean;\n hasOverrides: boolean;\n}): ComplianceControlCoverage[] {\n return [\n {\n framework: \"soc2\",\n control_id: \"CC7.2\",\n title: \"Audit trail completeness\",\n covered: opts.hasAuditEvents,\n evidence_kinds: [\"audit_log_slice\"],\n },\n {\n framework: \"soc2\",\n control_id: \"CC8.1\",\n title: \"Change management / HITL authorization\",\n covered: opts.decision === \"allow\" && opts.hasPermitChain,\n evidence_kinds: [\"permit_chain\"],\n },\n {\n framework: \"soc2\",\n control_id: \"CC6.1\",\n title: \"Logical access controls — authorization enforcement\",\n covered: true,\n evidence_kinds: [\"policy_snapshot\"],\n },\n {\n framework: \"soc2\",\n control_id: \"CC3.2\",\n title: \"Policy violations and override tracking\",\n covered: opts.hasOverrides,\n evidence_kinds: [\"policy_snapshot\", \"permit_chain\"],\n },\n ];\n}\n","/**\n * `atlasent.protect(...)` — the one-call, fail-closed execution-time\n * authorization boundary.\n *\n * ```ts\n * import atlasent from \"@atlasent/sdk\";\n *\n * const permit = await atlasent.protect({\n * agent: \"deploy-bot\",\n * action: \"production.deploy\",\n * context: { commit, approver },\n * });\n * // …run the action. If we got here, AtlaSent authorized it\n * // end-to-end (evaluate + verifyPermit).\n * ```\n *\n * Unlike {@link AtlaSentClient.evaluate}, `protect` never returns a\n * denied decision. On deny, it throws {@link AtlaSentDeniedError};\n * on transport / auth / server failure it throws\n * {@link AtlaSentError}. The action cannot execute unless a valid\n * {@link Permit} is returned — this is the SDK's category boundary,\n * not a helper.\n *\n * `protectWithEvidence` is the same contract plus a signed\n * {@link DecisionReceipt} minted on the way out. Use it when you need\n * tamper-evident proof of authorization stored alongside the action\n * record (deploy logs, payment records, close workflows).\n */\n\nimport { AtlaSentClient } from \"./client.js\";\nimport type { DeployGateRequest, DeployGateResponse } from \"./types.js\";\nimport {\n AtlaSentDeniedError,\n AtlaSentError,\n BundleVerificationError,\n normalizePermitOutcome,\n type AtlaSentDecision,\n} from \"./errors.js\";\nimport { getGlobalTrustRootManager } from \"./trustRoot.js\";\nimport type { AtlaSentClientOptions, ConstraintTrace } from \"./types.js\";\nimport {\n buildDecisionReceiptPayload,\n buildWhyTrace,\n computeContextHash,\n signDecisionReceiptHmac,\n} from \"./evidenceEngine.js\";\nimport type {\n DecisionReceipt,\n DecisionReceiptAlgorithm,\n} from \"./evidenceEngine.js\";\n\n/** Input to {@link protect}. Same shape as `EvaluateRequest`. */\nexport interface ProtectRequest {\n agent: string;\n action: string;\n context?: Record<string, unknown>;\n}\n\n/**\n * Success return from {@link protect}. The action is authorized\n * end-to-end — evaluation allowed AND the resulting permit verified.\n */\nexport interface Permit {\n /** Opaque permit / decision identifier. */\n permitId: string;\n /** Verification hash bound to the permit. */\n permitHash: string;\n /** Audit-trail entry associated with the decision (hash-chained). */\n auditHash: string;\n /** Human-readable reason from the policy engine. */\n reason: string;\n /** ISO 8601 timestamp of the verification. */\n timestamp: string;\n /** ISO-8601 expiration timestamp of the permit. null on pre-rollout servers. */\n permitExpiresAt: string | null;\n}\n\n/** Configuration for the process-wide singleton used by {@link protect}. */\nexport interface ConfigureOptions {\n /** Overrides `ATLASENT_API_KEY` env var. */\n apiKey?: string;\n /** Overrides the default `https://api.atlasent.io`. */\n baseUrl?: string;\n /** Per-request timeout in ms. */\n timeoutMs?: number;\n /** Inject a custom fetch (primarily for tests). */\n fetch?: typeof fetch;\n /** Override the retry policy. Pass `{ maxAttempts: 1 }` to disable retries. */\n retryPolicy?: import(\"./retry.js\").RetryPolicy;\n}\n\nlet sharedClient: AtlaSentClient | null = null;\nlet overrides: ConfigureOptions = {};\n\n/**\n * Configure the singleton client used by {@link protect}. Optional —\n * if `ATLASENT_API_KEY` is set in the environment, `protect` works\n * without any configuration. Calling `configure` again replaces the\n * singleton; subsequent `protect` calls use the new settings.\n */\nexport function configure(options: ConfigureOptions): void {\n overrides = { ...overrides, ...options };\n sharedClient = null;\n}\n\n/**\n * Run the canonical Deploy Gate V1 helper using the process-wide client.\n * Defaults to action `production.deploy`; execution is allowed only after\n * server-side `/v1-evaluate` and `/v1-verify-permit` both pass.\n */\nexport async function deployGate(\n request: DeployGateRequest = {},\n): Promise<DeployGateResponse> {\n return getClient().deployGate(request);\n}\n\n/** Reset the singleton. Exported for tests; not part of the public API. */\nexport function __resetSharedClientForTests(): void {\n sharedClient = null;\n overrides = {};\n}\n\nfunction getClient(): AtlaSentClient {\n if (sharedClient) return sharedClient;\n\n // Guard process.env access so this module is safe in browser and\n // edge-runtime environments where `process` is not defined as a global.\n const envApiKey =\n typeof process !== \"undefined\" && process.env\n ? process.env.ATLASENT_API_KEY\n : undefined;\n\n const apiKey = overrides.apiKey ?? envApiKey;\n if (!apiKey) {\n throw new AtlaSentError(\n \"AtlaSent is not configured. Set ATLASENT_API_KEY in the environment, or call atlasent.configure({ apiKey }).\",\n { code: \"invalid_api_key\" },\n );\n }\n const options: AtlaSentClientOptions = { apiKey };\n if (overrides.baseUrl !== undefined) options.baseUrl = overrides.baseUrl;\n if (overrides.timeoutMs !== undefined)\n options.timeoutMs = overrides.timeoutMs;\n if (overrides.fetch !== undefined) options.fetch = overrides.fetch;\n if (overrides.retryPolicy !== undefined)\n options.retryPolicy = overrides.retryPolicy;\n sharedClient = new AtlaSentClient(options);\n return sharedClient;\n}\n\n// Mirrors the server-side ACTION_TYPE_RE in v1-evaluate/handler.ts.\nconst ACTION_TYPE_RE = /^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$/;\n\nfunction wireDecisionToDenied(serverDecision: string): AtlaSentDecision {\n // Normalise to lowercase before matching — the decision field is now\n // always lowercase from evaluate(), but defensive lower-casing here\n // handles any edge case where an older code path sends uppercase.\n const lower = serverDecision.toLowerCase();\n if (lower === \"hold\" || lower === \"escalate\") return lower;\n return \"deny\";\n}\n\n// ── Execution-hash helpers ────────────────────────────────────────────────────\n\n/**\n * Sort all object keys recursively so the JSON serialization is\n * deterministic (RFC-8785-style canonical form). Arrays are preserved\n * in insertion order; only object keys are sorted.\n */\nfunction sortKeysDeep(val: unknown): unknown {\n if (Array.isArray(val)) return val.map(sortKeysDeep);\n if (val !== null && typeof val === \"object\") {\n return Object.keys(val as object)\n .sort()\n .reduce<Record<string, unknown>>((acc, k) => {\n acc[k] = sortKeysDeep((val as Record<string, unknown>)[k]);\n return acc;\n }, {});\n }\n return val;\n}\n\n/**\n * Compute a SHA-256 hex digest of the recursively key-sorted canonical\n * JSON of `payload`. Used as `execution_hash` on the permit-consume\n * (verify) request so the server can validate the evaluate payload\n * was not tampered with between evaluate and consume.\n *\n * Falls back to `node:crypto` when `crypto.subtle` is unavailable\n * (Node < 20 without the Web Crypto global).\n */\nasync function computeExecutionHash(payload: unknown): Promise<string> {\n const sorted = sortKeysDeep(payload);\n const canonical = JSON.stringify(sorted);\n\n // Prefer the Web Crypto API (available in browsers, Node 20+,\n // Cloudflare Workers, Deno, etc.).\n if (\n typeof globalThis !== \"undefined\" &&\n globalThis.crypto?.subtle?.digest\n ) {\n const bytes = new TextEncoder().encode(canonical);\n const buf = await globalThis.crypto.subtle.digest(\"SHA-256\", bytes);\n return Array.from(new Uint8Array(buf))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n // Fallback: node:crypto (Node < 20 or environments without crypto.subtle).\n try {\n // Dynamic import so bundlers that target browsers don't pull in\n // node internals. The `node:` prefix avoids any user-land shim.\n const { createHash } =\n await import(/* @vite-ignore */ /* webpackIgnore: true */ \"node:crypto\");\n return createHash(\"sha256\").update(canonical, \"utf8\").digest(\"hex\");\n } catch {\n // Last-resort: if neither crypto.subtle nor node:crypto is available\n // (very old Node, restricted runtime), return an empty string so the\n // verify call still proceeds — the server will reject if execution_hash\n // is required for production permits.\n // eslint-disable-next-line no-console\n console.warn(\n \"[atlasent] Could not compute execution_hash: neither crypto.subtle \" +\n \"nor node:crypto is available in this runtime.\",\n );\n return \"\";\n }\n}\n\nfunction generateReceiptId(): string {\n if (\n typeof globalThis !== \"undefined\" &&\n typeof globalThis.crypto?.randomUUID === \"function\"\n ) {\n return globalThis.crypto.randomUUID();\n }\n return `rcpt_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/**\n * Authorize an action end-to-end. On allow, returns a verified\n * {@link Permit}. On anything else, throws:\n *\n * - {@link AtlaSentDeniedError} — policy denied, or the permit\n * failed verification. Fail-closed: if this throws, the action\n * MUST NOT proceed.\n * - {@link AtlaSentError} — transport, timeout, auth, rate-limit,\n * or server error. Same fail-closed contract: do not proceed.\n */\nexport async function protect(request: ProtectRequest): Promise<Permit> {\n if (!ACTION_TYPE_RE.test(request.action)) {\n throw new AtlaSentError(\n `action must be in dot-notation format (e.g. \"production.deploy\"). Got: ${JSON.stringify(request.action)}`,\n { code: \"bad_request\" },\n );\n }\n // ADR-005 D3: fail-closed on expired trust snapshot. checkExpiry() also\n // emits the one-time half-life warning if >50% of validity window has elapsed.\n const trustMgr = getGlobalTrustRootManager({ disableRefresh: false });\n if (trustMgr.checkExpiry() === \"expired\") {\n const snap = trustMgr.getSnapshot();\n throw new BundleVerificationError({\n reason: \"trust_snapshot_expired\",\n snapshotValidUntil: snap.valid_until,\n snapshotFetchedAt: snap.issued_at,\n });\n }\n const client = getClient();\n const evaluation = await client.evaluate(request);\n\n // decision is now canonical lowercase: \"allow\" | \"deny\" | \"hold\" | \"escalate\"\n if (evaluation.decision !== \"allow\") {\n throw new AtlaSentDeniedError({\n decision: wireDecisionToDenied(evaluation.decision),\n evaluationId: evaluation.permitId,\n reason: evaluation.reason,\n auditHash: evaluation.auditHash,\n });\n }\n\n const environment = request.context?.environment as string | undefined;\n if (!environment) {\n throw new AtlaSentError(\n 'context.environment is required. Pass the environment where this action executes (e.g. \"production\", \"staging\").',\n { code: \"bad_request\" },\n );\n }\n\n // Compute execution_hash over the original evaluate payload so\n // the server can validate integrity on permit consume.\n const evaluatePayload = {\n action_type: request.action,\n actor_id: request.agent,\n context: request.context ?? {},\n };\n const execution_hash = await computeExecutionHash(evaluatePayload);\n\n const verifyRequest: {\n permitId: string;\n agent: string;\n action: string;\n context?: Record<string, unknown>;\n environment: string;\n execution_hash?: string;\n } = {\n permitId: evaluation.permitId,\n agent: request.agent,\n action: request.action,\n environment,\n ...(execution_hash ? { execution_hash } : {}),\n };\n if (request.context !== undefined) verifyRequest.context = request.context;\n const verification = await client.verifyPermit(verifyRequest);\n\n if (!verification.verified) {\n const outcome = normalizePermitOutcome(verification.outcome);\n throw new AtlaSentDeniedError({\n decision: \"deny\",\n evaluationId: evaluation.permitId,\n reason: `Permit failed verification (${verification.outcome})`,\n auditHash: evaluation.auditHash,\n ...(outcome !== undefined && { outcome }),\n });\n }\n\n return {\n permitId: evaluation.permitId,\n permitHash: verification.permitHash,\n auditHash: evaluation.auditHash,\n reason: evaluation.reason,\n timestamp: verification.timestamp,\n permitExpiresAt: verification.expiresAt ?? null,\n };\n}\n\n// ── Evidence-enhanced protect ─────────────────────────────────────────────────\n\n/**\n * A verified {@link Permit} with an embedded signed {@link DecisionReceipt}.\n *\n * Returned by {@link protectWithEvidence}. Store `receipt` alongside\n * your action record (deploy logs, payment records, close workflows)\n * to give auditors a self-contained proof of authorization.\n */\nexport interface PermitWithEvidence extends Permit {\n /** Signed per-decision receipt. `algorithm: \"none\"` when no signing secret was supplied. */\n receipt: DecisionReceipt;\n}\n\n/** Options for {@link protectWithEvidence}. */\nexport interface ProtectWithEvidenceOptions {\n /**\n * HMAC-SHA256 signing secret. When provided, the receipt is signed\n * and can be verified offline with `verifyDecisionReceiptHmac`.\n * Recommend `process.env.ATLASENT_RECEIPT_SIGNING_SECRET`.\n */\n signingSecret?: string;\n /**\n * Registry key ID recorded on the receipt, paired with `signingSecret`.\n * Used for key rotation: store the ID alongside the receipt so\n * verifiers know which key to use.\n */\n signingKeyId?: string;\n /**\n * If you have already called `client.evaluatePreflight()` for this\n * request, pass `constraintTrace` here to populate\n * `receipt.why_trace` with the full stage-by-stage \"why\" trace.\n * When omitted, `why_trace` is `null` on the receipt.\n */\n constraintTrace?: ConstraintTrace | null;\n}\n\n/**\n * Authorize an action end-to-end and mint a signed {@link DecisionReceipt}.\n *\n * Same fail-closed contract as {@link protect} — throws\n * {@link AtlaSentDeniedError} on deny, {@link AtlaSentError} on\n * transport failure. The action MUST NOT proceed if this throws.\n *\n * On allow, returns the verified `Permit` plus a signed `DecisionReceipt`\n * that captures:\n * - The evaluation ID and decision\n * - Human-readable reasons\n * - Permit ID and hash\n * - Audit-trail hash (hash-chain link)\n * - SHA-256 of the evaluate context (tamper-evidence for the inputs)\n * - Optional \"why\" trace (pass `constraintTrace` from `evaluatePreflight`)\n *\n * ```ts\n * const { permit, receipt } = await protectWithEvidence(\n * { agent: \"deploy-bot\", action: \"production.deploy\", context },\n * {\n * signingSecret: process.env.ATLASENT_RECEIPT_SIGNING_SECRET,\n * signingKeyId: \"key-v1\",\n * },\n * );\n * // Store alongside the deployment record.\n * await db.deployments.create({ commitSha, permit, receipt });\n * ```\n */\nexport async function protectWithEvidence(\n request: ProtectRequest,\n opts: ProtectWithEvidenceOptions = {},\n): Promise<PermitWithEvidence> {\n if (!ACTION_TYPE_RE.test(request.action)) {\n throw new AtlaSentError(\n `action must be in dot-notation format (e.g. \"production.deploy\"). Got: ${JSON.stringify(request.action)}`,\n { code: \"bad_request\" },\n );\n }\n const client = getClient();\n\n // 1. Evaluate (same logic as protect()).\n const evaluation = await client.evaluate(request);\n\n if (evaluation.decision !== \"allow\") {\n throw new AtlaSentDeniedError({\n decision: wireDecisionToDenied(evaluation.decision),\n evaluationId: evaluation.permitId,\n reason: evaluation.reason,\n auditHash: evaluation.auditHash,\n });\n }\n\n // 2. Extract environment, compute execution_hash, verify permit.\n const environment = request.context?.environment as string | undefined;\n if (!environment) {\n throw new AtlaSentError(\n 'context.environment is required. Pass the environment where this action executes (e.g. \"production\", \"staging\").',\n { code: \"bad_request\" },\n );\n }\n\n const evaluatePayload = {\n action_type: request.action,\n actor_id: request.agent,\n context: request.context ?? {},\n };\n const execution_hash = await computeExecutionHash(evaluatePayload);\n\n const verifyRequest: {\n permitId: string;\n agent: string;\n action: string;\n context?: Record<string, unknown>;\n environment: string;\n execution_hash?: string;\n } = {\n permitId: evaluation.permitId,\n agent: request.agent,\n action: request.action,\n environment,\n ...(execution_hash ? { execution_hash } : {}),\n };\n if (request.context !== undefined) verifyRequest.context = request.context;\n const verification = await client.verifyPermit(verifyRequest);\n\n if (!verification.verified) {\n const outcome = normalizePermitOutcome(verification.outcome);\n throw new AtlaSentDeniedError({\n decision: \"deny\",\n evaluationId: evaluation.permitId,\n reason: `Permit failed verification (${verification.outcome})`,\n auditHash: evaluation.auditHash,\n ...(outcome !== undefined && { outcome }),\n });\n }\n\n // 3. Build the receipt.\n const contextHash = await computeContextHash(request.context ?? {});\n\n const whyTrace = buildWhyTrace(\n \"allow\",\n evaluation.reasons,\n opts.constraintTrace ?? null,\n );\n\n const issuedAt = new Date().toISOString();\n const receiptId = generateReceiptId();\n const orgId = evaluation.permit?.orgId ?? \"\";\n\n const payload = buildDecisionReceiptPayload({\n receipt_id: receiptId,\n evaluation_id: evaluation.evaluationId,\n org_id: orgId,\n decision: \"allow\",\n action: request.action,\n actor: request.agent,\n resource_type:\n (request.context?.resource_type as string | undefined) ?? null,\n resource_id:\n (request.context?.resource_id as string | undefined) ?? null,\n reasons: evaluation.reasons,\n why_summary: whyTrace.summary,\n permit_id: evaluation.permitId,\n permit_hash: verification.permitHash,\n audit_hash: evaluation.auditHash,\n context_hash: contextHash,\n issued_at: issuedAt,\n });\n\n // 4. Sign if secret is provided.\n let signature: string | null = null;\n let algorithm: DecisionReceiptAlgorithm = \"none\";\n\n if (opts.signingSecret) {\n signature = await signDecisionReceiptHmac(payload, opts.signingSecret);\n algorithm = \"hmac-sha256\";\n }\n\n const receipt: DecisionReceipt = {\n receipt_id: receiptId,\n evaluation_id: evaluation.evaluationId,\n org_id: orgId,\n decision: \"allow\",\n action: request.action,\n actor: request.agent,\n resource_type:\n (request.context?.resource_type as string | undefined) ?? null,\n resource_id:\n (request.context?.resource_id as string | undefined) ?? null,\n reasons: evaluation.reasons,\n why_trace:\n opts.constraintTrace !== undefined ? whyTrace : null,\n permit_id: evaluation.permitId,\n permit_hash: verification.permitHash,\n audit_hash: evaluation.auditHash,\n context_hash: contextHash,\n issued_at: issuedAt,\n expires_at: null,\n algorithm,\n signature,\n signing_key_id: opts.signingKeyId ?? null,\n payload,\n };\n\n return {\n permitId: evaluation.permitId,\n permitHash: verification.permitHash,\n auditHash: evaluation.auditHash,\n reason: evaluation.reason,\n timestamp: verification.timestamp,\n permitExpiresAt: verification.expiresAt ?? null,\n receipt,\n };\n}\n","/**\n * `requirePermit` — higher-order execution gate for dangerous operations.\n *\n * Wraps any dangerous operation so it can only run after AtlaSent\n * authorizes it end-to-end (evaluate + verifyPermit). If authorization\n * is denied or the transport fails, the executor is never called.\n *\n * ```ts\n * import atlasent from \"@atlasent/sdk\";\n *\n * await atlasent.requirePermit(\n * {\n * action_type: \"database.table.drop\",\n * actor_id: \"agent:code-agent\",\n * resource_id: \"prod-db.users\",\n * environment: \"production\",\n * context: { reversibility: \"irreversible\", blast_radius: \"customer_data\" },\n * },\n * async () => {\n * await db.raw(\"DROP TABLE users\");\n * },\n * );\n * ```\n *\n * Unlike calling the executor directly, dangerous code cannot bypass\n * this gate: if `requirePermit` throws, the executor never runs.\n */\n\nimport { protect } from \"./protect.js\";\n\n/**\n * Catalog of built-in protected action types, mirroring `CanonicalProtectedActionType`\n * in the OpenAPI spec. Use these constants as `action_type` values in\n * {@link requirePermit} calls instead of bare strings.\n *\n * ```ts\n * await requirePermit(\n * { action_type: CanonicalProtectedActionType.DATABASE_TABLE_DELETE, ... },\n * () => db.raw(\"DELETE FROM users\"),\n * );\n * ```\n */\nexport const CanonicalProtectedActionType = {\n PRODUCTION_DEPLOY: \"production.deploy\",\n HR_EMPLOYEE_OFFBOARD: \"hr.employee.offboard\",\n HR_ACCESS_REVOKE: \"hr.access.revoke\",\n HR_ROLE_ESCALATE: \"hr.role.escalate\",\n ML_MODEL_PROMOTE: \"ml.model.promote\",\n ML_MODEL_RETIRE: \"ml.model.retire\",\n ML_MODEL_FINE_TUNE: \"ml.model.fine_tune\",\n CUSTOMER_DATA_DELETE: \"customer.data.delete\",\n CONTRACT_EXECUTE: \"contract.execute\",\n CONTRACT_AMEND: \"contract.amend\",\n PRICING_RULE_PUBLISH: \"pricing.rule.publish\",\n PRICING_DISCOUNT_APPROVE: \"pricing.discount.approve\",\n SECURITY_INCIDENT_ESCALATE: \"security.incident.escalate\",\n SECURITY_ACCESS_QUARANTINE: \"security.access.quarantine\",\n ACCESS_CERT_REVOKE: \"access.cert.revoke\",\n PERIOD_CLOSE_CERTIFY: \"period.close.certify\",\n DATABASE_MIGRATION_APPLY: \"database.migration.apply\",\n DATABASE_SCHEMA_DROP: \"database.schema.drop\",\n DATABASE_TABLE_DELETE: \"database.table.delete\",\n} as const;\n\nexport type CanonicalProtectedActionType =\n (typeof CanonicalProtectedActionType)[keyof typeof CanonicalProtectedActionType];\n\n/**\n * Describes a potentially dangerous action to be authorized before\n * the executor runs. Passed as the first argument to {@link requirePermit}.\n */\nexport type ProtectedAction = {\n /** Namespaced action type — e.g. \"database.table.drop\". */\n action_type: string;\n /** Agent or user requesting the action — e.g. \"agent:deploy-bot\". */\n actor_id: string;\n /** Resource being acted upon — e.g. \"prod-db.users\". */\n resource_id: string;\n /** Target deployment environment. Controls policy strictness. */\n environment: \"development\" | \"staging\" | \"production\";\n /** Arbitrary risk context forwarded to the policy engine. */\n context: Record<string, unknown>;\n};\n\n/**\n * Authorize a dangerous operation before running it.\n *\n * Calls `protect` (evaluate + verifyPermit) with the {@link ProtectedAction}\n * descriptor. If authorization succeeds, calls `execute` and returns its\n * result. On any failure — policy deny, invalid permit, transport error —\n * `execute` is never called and the error propagates to the caller.\n *\n * This is the pattern primitive: dangerous code should be callable\n * **only** through this wrapper. In code review, any operation in the list\n * below is illegal unless it appears inside `requirePermit(...)`:\n *\n * - `db.raw(...)` / `DROP TABLE` / `DELETE FROM` / `TRUNCATE TABLE`\n * - `exec(...)` / `rm -rf` / `kubectl delete` / `terraform destroy`\n * - `stripe.transfers.create(...)` / `github.deployments.create(...)`\n * - `railway.volumes.delete(...)` / `supabase.from(...).delete()`\n */\nexport async function requirePermit<T>(\n action: ProtectedAction,\n execute: () => Promise<T>,\n): Promise<T> {\n await protect({\n agent: action.actor_id,\n action: action.action_type,\n context: {\n resource_id: action.resource_id,\n environment: action.environment,\n ...action.context,\n },\n });\n return execute();\n}\n\n/**\n * Patterns for shell / database commands that are dangerous and must\n * be wrapped in {@link requirePermit} before execution.\n */\nconst DESTRUCTIVE_PATTERNS: ReadonlyArray<RegExp> = [\n /rm\\s+-rf/,\n /DROP\\s+TABLE/i,\n /DROP\\s+DATABASE/i,\n /DELETE\\s+FROM/i,\n /TRUNCATE\\s+TABLE/i,\n /railway\\s+volume\\s+delete/i,\n /kubectl\\s+delete/i,\n /terraform\\s+destroy/i,\n];\n\n/**\n * Classify a shell or database command as destructive.\n *\n * Returns the namespaced action type (e.g. `\"destructive.command\"`) when the\n * command matches a known dangerous pattern, or `null` when it appears safe.\n * Use the return value as `action_type` in a {@link requirePermit} call before\n * executing the command:\n *\n * ```ts\n * async function runCommand(command: string, actorId: string) {\n * const actionType = classifyCommand(command);\n * if (actionType) {\n * return requirePermit(\n * { action_type: actionType, actor_id: actorId, resource_id: command,\n * environment: \"production\", context: { command } },\n * () => exec(command),\n * );\n * }\n * return exec(command);\n * }\n * ```\n */\nexport function classifyCommand(command: string): string | null {\n return DESTRUCTIVE_PATTERNS.some((p) => p.test(command))\n ? \"destructive.command\"\n : null;\n}\n","/**\n * `atlasent.withPermit(...)` — the lexically-scoped form of\n * {@link protect}. TypeScript mirror of the Python SDK's\n * ``atlasent.with_permit(...)``.\n *\n * Same execution-boundary contract as {@link protect}: evaluate +\n * verifyPermit run end-to-end before the executor is invoked, and the\n * executor cannot run unless a verified {@link Permit} was returned.\n * The difference is purely lexical — `withPermit` binds the execution\n * to the permit's lifetime via a callback, so the call site reads as\n * \"execute this body under a permit\" rather than \"fetch a permit and\n * run code under it manually.\"\n *\n * ```ts\n * import atlasent from \"@atlasent/sdk\";\n *\n * const ok = await atlasent.withPermit(\n * {\n * agent: \"deploy-bot\",\n * action: \"production.deploy\",\n * context: { commit, approver },\n * },\n * async (permit) => {\n * const result = await runDeploy(commit);\n * return { ok: true, permitId: permit.permitId, result };\n * },\n * );\n * ```\n *\n * Pick the form that fits the call site:\n *\n * - {@link protect} when the caller wants the verified permit as a\n * value (e.g. to pass it across a process boundary, persist it\n * alongside their own record, or interleave it with non-trivial\n * control flow).\n * - {@link withPermit} when the action body is a single lexical scope\n * and \"no permit, no execution\" is the only thing the call site\n * needs to express.\n *\n * Both surfaces use the same underlying primitive and produce the\n * same audit-chain entry.\n */\n\nimport { protect, type Permit, type ProtectRequest } from \"./protect.js\";\n\n/**\n * Authorize a request end-to-end and invoke `fn` only on a verified\n * permit.\n *\n * @param request Same shape as {@link ProtectRequest}.\n * @param fn Invoked with the verified {@link Permit}. Its return\n * value (awaited if it is a promise) is propagated to the caller.\n *\n * @returns Whatever `fn` returns.\n *\n * @throws {AtlaSentDeniedError} Policy denied, hold/escalate, or\n * permit failed verification. `fn` is never invoked.\n * @throws {AtlaSentError} Transport, timeout, auth, rate-limit, or\n * server error. `fn` is never invoked.\n *\n * Errors thrown inside `fn` propagate untouched — the permit is\n * already consumed by the verify step in v1, so there is no\n * compensating revoke.\n */\nexport async function withPermit<T>(\n request: ProtectRequest,\n fn: (permit: Permit) => Promise<T> | T,\n): Promise<T> {\n const permit = await protect(request);\n return await fn(permit);\n}\n","/**\n * Approval/Override Runtime — fail-closed bridge between policy `hold`/`escalate`\n * outcomes and human approval.\n *\n * `protectOrEscalate()` — like `protect()` but handles hold/escalate by:\n * 1. Creating an HITL escalation via POST /v1/hitl\n * 2. Polling until approved, rejected, or timed out\n * 3. Returning an `ApprovalPermit` on approval; throwing on rejection/timeout\n *\n * `createEscalation()` — create an HITL escalation request (lower-level)\n * `waitForEscalationApproval()` — poll until the escalation resolves\n * `requestOverride()` — request a post-hoc override for a denied evaluation\n * `configureApprovalRuntime()` — set API key / base URL once\n */\n\nimport { AtlaSentDeniedError, AtlaSentError } from \"./errors.js\";\nimport type {\n HitlCreateRequest,\n HitlEscalation,\n HitlFallbackDecision,\n HitlQuorumTier,\n} from \"./hitl.js\";\nimport type { CreateOverrideRequest, OverrideV1 } from \"./overrides.js\";\nimport { protect, type Permit, type ProtectRequest } from \"./protect.js\";\n\n// ── Module-level configuration singleton ────────────────────────────────────\n\nexport interface ApprovalRuntimeConfig {\n apiKey?: string;\n baseUrl?: string;\n /** Per-request HTTP timeout in ms. Default 30_000. */\n timeoutMs?: number;\n}\n\nlet _runtimeConfig: ApprovalRuntimeConfig = {};\n\n/**\n * Configure the Approval Runtime singleton. Optional — if `ATLASENT_API_KEY` is\n * set in the environment, the runtime works without configuration. Calling this\n * again merges into the existing config.\n */\nexport function configureApprovalRuntime(config: ApprovalRuntimeConfig): void {\n _runtimeConfig = { ..._runtimeConfig, ...config };\n}\n\nfunction resolveConfig(overrides?: { apiKey?: string; baseUrl?: string }): {\n apiKey: string;\n baseUrl: string;\n requestTimeoutMs: number;\n} {\n const apiKey =\n overrides?.apiKey ??\n _runtimeConfig.apiKey ??\n (typeof process !== \"undefined\" && process.env\n ? process.env[\"ATLASENT_API_KEY\"]\n : undefined);\n\n if (!apiKey) {\n throw new AtlaSentError(\n \"ApprovalRuntime: no API key configured. Set ATLASENT_API_KEY or call configureApprovalRuntime({ apiKey }).\",\n { code: \"invalid_api_key\" },\n );\n }\n\n return {\n apiKey,\n baseUrl:\n overrides?.baseUrl ??\n _runtimeConfig.baseUrl ??\n \"https://api.atlasent.io\",\n requestTimeoutMs: _runtimeConfig.timeoutMs ?? 30_000,\n };\n}\n\n// ── Thin HTTP helpers (avoids importing the full AtlaSentClient) ─────────────\n\ninterface ResolvedConfig {\n apiKey: string;\n baseUrl: string;\n requestTimeoutMs: number;\n}\n\nasync function apiPost<T>(\n path: string,\n body: unknown,\n cfg: ResolvedConfig,\n): Promise<T> {\n const url = `${cfg.baseUrl}${path}`;\n let resp: Response;\n try {\n resp = await fetch(url, {\n method: \"POST\",\n headers: {\n Accept: \"application/json\",\n Authorization: `Bearer ${cfg.apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(cfg.requestTimeoutMs),\n });\n } catch (err) {\n throw new AtlaSentError(\n `ApprovalRuntime: network error calling ${path}`,\n { code: \"network\", cause: err },\n );\n }\n\n if (!resp.ok) {\n const text = await resp.text().catch(() => \"\");\n const code =\n resp.status === 401\n ? \"invalid_api_key\"\n : resp.status === 403\n ? \"forbidden\"\n : resp.status === 429\n ? \"rate_limited\"\n : \"server_error\";\n throw new AtlaSentError(\n `ApprovalRuntime: API error ${resp.status} at ${path}: ${text.slice(0, 200)}`,\n { code, status: resp.status },\n );\n }\n return resp.json() as Promise<T>;\n}\n\nasync function apiGet<T>(path: string, cfg: ResolvedConfig): Promise<T> {\n const url = `${cfg.baseUrl}${path}`;\n let resp: Response;\n try {\n resp = await fetch(url, {\n method: \"GET\",\n headers: {\n Accept: \"application/json\",\n Authorization: `Bearer ${cfg.apiKey}`,\n },\n signal: AbortSignal.timeout(cfg.requestTimeoutMs),\n });\n } catch (err) {\n throw new AtlaSentError(\n `ApprovalRuntime: network error calling ${path}`,\n { code: \"network\", cause: err },\n );\n }\n\n if (!resp.ok) {\n const text = await resp.text().catch(() => \"\");\n const code =\n resp.status === 401\n ? \"invalid_api_key\"\n : resp.status === 403\n ? \"forbidden\"\n : resp.status === 429\n ? \"rate_limited\"\n : \"server_error\";\n throw new AtlaSentError(\n `ApprovalRuntime: API error ${resp.status} at ${path}: ${text.slice(0, 200)}`,\n { code, status: resp.status },\n );\n }\n return resp.json() as Promise<T>;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// ── Core types ────────────────────────────────────────────────────────────────\n\n/** Opaque handle returned when an escalation is created. */\nexport interface EscalationHandle {\n readonly escalationId: string;\n readonly createdAt: string;\n readonly timeoutAt: string | null;\n readonly assignedToRole: string | null;\n}\n\n/** Terminal resolution status of an escalation. */\nexport type ApprovalStatus = \"approved\" | \"rejected\" | \"timed_out\";\n\n/** Full outcome returned when an escalation resolves. */\nexport interface EscalationOutcome {\n readonly status: ApprovalStatus;\n readonly escalation: HitlEscalation;\n readonly resolvedBy: string | null;\n readonly resolutionNote: string | null;\n readonly resolvedAt: string | null;\n}\n\n/**\n * Thrown by `protectOrEscalate` / `waitForEscalationApproval` when the\n * human reviewer rejects the escalation.\n */\nexport class EscalationDeniedError extends Error {\n override readonly name = \"EscalationDeniedError\" as const;\n readonly escalationId: string;\n readonly outcome: EscalationOutcome;\n\n constructor(outcome: EscalationOutcome) {\n super(\n `Escalation ${outcome.escalation.id} was rejected` +\n (outcome.resolutionNote ? `: ${outcome.resolutionNote}` : \"\"),\n );\n this.escalationId = outcome.escalation.id;\n this.outcome = outcome;\n }\n}\n\n/**\n * Thrown by `protectOrEscalate` / `waitForEscalationApproval` when the\n * client-side wait window expires before the escalation resolves.\n */\nexport class EscalationTimeoutError extends Error {\n override readonly name = \"EscalationTimeoutError\" as const;\n readonly escalationId: string;\n readonly outcome: EscalationOutcome;\n\n constructor(outcome: EscalationOutcome) {\n super(\n `Escalation ${outcome.escalation.id} timed out waiting for approval`,\n );\n this.escalationId = outcome.escalation.id;\n this.outcome = outcome;\n }\n}\n\n// ── createEscalation ──────────────────────────────────────────────────────────\n\n/**\n * Options for creating an HITL escalation. Extends `HitlCreateRequest` with\n * API-key and base-URL overrides for per-call credential injection.\n */\nexport interface CreateEscalationOptions extends Partial<HitlCreateRequest> {\n apiKey?: string;\n baseUrl?: string;\n}\n\n/**\n * Create an HITL escalation via POST /v1/hitl.\n *\n * The escalation is placed in `pending` status; a reviewer must approve or\n * reject it before the original action can proceed. Use\n * `waitForEscalationApproval()` to poll until the escalation resolves.\n */\nexport async function createEscalation(\n opts: CreateEscalationOptions,\n): Promise<EscalationHandle> {\n const { apiKey, baseUrl, ...hitlBody } = opts;\n const cfg = resolveConfig({\n ...(apiKey !== undefined ? { apiKey } : {}),\n ...(baseUrl !== undefined ? { baseUrl } : {}),\n });\n\n const body: HitlCreateRequest = {\n agent_id: hitlBody.agent_id ?? \"unknown\",\n escalation_reason:\n hitlBody.escalation_reason ?? \"Policy hold — awaiting human approval\",\n ...hitlBody,\n };\n\n const escalation = await apiPost<HitlEscalation>(\"/v1/hitl\", body, cfg);\n return {\n escalationId: escalation.id,\n createdAt: escalation.created_at,\n timeoutAt: escalation.timeout_at ?? null,\n assignedToRole: escalation.assigned_to_role ?? null,\n };\n}\n\n// ── waitForEscalationApproval ─────────────────────────────────────────────────\n\nexport interface WaitForApprovalOptions {\n escalationId: string;\n /** Max milliseconds to wait for a human to respond. Default 600_000 (10 min). */\n waitMs?: number;\n /** How often to poll the API. Default 5000ms. Minimum 1000ms. */\n pollIntervalMs?: number;\n apiKey?: string;\n baseUrl?: string;\n}\n\n/**\n * Poll GET /v1/escalations/:id until the escalation reaches a terminal status\n * (`approved`, `auto_approved`, `rejected`, or `timed_out`).\n *\n * Returns the resolved outcome regardless of approval/rejection — the caller\n * decides whether to throw. Use `protectOrEscalate()` for the opinionated flow.\n */\nexport async function waitForEscalationApproval(\n opts: WaitForApprovalOptions,\n): Promise<EscalationOutcome> {\n const cfg = resolveConfig({\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n const waitMs = opts.waitMs ?? 600_000;\n const pollIntervalMs = Math.max(opts.pollIntervalMs ?? 5_000, 1_000);\n const deadline = Date.now() + waitMs;\n\n const toOutcome = (escalation: HitlEscalation): EscalationOutcome | null => {\n const terminal =\n escalation.status === \"approved\" ||\n escalation.status === \"rejected\" ||\n escalation.status === \"auto_approved\" ||\n escalation.status === \"timed_out\";\n\n if (!terminal) return null;\n\n const status: ApprovalStatus =\n escalation.status === \"approved\" || escalation.status === \"auto_approved\"\n ? \"approved\"\n : escalation.status === \"timed_out\"\n ? \"timed_out\"\n : \"rejected\";\n\n return {\n status,\n escalation,\n resolvedBy: escalation.resolved_by ?? null,\n resolutionNote: escalation.resolution_note ?? null,\n resolvedAt: escalation.resolved_at ?? null,\n };\n };\n\n while (Date.now() < deadline) {\n const escalation = await apiGet<HitlEscalation>(\n `/v1/escalations/${opts.escalationId}`,\n cfg,\n );\n const outcome = toOutcome(escalation);\n if (outcome) return outcome;\n\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n await sleep(Math.min(pollIntervalMs, remaining));\n }\n\n // Final fetch at deadline\n const escalation = await apiGet<HitlEscalation>(\n `/v1/escalations/${opts.escalationId}`,\n cfg,\n );\n const outcome = toOutcome(escalation);\n if (outcome) return outcome;\n\n return {\n status: \"timed_out\",\n escalation,\n resolvedBy: null,\n resolutionNote: \"Client-side wait timeout elapsed\",\n resolvedAt: null,\n };\n}\n\n// ── protectOrEscalate ─────────────────────────────────────────────────────────\n\n/**\n * A verified Permit granted via human approval of an HITL escalation.\n * Extends {@link Permit} with escalation provenance fields.\n *\n * `approvalBasis: \"direct_policy\"` — action was allowed directly by policy;\n * no escalation was created.\n *\n * `approvalBasis: \"human_approval\"` — the policy returned `hold`/`escalate`;\n * a human reviewer approved the escalation.\n *\n * Guards and enforcement adapters should treat both as equivalent authorization\n * proof; auditors can distinguish them via `escalationId`.\n */\nexport interface ApprovalPermit extends Permit {\n /**\n * The HITL escalation ID that authorized this action. Empty string when\n * the action was directly allowed by policy (no escalation needed).\n */\n readonly escalationId: string;\n /** Identity of the reviewer who approved, or `null` for `auto_approved`. */\n readonly resolvedBy: string | null;\n readonly resolutionNote: string | null;\n readonly resolvedAt: string;\n readonly approvalBasis: \"direct_policy\" | \"human_approval\";\n}\n\nexport interface ProtectOrEscalateOptions {\n /** Agent ID recorded on the escalation. Defaults to `request.agent`. */\n agentId?: string;\n /** Human-readable reason surfaced in the reviewer's queue. */\n escalationReason?: string;\n /** The proposed action payload shown to reviewers. Defaults to `request.context`. */\n proposedAction?: Record<string, unknown>;\n riskScore?: number;\n assignedToRole?: string;\n quorumRequired?: HitlQuorumTier;\n fallbackDecision?: HitlFallbackDecision;\n /** ISO-8601 — when the escalation should auto-resolve per server policy. */\n timeoutAt?: string;\n metadata?: Record<string, unknown>;\n /** Max ms to wait for a human decision. Default 600_000 (10 min). */\n waitMs?: number;\n /** How often to poll. Default 5000ms. */\n pollIntervalMs?: number;\n apiKey?: string;\n baseUrl?: string;\n /** Called with the EscalationHandle immediately after it is created. */\n onEscalationCreated?: (handle: EscalationHandle) => void;\n}\n\n/**\n * Authorize an action end-to-end, automatically escalating to human review\n * when the policy returns `hold` or `escalate`.\n *\n * **Directly allowed** → returns `ApprovalPermit` with\n * `approvalBasis: \"direct_policy\"` (same semantics as `protect()`).\n *\n * **Hold / escalate** → creates an HITL escalation, polls for a human\n * decision, and returns `ApprovalPermit` with\n * `approvalBasis: \"human_approval\"` on approval.\n *\n * **Throws**:\n * - {@link EscalationDeniedError} — reviewer rejected the escalation\n * - {@link EscalationTimeoutError} — wait window elapsed without a decision\n * - {@link AtlaSentDeniedError} — hard deny (not hold/escalate); fail-closed\n * - {@link AtlaSentError} — transport / auth / server failure; fail-closed\n */\nexport async function protectOrEscalate(\n request: ProtectRequest,\n opts: ProtectOrEscalateOptions = {},\n): Promise<ApprovalPermit> {\n try {\n const permit = await protect(request);\n return {\n ...permit,\n escalationId: \"\",\n resolvedBy: null,\n resolutionNote: null,\n resolvedAt: permit.timestamp,\n approvalBasis: \"direct_policy\",\n };\n } catch (err) {\n if (\n !(err instanceof AtlaSentDeniedError) ||\n (err.decision !== \"hold\" && err.decision !== \"escalate\")\n ) {\n throw err;\n }\n }\n\n // Create HITL escalation\n const proposedAction =\n opts.proposedAction ?? (request.context as Record<string, unknown> | undefined);\n const handle = await createEscalation({\n agent_id: opts.agentId ?? request.agent,\n escalation_reason:\n opts.escalationReason ??\n `Policy hold for \"${request.action}\" by \"${request.agent}\"`,\n ...(proposedAction !== undefined ? { proposed_action: proposedAction } : {}),\n ...(opts.riskScore !== undefined ? { risk_score: opts.riskScore } : {}),\n ...(opts.assignedToRole !== undefined ? { assigned_to_role: opts.assignedToRole } : {}),\n ...(opts.quorumRequired !== undefined ? { quorum_required: opts.quorumRequired } : {}),\n ...(opts.fallbackDecision !== undefined ? { fallback_decision: opts.fallbackDecision } : {}),\n ...(opts.timeoutAt !== undefined ? { timeout_at: opts.timeoutAt } : {}),\n ...(opts.metadata !== undefined ? { metadata: opts.metadata } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n\n opts.onEscalationCreated?.(handle);\n\n // Wait for human decision\n const outcome = await waitForEscalationApproval({\n escalationId: handle.escalationId,\n ...(opts.waitMs !== undefined ? { waitMs: opts.waitMs } : {}),\n ...(opts.pollIntervalMs !== undefined ? { pollIntervalMs: opts.pollIntervalMs } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n\n if (outcome.status === \"rejected\") throw new EscalationDeniedError(outcome);\n if (outcome.status === \"timed_out\") throw new EscalationTimeoutError(outcome);\n\n // Approved — return ApprovalPermit\n return {\n permitId: `escl_${handle.escalationId}`,\n permitHash: \"\",\n auditHash: outcome.escalation.id,\n reason: outcome.resolutionNote ?? \"Approved by human reviewer\",\n timestamp: outcome.resolvedAt ?? new Date().toISOString(),\n permitExpiresAt: null,\n escalationId: handle.escalationId,\n resolvedBy: outcome.resolvedBy,\n resolutionNote: outcome.resolutionNote,\n resolvedAt: outcome.resolvedAt ?? new Date().toISOString(),\n approvalBasis: \"human_approval\",\n };\n}\n\n// ── requestOverride ────────────────────────────────────────────────────────────\n\nexport interface RequestOverrideOptions {\n /** Human-readable justification. Required; max 2000 characters. */\n reason: string;\n /** The evaluation ID that was denied and should be overridden. */\n evaluationId: string;\n /** How long this override is valid, in seconds. Max 604800 (7 days). */\n ttlSeconds?: number;\n /** Arbitrary metadata to attach (e.g. liability attribution context). */\n metadata?: Record<string, unknown>;\n apiKey?: string;\n baseUrl?: string;\n}\n\n/**\n * Request a post-hoc override for a denied evaluation via POST /v1/overrides.\n *\n * The override starts in `pending` status and takes effect only after an\n * authorized actor approves it. Subsequent evaluations for the same action\n * will return `allow` while the override is `approved` and within its TTL.\n *\n * Attach `metadata.requested_by` for liability attribution.\n */\nexport async function requestOverride(\n opts: RequestOverrideOptions,\n): Promise<OverrideV1> {\n const cfg = resolveConfig({\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n\n const body: CreateOverrideRequest = {\n reason: opts.reason,\n evaluationId: opts.evaluationId,\n ...(opts.ttlSeconds !== undefined && { ttlSeconds: opts.ttlSeconds }),\n ...(opts.metadata !== undefined && { metadata: opts.metadata }),\n };\n\n return apiPost<OverrideV1>(\"/v1/overrides\", body, cfg);\n}\n","/**\n * Context Layer — typed, validated, redaction-aware context for AtlaSent\n * evaluations.\n *\n * The current `protect()` / `evaluate()` API accepts\n * `context?: Record<string, unknown>` — a black box the policy engine\n * treats as an opaque blob. This module provides:\n *\n * 1. **Typed sub-schemas** — `ActorContext`, `ResourceContext`,\n * `EnvironmentContext`, `ActionMetaContext`, `HistoricalContext`, and\n * `ActionContext` (the union of all five).\n *\n * 2. **`buildActionContext()`** — a structured constructor that normalises\n * flat shorthands and validates at build time.\n *\n * 3. **`validateActionContext()`** — non-throwing validation that returns\n * typed `ContextValidationError[]` and `ContextValidationWarning[]`.\n *\n * 4. **`redactContext()`** — strips / masks sensitive fields before\n * logging or storing in receipts / evidence bundles.\n *\n * 5. **`flattenActionContext()`** — converts a typed `ActionContext` to the\n * flat `Record<string, unknown>` that `protect()` / `evaluate()` accept.\n *\n * ### Usage\n *\n * ```ts\n * import atlasent, { buildActionContext, redactContext } from \"@atlasent/sdk\";\n *\n * const ctx = buildActionContext({\n * actor: { id: \"user:alice\", type: \"human\", roles: [\"deploy_engineer\"] },\n * environment: { name: \"production\", region: \"us-east-1\" },\n * resource: { type: \"service\", id: \"api-gateway\", sensitivity: \"restricted\" },\n * org_id: \"org_acme\",\n * environment_id: \"env_prod_us_east\",\n * });\n *\n * const permit = await atlasent.protect({\n * agent: \"deploy-bot\",\n * action: \"production.deploy\",\n * context: flattenActionContext(ctx),\n * });\n *\n * // Store the redacted context alongside the permit — no PII in evidence.\n * const safe = redactContext(ctx);\n * await db.permits.create({ permitId: permit.permitId, context: safe });\n * ```\n */\n\n// ── Typed sub-schemas ──────────────────────────────────────────────────────────────\n\n/**\n * Identity of the actor requesting the action.\n *\n * `id` is the only required field; all others are policy-engine hints.\n * Omitting optional fields may cause deny on policies that gate on role\n * membership, trust level, or session binding.\n */\nexport interface ActorContext {\n /** Stable, opaque actor identifier (e.g. `\"user:alice\"`, `\"agent:deploy-bot\"`). */\n id: string;\n /** Human-readable label for audit trails and reviewer UIs. */\n label?: string;\n /** Discriminates human vs. AI agent vs. service account. */\n type?: \"human\" | \"agent\" | \"service_account\" | \"system\";\n /** Roles the actor holds at evaluation time. */\n roles?: string[];\n /** Trust tier. Policy rules can gate on this value. */\n trust_level?: \"high\" | \"medium\" | \"low\" | \"untrusted\" | string;\n /** Actor email — required for human-approval escalation UIs. */\n email?: string;\n /** Observed client IP — used in geo-restriction and rate-limit rules. */\n ip?: string;\n /** Session or OAuth token ID for replay-detection rules. */\n session_id?: string;\n /**\n * Organization this actor belongs to. Populated from\n * `BuildActionContextInput.org_id` when the actor has no explicit org_id.\n * Used by cross-tenant policy checks and usage metering.\n */\n org_id?: string;\n}\n\n/**\n * The resource the action targets.\n *\n * `type` is a stable string like `\"database.table\"`, `\"repository\"`,\n * or `\"payment\"`. `sensitivity` drives redaction rules in evidence\n * bundles — `\"restricted\"` fields are masked even in signed receipts.\n */\nexport interface ResourceContext {\n /** Stable resource type slug (e.g. `\"database.table\"`, `\"service\"`, `\"payment\"`). */\n type?: string;\n /** Opaque resource identifier (e.g. table name, repo name, payment ID). */\n id?: string;\n /** Human-readable name for reviewer UIs. */\n name?: string;\n /** Data-sensitivity classification — drives receipt redaction. */\n sensitivity?: \"public\" | \"internal\" | \"confidential\" | \"restricted\";\n /** Owner org or tenant of the resource. */\n owner?: string;\n /** Cloud or datacenter region where the resource lives. */\n region?: string;\n}\n\n/**\n * Deployment environment and infrastructure context.\n *\n * `name` is the field protect() reads to set the `environment` field\n * on the verify-permit request. Set it explicitly in runtime contexts\n * so verification is bound to the executing environment.\n */\nexport interface EnvironmentContext {\n /** Deployment tier (for example, `\"production\"` or `\"staging\"`). */\n name?: \"production\" | \"staging\" | \"development\" | \"test\" | string;\n /** Cloud or datacenter region (e.g. `\"us-east-1\"`, `\"eu-west-1\"`). */\n region?: string;\n /** CI/CD pipeline name (e.g. `\"github_actions\"`, `\"jenkins\"`). */\n pipeline?: string;\n /** Git SHA, image tag, or artifact version being deployed. */\n version?: string;\n}\n\n/**\n * Action-specific metadata that shapes policy decisions.\n *\n * `risk_level` and `reversibility` are the two fields most commonly\n * referenced by policy rules. Financial policies additionally gate on\n * `estimated_amount` and `currency`.\n */\nexport interface ActionMetaContext {\n /** Caller-assessed risk level of this specific invocation. */\n risk_level?: \"critical\" | \"high\" | \"medium\" | \"low\";\n /** Whether the action can be undone after execution. */\n reversibility?: \"reversible\" | \"irreversible\" | \"partial\";\n /** Free-text description shown to human reviewers in the HITL UI. */\n description?: string;\n /** Estimated monetary amount for financial actions. */\n estimated_amount?: number;\n /** ISO 4217 currency code (e.g. `\"USD\"`, `\"EUR\"`). */\n currency?: string;\n}\n\n/**\n * Historical and behavioral signals about the actor.\n *\n * These are caller-computed signals from the caller's own systems —\n * AtlaSent does not maintain the source-of-truth; it only evaluates\n * policy against the values provided here.\n */\nexport interface HistoricalContext {\n /** Number of times this actor performed this action in the past 24h. */\n recent_action_count?: number;\n /** ISO-8601 timestamp of the actor's most recent action of this type. */\n last_action_at?: string;\n /** True when the actor has unresolved policy violations on record. */\n has_violations?: boolean;\n /** Arbitrary caller-defined risk signals from upstream systems. */\n risk_signals?: Record<string, unknown>;\n}\n\n/**\n * The canonical typed context for AtlaSent evaluations.\n *\n * All sub-schemas are optional at the TypeScript level; policy rules\n * determine which fields are effectively required. Missing fields that\n * a policy expects will typically result in a `deny` decision.\n *\n * Flat shorthands (`resource_type`, `resource_id`, `environment_name`)\n * are supported for backward compatibility with existing\n * `Record<string, unknown>` call sites. `buildActionContext()` merges\n * them into the nested sub-schemas automatically.\n *\n * The `[key: string]: unknown` index signature allows arbitrary\n * custom fields to pass through to the policy engine unchanged.\n */\nexport interface ActionContext {\n actor?: ActorContext;\n resource?: ResourceContext;\n environment?: EnvironmentContext;\n action_meta?: ActionMetaContext;\n history?: HistoricalContext;\n\n /**\n * Organization ID — scopes the evaluation to this org's policies and\n * usage meters. Propagated from `BuildActionContextInput.org_id` and\n * also set on `actor.org_id` when the actor has no explicit org.\n */\n org_id?: string;\n\n /**\n * ID of the registered `org_environments` row.\n * Future billing dimension: usage will be metered per environment tier.\n * Optional and additive — existing call sites that pass `environment.name`\n * continue to work without providing this field.\n */\n environment_id?: string;\n\n // ── Flat shorthands for backward compat ───────────────────────────\n // These alias the most common nested fields so existing Record<string, unknown>\n // usage continues to work without refactoring. Both the flat and nested\n // forms are sent in flattenActionContext() output so policy rules written\n // against either form continue to work.\n\n /** Alias for `environment.name`. Merged into `environment` by buildActionContext. */\n environment_name?: string;\n /** Alias for `resource.type`. Merged into `resource` by buildActionContext. */\n resource_type?: string;\n /** Alias for `resource.id`. Merged into `resource` by buildActionContext. */\n resource_id?: string;\n\n [key: string]: unknown;\n}\n\n// ── buildActionContext ────────────────────────────────────────────────────────────\n\n/** Input for `buildActionContext()`. Mirrors `ActionContext` with `actor` required. */\nexport interface BuildActionContextInput {\n actor: ActorContext;\n resource?: ResourceContext;\n environment?: EnvironmentContext | string;\n action_meta?: ActionMetaContext;\n history?: HistoricalContext;\n /**\n * Organization ID — scopes the evaluation to this org's policies and\n * usage meters. Propagated to `actor.org_id` when the actor has no\n * explicit org_id, and also set as a top-level `org_id` on the context\n * so policy rules can reference it at `context.org_id`.\n */\n org_id?: string;\n /**\n * ID of the registered `org_environments` row (future billing dimension).\n * Passed through to the flat context as `environment_id`. Optional —\n * callers that pass only `environment.name` continue to work unchanged.\n */\n environment_id?: string;\n /** Arbitrary additional fields to pass through to the policy engine. */\n extra?: Record<string, unknown>;\n}\n\n/**\n * Construct a normalized `ActionContext`.\n *\n * - Accepts `environment` as a string shorthand for `{ name: environment }`.\n * - Populates flat shorthands (`resource_type`, `resource_id`,\n * `environment_name`) from the nested sub-schemas so both the nested and\n * flat forms are present in the output.\n * - Propagates `org_id` to `actor.org_id` when the actor has no explicit org.\n * - Propagates `environment_id` as a top-level context field for billing.\n * - Never throws — validation is a separate step via `validateActionContext()`.\n *\n * ```ts\n * const ctx = buildActionContext({\n * actor: { id: \"agent:deploy-bot\", type: \"agent\" },\n * environment: \"production\",\n * resource: { type: \"service\", id: \"checkout-api\" },\n * org_id: \"org_acme\",\n * environment_id: \"env_prod_us_east\",\n * });\n * ```\n */\nexport function buildActionContext(\n input: BuildActionContextInput,\n): ActionContext {\n const env: EnvironmentContext | undefined =\n typeof input.environment === \"string\"\n ? { name: input.environment }\n : input.environment;\n\n // Propagate org_id to actor when actor has no explicit org_id.\n const actor: ActorContext =\n input.org_id !== undefined && !input.actor.org_id\n ? { ...input.actor, org_id: input.org_id }\n : input.actor;\n\n const ctx: ActionContext = {\n actor,\n ...(input.resource !== undefined && { resource: input.resource }),\n ...(env !== undefined && { environment: env }),\n ...(input.action_meta !== undefined && { action_meta: input.action_meta }),\n ...(input.history !== undefined && { history: input.history }),\n ...(input.org_id !== undefined && { org_id: input.org_id }),\n ...(input.environment_id !== undefined && { environment_id: input.environment_id }),\n ...(input.extra ?? {}),\n };\n\n // Populate flat shorthands from nested sub-schemas\n if (env?.name !== undefined) ctx.environment_name = env.name;\n if (input.resource?.type !== undefined)\n ctx.resource_type = input.resource.type;\n if (input.resource?.id !== undefined) ctx.resource_id = input.resource.id;\n\n return ctx;\n}\n\n// ── validateActionContext ────────────────────────────────────────────────────────\n\n/** A field-level error from `validateActionContext()`. */\nexport interface ContextValidationError {\n /** Dot-delimited field path (e.g. `\"actor.id\"`, `\"action_meta.currency\"`). */\n field: string;\n /** Machine-readable error code. */\n code:\n | \"required\"\n | \"invalid_type\"\n | \"invalid_value\"\n | \"cross_field\"\n | \"sensitive_field\";\n /** Human-readable explanation. */\n message: string;\n}\n\n/** A non-blocking advisory from `validateActionContext()`. */\nexport interface ContextValidationWarning {\n field: string;\n code: \"recommended\" | \"deprecated\" | \"performance\";\n message: string;\n}\n\n/** Result of `validateActionContext()`. */\nexport interface ContextValidationResult {\n valid: boolean;\n errors: ContextValidationError[];\n warnings: ContextValidationWarning[];\n}\n\n/** Options for `validateActionContext()`. */\nexport interface ValidateContextOptions {\n /**\n * Extra fields to treat as required. Dot-delimited paths are supported\n * (e.g. `[\"actor.roles\", \"resource.id\"]`).\n */\n requiredFields?: string[];\n /**\n * When true, skip the built-in cross-field checks (e.g.\n * estimated_amount → currency). Useful for partial contexts.\n */\n skipCrossFieldChecks?: boolean;\n}\n\nfunction getNestedValue(\n obj: Record<string, unknown>,\n path: string,\n): unknown {\n return path.split(\".\").reduce<unknown>((cur, key) => {\n if (cur !== null && typeof cur === \"object\") {\n return (cur as Record<string, unknown>)[key];\n }\n return undefined;\n }, obj);\n}\n\n/**\n * Validate an `ActionContext` without throwing.\n *\n * Returns a `ContextValidationResult` with `valid: false` and a list of\n * typed `errors` / `warnings` when the context is malformed or missing\n * fields. Does not throw — the caller decides what to do with errors.\n *\n * Built-in checks:\n * - `actor.id` is required when `actor` is present\n * - `environment.name` is recommended (warns if absent)\n * - `action_meta.currency` is required when `action_meta.estimated_amount > 0`\n * - ISO 4217 format check for `action_meta.currency`\n * - `history.last_action_at` must be a valid ISO-8601 string\n * - `resource.sensitivity` must be a known value when present\n *\n * ```ts\n * const { valid, errors, warnings } = validateActionContext(ctx, {\n * requiredFields: [\"resource.id\", \"actor.roles\"],\n * });\n * if (!valid) logger.warn(\"Context validation failed\", { errors });\n * ```\n */\nexport function validateActionContext(\n ctx: ActionContext,\n opts: ValidateContextOptions = {},\n): ContextValidationResult {\n const errors: ContextValidationError[] = [];\n const warnings: ContextValidationWarning[] = [];\n\n const ctxObj = ctx as Record<string, unknown>;\n\n // ── actor.id required when actor is provided ────────────────────────\n if (ctx.actor !== undefined) {\n if (!ctx.actor.id || typeof ctx.actor.id !== \"string\") {\n errors.push({\n field: \"actor.id\",\n code: \"required\",\n message: \"actor.id is required when actor is provided\",\n });\n }\n }\n\n // ── environment.name recommended ────────────────────────────────────\n const hasEnvName =\n ctx.environment?.name !== undefined ||\n ctx.environment_name !== undefined;\n if (!hasEnvName) {\n warnings.push({\n field: \"environment.name\",\n code: \"recommended\",\n message:\n \"environment.name is not set; provide it so verify-permit can bind to the execution environment\",\n });\n }\n\n // ── cross-field: estimated_amount requires currency ─────────────────\n if (!opts.skipCrossFieldChecks) {\n const amount = ctx.action_meta?.estimated_amount;\n if (typeof amount === \"number\" && amount > 0) {\n if (!ctx.action_meta?.currency) {\n errors.push({\n field: \"action_meta.currency\",\n code: \"cross_field\",\n message:\n \"action_meta.currency is required when action_meta.estimated_amount > 0\",\n });\n } else if (!/^[A-Z]{3}$/.test(ctx.action_meta.currency)) {\n errors.push({\n field: \"action_meta.currency\",\n code: \"invalid_value\",\n message:\n `action_meta.currency '${ctx.action_meta.currency}' is not a valid ISO 4217 code (expected 3 uppercase letters)`,\n });\n }\n }\n }\n\n // ── history.last_action_at must be ISO-8601 ─────────────────────────\n if (ctx.history?.last_action_at !== undefined) {\n const ts = new Date(ctx.history.last_action_at);\n if (isNaN(ts.getTime())) {\n errors.push({\n field: \"history.last_action_at\",\n code: \"invalid_type\",\n message: `history.last_action_at '${ctx.history.last_action_at}' is not a valid ISO-8601 timestamp`,\n });\n }\n }\n\n // ── resource.sensitivity must be a known value ──────────────────────\n const knownSensitivities = new Set([\n \"public\",\n \"internal\",\n \"confidential\",\n \"restricted\",\n ]);\n if (\n ctx.resource?.sensitivity !== undefined &&\n !knownSensitivities.has(ctx.resource.sensitivity)\n ) {\n errors.push({\n field: \"resource.sensitivity\",\n code: \"invalid_value\",\n message: `resource.sensitivity '${ctx.resource.sensitivity}' is not one of: public, internal, confidential, restricted`,\n });\n }\n\n // ── caller-specified required fields ────────────────────────────────\n for (const fieldPath of opts.requiredFields ?? []) {\n const value = getNestedValue(ctxObj, fieldPath);\n if (value === undefined || value === null || value === \"\") {\n errors.push({\n field: fieldPath,\n code: \"required\",\n message: `${fieldPath} is required by the caller's validation rules`,\n });\n }\n }\n\n return { valid: errors.length === 0, errors, warnings };\n}\n\n// ── redactContext ────────────────────────────────────────────────────────────────\n\n/** Redaction mode applied to a matched field. */\nexport type RedactionMode = \"remove\" | \"mask\" | \"hash\";\n\n/**\n * A single redaction rule. `field` is matched against every key at\n * every nesting level in the context object.\n *\n * `path` narrows the match to a specific dot-delimited location\n * (e.g. `\"actor.email\"` to only mask email inside the actor sub-object,\n * not top-level email fields).\n */\nexport interface RedactionRule {\n /** Key name or regex applied to every key in the context tree. */\n field: string | RegExp;\n /** What to do with the matched value. */\n mode: RedactionMode;\n /**\n * Optional dot-delimited path constraint. When set, the rule only\n * applies to a key at this exact path (e.g. `\"actor.session_id\"`).\n */\n path?: string;\n}\n\n/**\n * Built-in redaction rules covering OWASP Top 10 sensitive field\n * name patterns. Matched case-insensitively against every key name\n * at every nesting level.\n *\n * Callers can extend this list or pass a custom rule set to\n * `redactContext()`.\n */\nexport const DEFAULT_REDACTION_RULES: readonly RedactionRule[] = [\n {\n field: /password|passwd|passphrase/i,\n mode: \"remove\",\n },\n {\n field: /secret|private_key|client_secret|signing_secret/i,\n mode: \"remove\",\n },\n {\n field: /api_key|apikey|access_key|access_token/i,\n mode: \"remove\",\n },\n {\n field: /\\btoken\\b|auth_token|bearer/i,\n mode: \"mask\",\n },\n {\n field: /\\bssn\\b|social_security|tax_id|\\bsin\\b/i,\n mode: \"remove\",\n },\n {\n field: /credit_card|card_number|pan\\b|cvv|cvc|expiry/i,\n mode: \"remove\",\n },\n {\n field: /\\bemail\\b/i,\n mode: \"mask\",\n },\n {\n field: /phone|mobile|cell\\b/i,\n mode: \"mask\",\n },\n {\n field: /\\bip\\b|ip_address|remote_addr/i,\n mode: \"mask\",\n },\n {\n field: /dob|date_of_birth|birth_date|birthdate/i,\n mode: \"remove\",\n },\n];\n\nconst MASK_PLACEHOLDER = \"[REDACTED]\";\n\nfunction matchesRule(key: string, rule: RedactionRule): boolean {\n if (typeof rule.field === \"string\") {\n return key.toLowerCase() === rule.field.toLowerCase();\n }\n return rule.field.test(key);\n}\n\nfunction redactValue(\n value: unknown,\n mode: RedactionMode,\n): unknown {\n if (mode === \"remove\") return undefined;\n if (mode === \"mask\") return MASK_PLACEHOLDER;\n // \"hash\" — return a stable placeholder; callers that want actual hashing\n // can post-process the \"[HASHED]\" sentinel.\n return \"[HASHED]\";\n}\n\nfunction redactObject(\n obj: Record<string, unknown>,\n rules: readonly RedactionRule[],\n currentPath: string,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const fieldPath = currentPath ? `${currentPath}.${key}` : key;\n\n // Find the first matching rule (path-constrained rules take priority)\n const matchingRule = rules.find(\n (r) =>\n matchesRule(key, r) && (r.path === undefined || r.path === fieldPath),\n );\n\n if (matchingRule) {\n const redacted = redactValue(value, matchingRule.mode);\n if (redacted !== undefined) result[key] = redacted;\n // If mode === \"remove\", the key is omitted (undefined not assigned)\n } else if (Array.isArray(value)) {\n result[key] = value.map((item) =>\n item !== null && typeof item === \"object\" && !Array.isArray(item)\n ? redactObject(item as Record<string, unknown>, rules, fieldPath)\n : item,\n );\n } else if (value !== null && typeof value === \"object\") {\n result[key] = redactObject(\n value as Record<string, unknown>,\n rules,\n fieldPath,\n );\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/**\n * Return a redacted copy of `ctx` with sensitive fields removed or masked.\n *\n * Uses `DEFAULT_REDACTION_RULES` when `rules` is omitted. Callers can\n * extend or replace the default rules:\n *\n * ```ts\n * import { DEFAULT_REDACTION_RULES, redactContext } from \"@atlasent/sdk\";\n *\n * const safe = redactContext(ctx, [\n * ...DEFAULT_REDACTION_RULES,\n * { field: /internal_id/, mode: \"hash\" },\n * ]);\n * ```\n *\n * Never mutates the input; returns a shallow-to-deep copy.\n */\nexport function redactContext(\n ctx: ActionContext,\n rules: readonly RedactionRule[] = DEFAULT_REDACTION_RULES,\n): ActionContext {\n return redactObject(\n ctx as Record<string, unknown>,\n rules,\n \"\",\n ) as ActionContext;\n}\n\n// ── flattenActionContext ──────────────────────────────────────────────────────────\n\n/**\n * Convert a typed `ActionContext` to the flat `Record<string, unknown>`\n * that `protect()` / `evaluate()` / `verifyPermit()` accept.\n *\n * The output merges:\n * 1. All top-level scalar fields from `ActionContext` (including flat\n * shorthands like `environment_name`, and billing dimensions like\n * `org_id` and `environment_id`).\n * 2. Nested sub-schemas (`actor`, `resource`, `environment`, etc.) preserved\n * as nested objects so policy rules written against either the nested or\n * flat form work correctly.\n *\n * The nested form is always present in the output; the flat shorthands\n * (`resource_type`, `resource_id`, `environment_name`, `environment`) are\n * duplicated at the top level for policy rules that use the flat path.\n *\n * ```ts\n * const permit = await protect({\n * agent: \"deploy-bot\",\n * action: \"production.deploy\",\n * context: flattenActionContext(ctx),\n * });\n * ```\n */\nexport function flattenActionContext(\n ctx: ActionContext,\n): Record<string, unknown> {\n const flat: Record<string, unknown> = {};\n\n // Copy all top-level fields (both structured sub-schemas and extra fields)\n for (const [key, value] of Object.entries(ctx)) {\n flat[key] = value;\n }\n\n // Expose a flat string shorthand for environment name alongside the full\n // nested object. Using a separate key preserves nested fields (region,\n // pipeline, etc.) that were already copied above.\n const envName = ctx.environment?.name ?? ctx.environment_name;\n if (envName !== undefined) {\n flat[\"environment_name\"] = envName;\n }\n\n return flat;\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type DeployEnvironment = \"production\" | \"staging\" | \"development\" | string;\n\nexport interface DeployGateOptions {\n service: string;\n resourceType?: string;\n sha?: string;\n workflow?: string;\n actorId?: string;\n actorLabel?: string;\n environment?: DeployEnvironment;\n description?: string;\n requireApproval?: boolean;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n /** Slack Incoming Webhook URL. When set, an informational message is posted\n * when the gate returns deny or escalate. Best-effort; never throws. */\n notifySlackWebhook?: string;\n}\n\nfunction resolveEnvActor(): string | undefined {\n return (\n process.env[\"GITHUB_ACTOR\"] ??\n process.env[\"GITLAB_USER_LOGIN\"] ??\n process.env[\"CIRCLE_USERNAME\"] ??\n process.env[\"BITBUCKET_STEP_TRIGGERER_UUID\"] ??\n undefined\n );\n}\n\nfunction resolveEnvSha(): string | undefined {\n return (\n process.env[\"GITHUB_SHA\"] ??\n process.env[\"CI_COMMIT_SHA\"] ??\n process.env[\"CIRCLE_SHA1\"] ??\n process.env[\"BITBUCKET_COMMIT\"] ??\n undefined\n );\n}\n\nfunction resolveEnvWorkflow(): string | undefined {\n return (\n process.env[\"GITHUB_WORKFLOW\"] ??\n process.env[\"CI_PIPELINE_NAME\"] ??\n process.env[\"CIRCLE_WORKFLOW_NAME\"] ??\n undefined\n );\n}\n\nexport async function protectDeploy(\n opts: DeployGateOptions,\n): Promise<ApprovalPermit | Permit> {\n const actorId = opts.actorId ?? resolveEnvActor() ?? \"ci-system\";\n const sha = opts.sha ?? resolveEnvSha();\n const workflow = opts.workflow ?? resolveEnvWorkflow();\n const environment = opts.environment ?? \"production\";\n const isProduction = environment === \"production\";\n\n const ctx = buildActionContext({\n actor: {\n id: actorId,\n type: \"service_account\",\n ...(opts.actorLabel !== undefined ? { label: opts.actorLabel } : {}),\n },\n resource: {\n id: opts.service,\n type: opts.resourceType ?? \"service\",\n },\n environment,\n action_meta: {\n risk_level: isProduction ? \"critical\" : \"medium\",\n reversibility: \"partial\",\n ...(opts.description !== undefined\n ? { description: opts.description }\n : sha !== undefined\n ? { description: `Deploy ${sha.slice(0, 8)} to ${environment}` }\n : {}),\n },\n extra: {\n sha,\n workflow,\n },\n });\n\n const request = {\n action: \"production.deploy\",\n agent: actorId,\n context: flattenActionContext(ctx),\n };\n\n const notifyDenied = async (reason: string): Promise<void> => {\n if (!opts.notifySlackWebhook) return;\n try {\n await fetch(opts.notifySlackWebhook, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n text: `:no_entry: AtlaSent Deploy Gate DENIED: ${request.action} (${environment})`,\n blocks: [\n {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: `*:no_entry: AtlaSent Deploy Gate DENIED*\\n*Action:* \\`${request.action}\\`\\n*Service:* ${opts.service}\\n*Environment:* ${environment}\\n*Actor:* ${actorId}\\n*Reason:* ${reason}`,\n },\n },\n ],\n }),\n });\n } catch {\n // notification errors are always swallowed\n }\n };\n\n try {\n if (opts.requireApproval || isProduction) {\n return await protectOrEscalate(request, {\n escalationReason: `Production deployment of ${opts.service} requires human approval`,\n assignedToRole: opts.assignedToRole ?? \"release-manager\",\n waitMs: opts.waitMs ?? 30 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n }\n return await protect(request);\n } catch (err: unknown) {\n const reason =\n err instanceof Error ? err.message : \"authorization denied\";\n await notifyDenied(reason);\n throw err;\n }\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\n// data export actions use protectDataExport() from verticals/dataExport.ts\nexport type CloseActionType = \"period.close\" | \"period.reopen\" | \"reconciliation.lock\" | \"reconciliation.certify\";\n\nexport interface CloseGovernanceOptions {\n action: CloseActionType;\n periodLabel: string;\n closedBy: string;\n entityId: string;\n entityName?: string;\n dataClassification?: \"internal\" | \"confidential\" | \"restricted\";\n assignedToRole?: string;\n requireDualApproval?: boolean;\n waitMs?: number;\n description?: string;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nconst ACTION_RISK: Record<CloseActionType, \"critical\" | \"high\" | \"medium\" | \"low\"> = {\n \"period.close\": \"critical\",\n \"period.reopen\": \"critical\",\n \"reconciliation.lock\": \"high\",\n \"reconciliation.certify\": \"high\",\n};\n\nconst ACTION_REVERSIBILITY: Record<CloseActionType, \"reversible\" | \"irreversible\" | \"partial\"> = {\n \"period.close\": \"partial\",\n \"period.reopen\": \"partial\",\n \"reconciliation.lock\": \"reversible\",\n \"reconciliation.certify\": \"irreversible\",\n};\n\nexport interface ReconciliationCertifyOptions {\n accountId: string;\n period: string;\n certifiedBy: string;\n balanceDifference: number;\n dualApprovalRequired: boolean;\n secondApprover?: string;\n supportingEvidenceUri?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectReconciliationCertify(\n opts: ReconciliationCertifyOptions,\n): Promise<ApprovalPermit> {\n return protectCloseAction({\n action: \"reconciliation.certify\",\n periodLabel: opts.period,\n closedBy: opts.certifiedBy,\n entityId: opts.accountId,\n requireDualApproval: opts.dualApprovalRequired,\n description: `Reconciliation certify for account ${opts.accountId} period ${opts.period} by ${opts.certifiedBy}`,\n ...(opts.assignedToRole !== undefined ? { assignedToRole: opts.assignedToRole } : {}),\n ...(opts.waitMs !== undefined ? { waitMs: opts.waitMs } : {}),\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n}\n\nexport async function protectCloseAction(\n opts: CloseGovernanceOptions,\n): Promise<ApprovalPermit> {\n const ctx = buildActionContext({\n actor: {\n id: opts.closedBy,\n type: \"human\",\n trust_level: \"medium\",\n },\n resource: {\n id: opts.entityId,\n type: \"accounting_entity\",\n sensitivity: opts.dataClassification ?? \"confidential\",\n ...(opts.entityName !== undefined ? { name: opts.entityName } : {}),\n },\n environment: \"production\",\n action_meta: {\n risk_level: ACTION_RISK[opts.action],\n reversibility: ACTION_REVERSIBILITY[opts.action],\n description: opts.description ?? `${opts.action} for period ${opts.periodLabel} on entity ${opts.entityId}`,\n },\n extra: {\n period_label: opts.periodLabel,\n close_action: opts.action,\n },\n });\n\n return protectOrEscalate(\n {\n action: opts.action,\n agent: opts.closedBy,\n context: flattenActionContext(ctx),\n },\n {\n escalationReason: `Accounting ${opts.action} for period '${opts.periodLabel}' requires approval`,\n assignedToRole: opts.assignedToRole ?? \"controller\",\n quorumRequired: (opts.requireDualApproval ?? opts.action === \"period.close\") ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 24 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n },\n );\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport const VENDOR_PAYMENT_ACTION = \"vendor.payment.release\" as const;\n\nexport interface PaymentReleaseOptions {\n amount: number;\n currency: string;\n vendorId: string;\n vendorName?: string;\n authorizedBy: string;\n reference?: string;\n description?: string;\n autoEscalateAbove?: number;\n requireDualApprovalAbove?: number;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nconst ISO_4217 = /^[A-Z]{3}$/;\n\nexport async function protectPaymentRelease(\n opts: PaymentReleaseOptions,\n): Promise<ApprovalPermit | Permit> {\n if (!ISO_4217.test(opts.currency)) {\n throw new TypeError(\n `Invalid currency code '${opts.currency}': must be a 3-letter ISO 4217 code (e.g. USD, EUR, GBP)`,\n );\n }\n\n if (opts.amount <= 0) {\n throw new RangeError(`Payment amount must be greater than 0, got ${opts.amount}`);\n }\n\n const escalateThreshold = opts.autoEscalateAbove ?? 10_000;\n const dualThreshold = opts.requireDualApprovalAbove ?? 100_000;\n const needsEscalation = opts.amount > escalateThreshold;\n const needsDual = opts.amount > dualThreshold;\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: opts.vendorId,\n type: \"vendor\",\n ...(opts.vendorName !== undefined ? { name: opts.vendorName } : {}),\n },\n environment: \"production\",\n action_meta: {\n risk_level: opts.amount > dualThreshold ? \"critical\" : opts.amount > escalateThreshold ? \"high\" : \"medium\",\n reversibility: \"irreversible\",\n estimated_amount: opts.amount,\n currency: opts.currency,\n description: opts.description ?? `Release ${opts.currency} ${opts.amount.toLocaleString()} to ${opts.vendorName ?? opts.vendorId}`,\n },\n extra: {\n reference: opts.reference,\n },\n });\n\n const request = {\n action: VENDOR_PAYMENT_ACTION,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n };\n\n if (needsEscalation) {\n return protectOrEscalate(request, {\n escalationReason: `Payment of ${opts.currency} ${opts.amount.toLocaleString()} to ${opts.vendorName ?? opts.vendorId} exceeds auto-approval threshold of ${opts.currency} ${escalateThreshold.toLocaleString()}`,\n assignedToRole: opts.assignedToRole ?? \"finance-approver\",\n quorumRequired: needsDual ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 4 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n }\n return protect(request);\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport const CUSTOMER_DATA_EXPORT_ACTION = \"customer.data.export\" as const;\n\nexport interface DataExportOptions {\n dataset: string;\n destination: string;\n containsPii: boolean;\n rowCount: number;\n dataClassification: \"public\" | \"internal\" | \"confidential\" | \"restricted\";\n purpose: string;\n dpaReference?: string;\n encryption?: string;\n authorizedBy: string;\n rowCap?: number;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nfunction classifyExportRisk(opts: DataExportOptions): \"low\" | \"medium\" | \"high\" | \"critical\" {\n if (opts.containsPii && opts.rowCount > 10000) return \"critical\";\n if (opts.containsPii) return \"high\";\n if (opts.dataClassification === \"confidential\" || opts.dataClassification === \"restricted\") return \"high\";\n return \"medium\";\n}\n\nexport async function protectDataExport(\n opts: DataExportOptions,\n): Promise<ApprovalPermit | Permit> {\n const riskLevel = classifyExportRisk(opts);\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: opts.dataset,\n type: \"dataset\",\n sensitivity: opts.dataClassification,\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: \"irreversible\",\n description: `Export dataset '${opts.dataset}' to '${opts.destination}' (${opts.rowCount} rows, PII: ${opts.containsPii})`,\n },\n extra: {\n destination: opts.destination,\n row_count: opts.rowCount,\n contains_pii: opts.containsPii,\n data_classification: opts.dataClassification,\n purpose: opts.purpose,\n dpa_reference: opts.dpaReference,\n encryption: opts.encryption,\n row_cap: opts.rowCap,\n },\n });\n\n const request = {\n action: CUSTOMER_DATA_EXPORT_ACTION,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n };\n\n if (riskLevel === \"critical\" || riskLevel === \"high\") {\n return protectOrEscalate(request, {\n escalationReason: `Data export of '${opts.dataset}' to '${opts.destination}' requires approval (risk: ${riskLevel})`,\n assignedToRole: opts.assignedToRole ?? \"data-governance\",\n waitMs: opts.waitMs ?? 4 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n }\n return protect(request);\n}\n","import { protect } from \"./protect.js\";\nimport { AtlaSentDeniedError } from \"./errors.js\";\nimport type { ProtectRequest, Permit } from \"./protect.js\";\n\nexport type ShadowMode = \"observe\" | \"warn\" | \"enforce\";\n\nexport interface ShadowOutcome {\n readonly decision: \"permit\" | \"deny\" | \"hold\" | \"escalate\";\n readonly permit: Permit | null;\n readonly error: AtlaSentDeniedError | null;\n readonly would_have_blocked: boolean;\n readonly latencyMs: number;\n readonly evaluationId: string | null;\n readonly request: ProtectRequest;\n readonly mode: ShadowMode;\n}\n\nexport interface ShadowConfig {\n mode?: ShadowMode;\n onOutcome?: (outcome: ShadowOutcome) => void | Promise<void>;\n reportToApi?: boolean;\n apiKey?: string;\n baseUrl?: string;\n}\n\nlet _defaultConfig: ShadowConfig = {};\n\nexport function configureShadow(config: ShadowConfig): void {\n _defaultConfig = { ..._defaultConfig, ...config };\n}\n\nexport interface ShadowOptions extends ShadowConfig {}\n\nexport async function protectShadow(\n request: ProtectRequest,\n opts?: ShadowOptions,\n): Promise<ShadowOutcome> {\n const merged: ShadowConfig = { ..._defaultConfig, ...opts };\n const mode = merged.mode ?? \"observe\";\n\n if (mode === \"enforce\") {\n const start = Date.now();\n const permit = await protect(request);\n const outcome: ShadowOutcome = {\n decision: \"permit\",\n permit,\n error: null,\n would_have_blocked: false,\n latencyMs: Date.now() - start,\n evaluationId: permit.permitId,\n request,\n mode,\n };\n await _notify(outcome, merged);\n return outcome;\n }\n\n const start = Date.now();\n try {\n const permit = await protect(request);\n const outcome: ShadowOutcome = {\n decision: \"permit\",\n permit,\n error: null,\n would_have_blocked: false,\n latencyMs: Date.now() - start,\n evaluationId: permit.permitId,\n request,\n mode,\n };\n await _notify(outcome, merged);\n if (merged.reportToApi) {\n void reportShadowEvent(outcome, merged).catch(() => undefined);\n }\n return outcome;\n } catch (err) {\n if (err instanceof AtlaSentDeniedError) {\n const outcome: ShadowOutcome = {\n decision: err.decision as \"deny\" | \"hold\" | \"escalate\",\n permit: null,\n error: err,\n would_have_blocked: true,\n latencyMs: Date.now() - start,\n evaluationId: err.evaluationId ?? null,\n request,\n mode,\n };\n if (mode === \"warn\") {\n // eslint-disable-next-line no-console\n console.warn(\n `[AtlaSent shadow:warn] Action '${request.action}' would have been blocked (decision=${err.decision}, evaluationId=${err.evaluationId ?? \"unknown\"})`,\n );\n }\n await _notify(outcome, merged);\n if (merged.reportToApi) {\n void reportShadowEvent(outcome, merged).catch(() => undefined);\n }\n return outcome;\n }\n throw err;\n }\n}\n\nasync function _notify(\n outcome: ShadowOutcome,\n config: ShadowConfig,\n): Promise<void> {\n if (config.onOutcome) {\n try {\n await config.onOutcome(outcome);\n } catch {\n // onOutcome errors must never propagate\n }\n }\n}\n\nexport interface ShadowEventPayload {\n action: string;\n agentId: string | null;\n decision: ShadowOutcome[\"decision\"];\n would_have_blocked: boolean;\n latencyMs: number;\n evaluationId: string | null;\n mode: ShadowMode;\n deniedReason?: string;\n timestamp: string;\n}\n\nexport async function reportShadowEvent(\n outcome: ShadowOutcome,\n opts?: Pick<ShadowConfig, \"apiKey\" | \"baseUrl\">,\n): Promise<void> {\n const apiKey =\n opts?.apiKey ?? _defaultConfig.apiKey ?? process.env[\"ATLASENT_API_KEY\"] ?? \"\";\n const baseUrl =\n opts?.baseUrl ?? _defaultConfig.baseUrl ?? process.env[\"ATLASENT_BASE_URL\"] ?? \"https://api.atlasent.ai\";\n\n const payload: ShadowEventPayload = {\n action: outcome.request.action,\n agentId: outcome.request.agent ?? null,\n decision: outcome.decision,\n would_have_blocked: outcome.would_have_blocked,\n latencyMs: outcome.latencyMs,\n evaluationId: outcome.evaluationId,\n mode: outcome.mode,\n ...(outcome.error ? { deniedReason: outcome.error.message } : {}),\n timestamp: new Date().toISOString(),\n };\n\n const response = await fetch(`${baseUrl}/v1/shadow-events`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok && response.status >= 500) {\n throw new Error(`Shadow event reporting failed: ${response.status}`);\n }\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { protectShadow } from \"../shadow.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { ShadowOutcome } from \"../shadow.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type AgentToolMode = \"observe\" | \"enforce\" | \"escalate\";\n\nexport interface AgentToolOptions {\n toolName: string;\n toolArgs: Record<string, unknown>;\n agentId: string;\n sessionId?: string;\n riskLevel?: \"critical\" | \"high\" | \"medium\" | \"low\";\n mode?: AgentToolMode;\n assignedToRole?: string;\n waitMs?: number;\n description?: string;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nconst HIGH_RISK_TOOLS = new Set([\n \"bash\", \"shell\", \"exec\", \"execute_code\", \"run_command\",\n \"write_file\", \"delete_file\", \"overwrite_file\",\n \"sql_execute\", \"db_write\", \"db_delete\",\n \"send_email\", \"send_message\", \"post_to_slack\",\n \"create_pr\", \"merge_pr\", \"push_code\",\n \"deploy\", \"release\",\n \"make_payment\", \"transfer_funds\",\n \"create_user\", \"delete_user\", \"modify_permissions\",\n \"aws_cli\", \"gcloud\", \"kubectl\",\n]);\n\nconst CRITICAL_TOOLS = new Set([\n \"bash\", \"shell\", \"exec\", \"execute_code\", \"run_command\",\n \"delete_file\", \"db_delete\",\n \"make_payment\", \"transfer_funds\",\n \"delete_user\", \"modify_permissions\",\n \"deploy\", \"release\",\n]);\n\nexport function classifyToolRisk(\n toolName: string,\n): \"critical\" | \"high\" | \"medium\" | \"low\" {\n const normalized = toolName.toLowerCase().replace(/[^a-z0-9_]/g, \"_\");\n if (CRITICAL_TOOLS.has(normalized)) return \"critical\";\n if (HIGH_RISK_TOOLS.has(normalized)) return \"high\";\n if (normalized.includes(\"write\") || normalized.includes(\"create\") || normalized.includes(\"update\")) return \"medium\";\n return \"low\";\n}\n\nexport async function protectToolCall(\n opts: AgentToolOptions,\n): Promise<ApprovalPermit | Permit | ShadowOutcome> {\n const inferredRisk = opts.riskLevel ?? classifyToolRisk(opts.toolName);\n const mode = opts.mode ?? (inferredRisk === \"low\" ? \"enforce\" : \"escalate\");\n\n const ctx = buildActionContext({\n actor: {\n id: opts.agentId,\n type: \"agent\",\n ...(opts.sessionId !== undefined ? { session_id: opts.sessionId } : {}),\n },\n resource: {\n type: \"agent_tool\",\n id: opts.toolName,\n },\n environment: \"production\",\n action_meta: {\n risk_level: inferredRisk,\n reversibility: inferredRisk === \"critical\" || inferredRisk === \"high\" ? \"irreversible\" : \"reversible\",\n description: opts.description ?? `Agent ${opts.agentId} calling tool '${opts.toolName}'`,\n },\n extra: {\n tool_args_keys: Object.keys(opts.toolArgs),\n session_id: opts.sessionId,\n },\n });\n\n const request = {\n action: `agent_tool.${opts.toolName}`,\n agent: opts.agentId,\n context: flattenActionContext(ctx),\n };\n\n if (mode === \"observe\") {\n return protectShadow(request, { mode: \"observe\" });\n }\n\n if (mode === \"escalate\" || inferredRisk === \"critical\") {\n return protectOrEscalate(request, {\n escalationReason: `Agent '${opts.agentId}' is calling ${inferredRisk}-risk tool '${opts.toolName}'`,\n assignedToRole: opts.assignedToRole ?? \"agent-supervisor\",\n riskScore: inferredRisk === \"critical\" ? 1.0 : inferredRisk === \"high\" ? 0.75 : 0.5,\n waitMs: opts.waitMs ?? 15 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n }\n\n return protect(request);\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type GxpActionType =\n | \"manufacturing.batch_record.release\"\n | \"clinical.tmf.record.modify\"\n | \"clinical.data.access\"\n | \"clinical.source_data.read\"\n | \"clinical.signature.apply\"\n | \"clinical.deviation.report\"\n | \"clinical.consent.update\"\n | \"quality.capa.initiate\"\n | \"quality.capa.assign\"\n | \"quality.capa.progress\"\n | \"quality.capa.effectiveness_check\"\n | \"quality.capa.close\"\n | \"quality.deviation.detect\"\n | \"quality.deviation.classify\"\n | \"quality.deviation.escalate\"\n | \"quality.deviation.investigate\"\n | \"quality.deviation.close\"\n | \"quality.change_control.initiate\"\n | \"quality.change_control.classify\"\n | \"quality.change_control.approve\"\n | \"quality.change_control.implement\"\n | \"quality.change_control.close\";\n\nconst GXP_ACTION_RISK: Record<GxpActionType, \"high\" | \"critical\"> = {\n \"manufacturing.batch_record.release\": \"critical\",\n \"clinical.tmf.record.modify\": \"high\",\n \"clinical.data.access\": \"high\",\n \"clinical.source_data.read\": \"high\",\n \"clinical.signature.apply\": \"high\",\n \"clinical.deviation.report\": \"high\",\n \"clinical.consent.update\": \"high\",\n \"quality.capa.initiate\": \"high\",\n \"quality.capa.assign\": \"high\",\n \"quality.capa.progress\": \"high\",\n \"quality.capa.effectiveness_check\": \"high\",\n \"quality.capa.close\": \"high\",\n \"quality.deviation.detect\": \"high\",\n \"quality.deviation.classify\": \"high\",\n \"quality.deviation.escalate\": \"high\",\n \"quality.deviation.investigate\": \"high\",\n \"quality.deviation.close\": \"high\",\n \"quality.change_control.initiate\": \"high\",\n \"quality.change_control.classify\": \"high\",\n \"quality.change_control.approve\": \"high\",\n \"quality.change_control.implement\": \"high\",\n \"quality.change_control.close\": \"high\",\n};\n\nexport interface BatchRecordReleaseOptions {\n batchId: string;\n productCode: string;\n lotNumber: string;\n certifiedBy: string;\n qaSignoffBy: string;\n batchRecordComplete: boolean;\n deviationCount: number;\n regulatoryRegion: string;\n action: \"manufacturing.batch_record.release\";\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport interface ClinicalDataAccessOptions {\n subjectId: string;\n dataCategory: string;\n accessedBy: string;\n purpose: string;\n aiAgent: boolean;\n consentVerified: boolean;\n trialId: string;\n action: \"clinical.data.access\";\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport interface CAPAOptions {\n capaId: string;\n action: GxpActionType & `quality.capa.${string}`;\n initiatedBy?: string;\n closedBy?: string;\n secondClosedBy?: string;\n severity?: \"minor\" | \"major\" | \"critical\";\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n [key: string]: unknown;\n}\n\nexport type GxpActionOptions =\n | BatchRecordReleaseOptions\n | ClinicalDataAccessOptions\n | CAPAOptions\n | { action: GxpActionType; assignedToRole?: string; waitMs?: number; onEscalationCreated?: (handle: EscalationHandle) => void; apiKey?: string; baseUrl?: string; [key: string]: unknown };\n\nexport async function protectGxpAction(\n opts: GxpActionOptions,\n): Promise<ApprovalPermit> {\n const action = opts.action as GxpActionType;\n const riskLevel = GXP_ACTION_RISK[action] ?? \"high\";\n\n const actorId =\n (\"certifiedBy\" in opts && opts.certifiedBy) ||\n (\"accessedBy\" in opts && opts.accessedBy) ||\n (\"initiatedBy\" in opts && opts.initiatedBy) ||\n (\"closedBy\" in opts && opts.closedBy) ||\n \"gxp-agent\";\n\n const resourceId =\n (\"batchId\" in opts && opts.batchId) ||\n (\"capaId\" in opts && opts.capaId) ||\n (\"subjectId\" in opts && opts.subjectId) ||\n action;\n\n const ctx = buildActionContext({\n actor: {\n id: actorId as string,\n type: \"human\",\n },\n resource: {\n id: resourceId as string,\n type: \"gxp_record\",\n sensitivity: \"restricted\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: \"irreversible\",\n description: `GxP action '${action}' on resource '${resourceId}'`,\n },\n extra: {\n gxp_action: action,\n machine_executable: false,\n fail_closed: true,\n ...Object.fromEntries(\n Object.entries(opts).filter(([k]) => ![\"action\", \"assignedToRole\", \"waitMs\", \"onEscalationCreated\", \"apiKey\", \"baseUrl\"].includes(k)),\n ),\n },\n });\n\n return protectOrEscalate(\n {\n action,\n agent: actorId as string,\n context: flattenActionContext(ctx),\n },\n {\n escalationReason: `GxP action '${action}' requires human review — machine_executable: false`,\n assignedToRole: opts.assignedToRole ?? (riskLevel === \"critical\" ? \"qa-director\" : \"qa-reviewer\"),\n quorumRequired: action === \"quality.capa.close\" || action === \"manufacturing.batch_record.release\" ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 24 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n },\n );\n}\n\nexport async function protectBatchRecordRelease(\n opts: Omit<BatchRecordReleaseOptions, \"action\">,\n): Promise<ApprovalPermit> {\n return protectGxpAction({ ...opts, action: \"manufacturing.batch_record.release\" });\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type PaymentOperationActionType =\n | \"payment.approval.approve\"\n | \"payment.approval.deny\"\n | \"payment.execute.approved\"\n | \"payment.execute.held\"\n | \"payment.execute.denied\"\n | \"payment.execute.policy_error\"\n | \"qb.transaction.approve\";\n\nconst PAYMENT_ACTION_RISK: Record<PaymentOperationActionType, \"critical\" | \"high\" | \"medium\"> = {\n \"payment.approval.approve\": \"high\",\n \"payment.approval.deny\": \"medium\",\n \"payment.execute.approved\": \"critical\",\n \"payment.execute.held\": \"high\",\n \"payment.execute.denied\": \"medium\",\n \"payment.execute.policy_error\": \"high\",\n \"qb.transaction.approve\": \"high\",\n};\n\nconst ESCALATE_ACTIONS = new Set<PaymentOperationActionType>([\n \"payment.approval.approve\",\n \"payment.execute.approved\",\n \"payment.execute.held\",\n \"payment.execute.policy_error\",\n \"qb.transaction.approve\",\n]);\n\nexport interface PaymentOperationOptions {\n paymentId: string;\n action: PaymentOperationActionType;\n amount?: number;\n currency?: string;\n approvedBy?: string;\n deniedBy?: string;\n executedBy?: string;\n heldBy?: string;\n holdReason?: string;\n policyRule?: string;\n errorCode?: string;\n bankReference?: string;\n invoiceId?: string;\n vendorId?: string;\n accountCode?: string;\n transactionId?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectPaymentOperation(\n opts: PaymentOperationOptions,\n): Promise<ApprovalPermit | Permit> {\n const riskLevel = PAYMENT_ACTION_RISK[opts.action] ?? \"high\";\n\n const actorId =\n opts.approvedBy ??\n opts.executedBy ??\n opts.deniedBy ??\n opts.heldBy ??\n \"payment-system\";\n\n const ctx = buildActionContext({\n actor: {\n id: actorId,\n type: \"human\",\n },\n resource: {\n id: opts.paymentId,\n type: \"payment\",\n ...(opts.vendorId !== undefined ? { vendor_id: opts.vendorId } : {}),\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: opts.action.includes(\"execute\") ? \"irreversible\" : \"reversible\",\n description: `Payment operation '${opts.action}' on payment '${opts.paymentId}'`,\n ...(opts.amount !== undefined ? { estimated_amount: opts.amount } : {}),\n ...(opts.currency !== undefined ? { currency: opts.currency } : {}),\n },\n extra: {\n payment_action: opts.action,\n ...(opts.invoiceId !== undefined ? { invoice_id: opts.invoiceId } : {}),\n ...(opts.holdReason !== undefined ? { hold_reason: opts.holdReason } : {}),\n ...(opts.policyRule !== undefined ? { policy_rule: opts.policyRule } : {}),\n ...(opts.errorCode !== undefined ? { error_code: opts.errorCode } : {}),\n ...(opts.bankReference !== undefined ? { bank_reference: opts.bankReference } : {}),\n ...(opts.accountCode !== undefined ? { account_code: opts.accountCode } : {}),\n ...(opts.transactionId !== undefined ? { transaction_id: opts.transactionId } : {}),\n },\n });\n\n const request = {\n action: opts.action,\n agent: actorId,\n context: flattenActionContext(ctx),\n };\n\n if (ESCALATE_ACTIONS.has(opts.action) || riskLevel === \"critical\") {\n return protectOrEscalate(request, {\n escalationReason: `Payment operation '${opts.action}' on payment '${opts.paymentId}' requires approval`,\n assignedToRole: opts.assignedToRole ?? \"finance-approver\",\n quorumRequired: riskLevel === \"critical\" ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 4 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n }\n\n return protect(request);\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type DeploymentActionType =\n | \"deployment.production.execute\"\n | \"deployment.staging.execute\"\n | \"deployment.rollback.execute\";\n\n/**\n * V1 backward-compatibility constant. The original `production.deploy`\n * action string from deployGate.ts is still supported by the server.\n * Use `DeploymentActionType` values for new V2 integrations.\n */\nexport const DEPLOY_V1_ACTION = \"production.deploy\" as const;\n\nconst DEPLOYMENT_ACTION_RISK: Record<DeploymentActionType, \"critical\" | \"high\"> = {\n \"deployment.production.execute\": \"critical\",\n \"deployment.staging.execute\": \"high\",\n \"deployment.rollback.execute\": \"critical\",\n};\n\nexport interface DeploymentV2Options {\n action: DeploymentActionType;\n deploymentId: string;\n buildSha: string;\n environment: \"production\" | \"staging\";\n approvedBy?: string;\n rollbackPlan?: string;\n changeTicket?: string;\n incidentId?: string;\n rollbackTarget?: string;\n authorizedBy?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectDeploymentV2(\n opts: DeploymentV2Options,\n): Promise<ApprovalPermit> {\n if (opts.action === \"deployment.rollback.execute\") {\n if (!opts.incidentId) {\n throw new TypeError(\n `deployment.rollback.execute requires 'incidentId' to be set`,\n );\n }\n if (!opts.rollbackTarget) {\n throw new TypeError(\n `deployment.rollback.execute requires 'rollbackTarget' to be set`,\n );\n }\n }\n\n const riskLevel = DEPLOYMENT_ACTION_RISK[opts.action] ?? \"high\";\n const actorId = opts.authorizedBy ?? opts.approvedBy ?? \"deploy-system\";\n\n const ctx = buildActionContext({\n actor: {\n id: actorId,\n type: \"service_account\",\n },\n resource: {\n id: opts.deploymentId,\n type: \"deployment\",\n },\n environment: opts.environment,\n action_meta: {\n risk_level: riskLevel,\n reversibility: opts.action === \"deployment.rollback.execute\" ? \"partial\" : \"irreversible\",\n description: `Deployment V2 '${opts.action}' for '${opts.deploymentId}' at sha '${opts.buildSha.slice(0, 8)}'`,\n },\n extra: {\n build_sha: opts.buildSha,\n ...(opts.changeTicket !== undefined ? { change_ticket: opts.changeTicket } : {}),\n ...(opts.rollbackPlan !== undefined ? { rollback_plan: opts.rollbackPlan } : {}),\n ...(opts.incidentId !== undefined ? { incident_id: opts.incidentId } : {}),\n ...(opts.rollbackTarget !== undefined ? { rollback_target: opts.rollbackTarget } : {}),\n },\n });\n\n return protectOrEscalate(\n {\n action: opts.action,\n agent: actorId,\n context: flattenActionContext(ctx),\n },\n {\n escalationReason: `Deployment V2 '${opts.action}' of '${opts.deploymentId}' requires human approval`,\n assignedToRole: opts.assignedToRole ?? \"release-manager\",\n quorumRequired: riskLevel === \"critical\" ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 30 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n },\n );\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type BehaviorEventCategory =\n | \"general\"\n | \"health.mental\"\n | \"health.adherence\"\n | \"financial\"\n | \"minor\";\n\nexport const BEHAVIOR_SENSITIVE_CATEGORIES: BehaviorEventCategory[] = [\n \"health.mental\",\n \"health.adherence\",\n \"financial\",\n \"minor\",\n];\n\nexport interface BehaviorEventOptions {\n action: \"behavior.event.share\";\n subjectId: string;\n eventCategory: BehaviorEventCategory;\n destination: string;\n purpose: string;\n consentVerified: boolean;\n dataMinimized: boolean;\n subjectIsMinor?: boolean;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nfunction isSensitive(opts: BehaviorEventOptions): boolean {\n return (\n BEHAVIOR_SENSITIVE_CATEGORIES.includes(opts.eventCategory) ||\n (opts.subjectIsMinor === true)\n );\n}\n\nfunction classifyBehaviorRisk(opts: BehaviorEventOptions): \"critical\" | \"high\" | \"medium\" {\n if (opts.subjectIsMinor === true) return \"critical\";\n if (opts.eventCategory === \"health.mental\") return \"critical\";\n if (BEHAVIOR_SENSITIVE_CATEGORIES.includes(opts.eventCategory)) return \"high\";\n return \"medium\";\n}\n\nexport async function protectBehaviorEvent(\n opts: BehaviorEventOptions,\n): Promise<ApprovalPermit> {\n const riskLevel = classifyBehaviorRisk(opts);\n const sensitive = isSensitive(opts);\n\n const ctx = buildActionContext({\n actor: {\n id: opts.subjectId,\n type: \"human\",\n },\n resource: {\n id: opts.subjectId,\n type: \"behavior_event\",\n sensitivity: sensitive ? \"restricted\" : \"confidential\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: \"irreversible\",\n description: `Behavior event share for subject '${opts.subjectId}' category '${opts.eventCategory}' to '${opts.destination}'`,\n },\n extra: {\n behavior_event_category: opts.eventCategory,\n destination: opts.destination,\n purpose: opts.purpose,\n consent_verified: opts.consentVerified,\n data_minimized: opts.dataMinimized,\n machine_executable: !sensitive,\n subject_is_minor: opts.subjectIsMinor ?? false,\n hold_reason: opts.subjectIsMinor ? \"HOLD_HUMAN_REVIEW_REQUIRED\" : undefined,\n },\n });\n\n return protectOrEscalate(\n {\n action: opts.action,\n agent: opts.subjectId,\n context: flattenActionContext(ctx),\n },\n {\n escalationReason: opts.subjectIsMinor\n ? `HOLD_HUMAN_REVIEW_REQUIRED: behavior event share for minor subject '${opts.subjectId}'`\n : `Behavior event share for sensitive category '${opts.eventCategory}' requires human review`,\n assignedToRole: opts.assignedToRole ?? (opts.subjectIsMinor ? \"safeguarding-officer\" : \"privacy-reviewer\"),\n quorumRequired: opts.subjectIsMinor || riskLevel === \"critical\" ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 4 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n },\n );\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type InfraActionType =\n | \"aws.ec2.stop_instance\"\n | \"aws.ec2.terminate_instance\"\n | \"github.repos.delete\"\n | \"database.table.drop\"\n | \"database.volume.delete\"\n | \"db.table.delete\"\n | \"infra.volume.delete\";\n\nconst INFRA_ACTION_RISK: Record<InfraActionType, \"critical\" | \"high\"> = {\n \"aws.ec2.stop_instance\": \"high\",\n \"aws.ec2.terminate_instance\": \"critical\",\n \"github.repos.delete\": \"critical\",\n \"database.table.drop\": \"critical\",\n \"database.volume.delete\": \"critical\",\n \"db.table.delete\": \"critical\",\n \"infra.volume.delete\": \"critical\",\n};\n\nconst MACHINE_EXECUTABLE_ACTIONS = new Set<InfraActionType>([\n \"aws.ec2.stop_instance\",\n]);\n\nconst DATA_DESTRUCTIVE_ACTIONS = new Set<InfraActionType>([\n \"database.table.drop\",\n \"database.volume.delete\",\n \"db.table.delete\",\n \"infra.volume.delete\",\n]);\n\nexport interface InfraActionOptions {\n action: InfraActionType;\n resourceId: string;\n authorizedBy: string;\n reason: string;\n changeTicket?: string;\n incidentId?: string;\n backupVerified?: boolean;\n region?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectInfraAction(\n opts: InfraActionOptions,\n): Promise<ApprovalPermit | Permit> {\n if (!opts.changeTicket && !opts.incidentId) {\n throw new TypeError(\n `Infrastructure action '${opts.action}' requires either 'changeTicket' or 'incidentId'`,\n );\n }\n\n if (DATA_DESTRUCTIVE_ACTIONS.has(opts.action) && opts.backupVerified !== true) {\n throw new TypeError(\n `Data-destructive action '${opts.action}' requires 'backupVerified: true'`,\n );\n }\n\n const riskLevel = INFRA_ACTION_RISK[opts.action] ?? \"high\";\n const machineExecutable = MACHINE_EXECUTABLE_ACTIONS.has(opts.action);\n const isDestructive = !machineExecutable;\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: opts.resourceId,\n type: \"infrastructure_resource\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: DATA_DESTRUCTIVE_ACTIONS.has(opts.action) ? \"irreversible\" : opts.action === \"aws.ec2.terminate_instance\" ? \"irreversible\" : \"reversible\",\n description: `Infrastructure action '${opts.action}' on resource '${opts.resourceId}': ${opts.reason}`,\n },\n extra: {\n infra_action: opts.action,\n machine_executable: machineExecutable,\n reason: opts.reason,\n ...(opts.changeTicket !== undefined ? { change_ticket: opts.changeTicket } : {}),\n ...(opts.incidentId !== undefined ? { incident_id: opts.incidentId } : {}),\n ...(opts.backupVerified !== undefined ? { backup_verified: opts.backupVerified } : {}),\n ...(opts.region !== undefined ? { region: opts.region } : {}),\n },\n });\n\n const request = {\n action: opts.action,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n };\n\n if (isDestructive || riskLevel === \"critical\") {\n return protectOrEscalate(request, {\n escalationReason: `Infrastructure action '${opts.action}' on '${opts.resourceId}' requires human approval (machine_executable: false)`,\n assignedToRole: opts.assignedToRole ?? (DATA_DESTRUCTIVE_ACTIONS.has(opts.action) ? \"dba-approver\" : \"infra-approver\"),\n quorumRequired: riskLevel === \"critical\" ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 30 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n }\n\n return protect(request);\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type HrActionType =\n | \"hr.employee.offboard\"\n | \"hr.access.revoke\"\n | \"hr.role.escalate\";\n\nconst HR_ACTION_RISK: Record<HrActionType, \"critical\" | \"high\"> = {\n \"hr.employee.offboard\": \"high\",\n \"hr.access.revoke\": \"high\",\n \"hr.role.escalate\": \"critical\",\n};\n\nconst MACHINE_EXECUTABLE_ACTIONS = new Set<HrActionType>([\n \"hr.access.revoke\",\n]);\n\nexport interface HrActionOptions {\n action: HrActionType;\n employeeId: string;\n authorizedBy: string;\n // offboard-specific\n effectiveDate?: string;\n offboardingReason?: string;\n // role-escalate-specific\n requestedRole?: string;\n businessJustification?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectHrAction(\n opts: HrActionOptions,\n): Promise<ApprovalPermit | Permit> {\n if (opts.action === \"hr.employee.offboard\") {\n if (!opts.effectiveDate) {\n throw new TypeError(\n `HR action 'hr.employee.offboard' requires 'effectiveDate'`,\n );\n }\n if (!opts.offboardingReason) {\n throw new TypeError(\n `HR action 'hr.employee.offboard' requires 'offboardingReason'`,\n );\n }\n }\n\n if (opts.action === \"hr.role.escalate\") {\n if (!opts.requestedRole) {\n throw new TypeError(\n `HR action 'hr.role.escalate' requires 'requestedRole'`,\n );\n }\n if (!opts.businessJustification) {\n throw new TypeError(\n `HR action 'hr.role.escalate' requires 'businessJustification'`,\n );\n }\n }\n\n const riskLevel = HR_ACTION_RISK[opts.action] ?? \"high\";\n const machineExecutable = MACHINE_EXECUTABLE_ACTIONS.has(opts.action);\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: opts.employeeId,\n type: \"hr_employee_record\",\n sensitivity: \"restricted\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: opts.action === \"hr.employee.offboard\" ? \"irreversible\" : \"reversible\",\n description: `HR action '${opts.action}' on employee '${opts.employeeId}'`,\n },\n extra: {\n hr_action: opts.action,\n machine_executable: machineExecutable,\n ...(opts.effectiveDate !== undefined ? { effective_date: opts.effectiveDate } : {}),\n ...(opts.offboardingReason !== undefined ? { offboarding_reason: opts.offboardingReason } : {}),\n ...(opts.requestedRole !== undefined ? { requested_role: opts.requestedRole } : {}),\n ...(opts.businessJustification !== undefined ? { business_justification: opts.businessJustification } : {}),\n },\n });\n\n const request = {\n action: opts.action,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n };\n\n if (!machineExecutable || riskLevel === \"critical\") {\n return protectOrEscalate(request, {\n escalationReason: `HR action '${opts.action}' on employee '${opts.employeeId}' requires human review (machine_executable: false)`,\n assignedToRole: opts.assignedToRole ?? (riskLevel === \"critical\" ? \"security-approver\" : \"hr-approver\"),\n quorumRequired: riskLevel === \"critical\" ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 24 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n }\n\n return protect(request);\n}\n\nexport async function protectHrOffboard(\n opts: Omit<HrActionOptions, \"action\"> & { effectiveDate: string; offboardingReason: string },\n): Promise<ApprovalPermit | Permit> {\n return protectHrAction({ ...opts, action: \"hr.employee.offboard\" });\n}\n\nexport async function protectHrRoleEscalate(\n opts: Omit<HrActionOptions, \"action\"> & { requestedRole: string; businessJustification: string },\n): Promise<ApprovalPermit | Permit> {\n return protectHrAction({ ...opts, action: \"hr.role.escalate\" });\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type ModelGovernanceActionType =\n | \"ml.model.promote\"\n | \"ml.model.retire\"\n | \"ml.model.fine_tune\";\n\nconst MODEL_ACTION_RISK: Record<ModelGovernanceActionType, \"critical\" | \"high\"> = {\n \"ml.model.promote\": \"critical\",\n \"ml.model.retire\": \"high\",\n \"ml.model.fine_tune\": \"high\",\n};\n\nexport interface ModelGovernanceOptions {\n action: ModelGovernanceActionType;\n modelId: string;\n authorizedBy: string;\n reason: string;\n safetyReviewId?: string;\n serviceImpactAssessed?: boolean;\n alignmentVerified?: boolean;\n targetEnvironment?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectModelGovernance(\n opts: ModelGovernanceOptions,\n): Promise<ApprovalPermit> {\n const riskLevel = MODEL_ACTION_RISK[opts.action] ?? \"high\";\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: opts.modelId,\n type: \"ml_model\",\n sensitivity: \"restricted\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: opts.action === \"ml.model.retire\" ? \"irreversible\" : \"reversible\",\n description: `Model governance action '${opts.action}' on model '${opts.modelId}': ${opts.reason}`,\n },\n extra: {\n model_action: opts.action,\n machine_executable: false,\n fail_closed: true,\n reason: opts.reason,\n ...(opts.safetyReviewId !== undefined ? { safety_review_id: opts.safetyReviewId } : {}),\n ...(opts.serviceImpactAssessed !== undefined ? { service_impact_assessed: opts.serviceImpactAssessed } : {}),\n ...(opts.alignmentVerified !== undefined ? { alignment_verified: opts.alignmentVerified } : {}),\n ...(opts.targetEnvironment !== undefined ? { target_environment: opts.targetEnvironment } : {}),\n },\n });\n\n return protectOrEscalate(\n {\n action: opts.action,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n },\n {\n escalationReason: `Model governance action '${opts.action}' on '${opts.modelId}' requires human review — machine_executable: false`,\n assignedToRole: opts.assignedToRole ?? (riskLevel === \"critical\" ? \"ml-safety-director\" : \"ml-reviewer\"),\n quorumRequired: riskLevel === \"critical\" ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 48 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n },\n );\n}\n\nexport async function protectModelPromotion(\n opts: Omit<ModelGovernanceOptions, \"action\">,\n): Promise<ApprovalPermit> {\n return protectModelGovernance({ ...opts, action: \"ml.model.promote\" });\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type DataDeleteActionType = \"customer.data.delete\";\n\nexport type GdprLegalBasis =\n | \"erasure_request\"\n | \"retention_expired\"\n | \"consent_withdrawn\"\n | \"controller_instruction\";\n\nexport interface DataDeleteOptions {\n action: DataDeleteActionType;\n dataSubjectId: string;\n verifiedBy: string;\n gdprBasis: GdprLegalBasis;\n dpaReference?: string;\n dataCategories?: string[];\n retentionEndDate?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectCustomerDataDelete(\n opts: DataDeleteOptions,\n): Promise<ApprovalPermit> {\n const ctx = buildActionContext({\n actor: {\n id: opts.verifiedBy,\n type: \"human\",\n },\n resource: {\n id: opts.dataSubjectId,\n type: \"customer_data\",\n sensitivity: \"restricted\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: \"critical\",\n reversibility: \"irreversible\",\n description: `Customer data deletion for data subject '${opts.dataSubjectId}' under GDPR/CCPA basis '${opts.gdprBasis}'`,\n },\n extra: {\n data_delete_action: opts.action,\n machine_executable: false,\n fail_closed: true,\n gdpr_basis: opts.gdprBasis,\n verified_by: opts.verifiedBy,\n data_subject_id: opts.dataSubjectId,\n ...(opts.dpaReference !== undefined ? { dpa_reference: opts.dpaReference } : {}),\n ...(opts.dataCategories !== undefined ? { data_categories: opts.dataCategories } : {}),\n ...(opts.retentionEndDate !== undefined ? { retention_end_date: opts.retentionEndDate } : {}),\n },\n });\n\n return protectOrEscalate(\n {\n action: opts.action,\n agent: opts.verifiedBy,\n context: flattenActionContext(ctx),\n },\n {\n escalationReason: `Customer data deletion for '${opts.dataSubjectId}' is irreversible and requires compliance officer sign-off — machine_executable: false, fail_closed: true`,\n assignedToRole: opts.assignedToRole ?? \"compliance-officer\",\n quorumRequired: \"simple_majority\",\n waitMs: opts.waitMs ?? 72 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n },\n );\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type ContractActionType =\n | \"contract.execute\"\n | \"contract.amend\";\n\nconst CONTRACT_ACTION_RISK: Record<ContractActionType, \"critical\" | \"high\"> = {\n \"contract.execute\": \"critical\",\n \"contract.amend\": \"high\",\n};\n\nexport interface ContractActionOptions {\n action: ContractActionType;\n contractId: string;\n authorizedBy: string;\n counterparty: string;\n legalReviewId?: string;\n estimatedValue?: number;\n currency?: string;\n effectiveDate?: string;\n amendmentDescription?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectContractAction(\n opts: ContractActionOptions,\n): Promise<ApprovalPermit> {\n if (opts.action === \"contract.amend\" && !opts.amendmentDescription) {\n throw new TypeError(\n `Contract action 'contract.amend' requires 'amendmentDescription'`,\n );\n }\n\n const riskLevel = CONTRACT_ACTION_RISK[opts.action] ?? \"high\";\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: opts.contractId,\n type: \"contract\",\n sensitivity: \"restricted\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: opts.action === \"contract.execute\" ? \"irreversible\" : \"partial\",\n description: `Contract action '${opts.action}' on contract '${opts.contractId}' with counterparty '${opts.counterparty}'`,\n ...(opts.estimatedValue !== undefined ? { estimated_amount: opts.estimatedValue } : {}),\n ...(opts.currency !== undefined ? { currency: opts.currency } : {}),\n },\n extra: {\n contract_action: opts.action,\n machine_executable: false,\n fail_closed: true,\n counterparty: opts.counterparty,\n ...(opts.legalReviewId !== undefined ? { legal_review_id: opts.legalReviewId } : {}),\n ...(opts.effectiveDate !== undefined ? { effective_date: opts.effectiveDate } : {}),\n ...(opts.amendmentDescription !== undefined ? { amendment_description: opts.amendmentDescription } : {}),\n },\n });\n\n return protectOrEscalate(\n {\n action: opts.action,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n },\n {\n escalationReason: `Contract action '${opts.action}' on '${opts.contractId}' requires legal review — machine_executable: false`,\n assignedToRole: opts.assignedToRole ?? (riskLevel === \"critical\" ? \"legal-director\" : \"legal-reviewer\"),\n quorumRequired: riskLevel === \"critical\" ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 48 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n },\n );\n}\n\nexport async function protectContractExecution(\n opts: Omit<ContractActionOptions, \"action\">,\n): Promise<ApprovalPermit> {\n return protectContractAction({ ...opts, action: \"contract.execute\" });\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type PricingActionType =\n | \"pricing.rule.publish\"\n | \"pricing.discount.approve\";\n\nfunction classifyPricingRisk(opts: PricingActionOptions): \"high\" | \"medium\" {\n if (opts.action === \"pricing.rule.publish\") {\n return \"high\";\n }\n // pricing.discount.approve: medium for <10%, high for >=10%\n const pct = opts.discountPercent ?? 0;\n return pct >= 10 ? \"high\" : \"medium\";\n}\n\nfunction isPricingMachineExecutable(opts: PricingActionOptions): boolean {\n if (opts.action === \"pricing.rule.publish\") {\n // machine_executable: true for changes <5%, false for >=5%\n const pct = opts.priceChangePct ?? 0;\n return pct < 5;\n }\n // pricing.discount.approve: machine_executable: true for small (<10%) discounts\n const pct = opts.discountPercent ?? 0;\n return pct < 10;\n}\n\nexport interface PricingActionOptions {\n action: PricingActionType;\n ruleId: string;\n authorizedBy: string;\n // pricing.rule.publish\n priceChangePct?: number;\n affectedSkus?: string[];\n effectiveDate?: string;\n // pricing.discount.approve\n discountPercent?: number;\n customerId?: string;\n discountReason?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectPricingAction(\n opts: PricingActionOptions,\n): Promise<ApprovalPermit | Permit> {\n const riskLevel = classifyPricingRisk(opts);\n const machineExecutable = isPricingMachineExecutable(opts);\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: opts.ruleId,\n type: \"pricing_rule\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: \"reversible\",\n description: `Pricing action '${opts.action}' on rule '${opts.ruleId}'`,\n },\n extra: {\n pricing_action: opts.action,\n machine_executable: machineExecutable,\n ...(opts.priceChangePct !== undefined ? { price_change_pct: opts.priceChangePct } : {}),\n ...(opts.affectedSkus !== undefined ? { affected_skus: opts.affectedSkus } : {}),\n ...(opts.effectiveDate !== undefined ? { effective_date: opts.effectiveDate } : {}),\n ...(opts.discountPercent !== undefined ? { discount_percent: opts.discountPercent } : {}),\n ...(opts.customerId !== undefined ? { customer_id: opts.customerId } : {}),\n ...(opts.discountReason !== undefined ? { discount_reason: opts.discountReason } : {}),\n },\n });\n\n const request = {\n action: opts.action,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n };\n\n if (!machineExecutable || riskLevel === \"high\") {\n return protectOrEscalate(request, {\n escalationReason: `Pricing action '${opts.action}' on '${opts.ruleId}' requires human approval (machine_executable: false)`,\n assignedToRole: opts.assignedToRole ?? \"pricing-approver\",\n quorumRequired: \"single_approver\",\n waitMs: opts.waitMs ?? 4 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n }\n\n return protect(request);\n}\n\nexport async function protectPricingRule(\n opts: Omit<PricingActionOptions, \"action\">,\n): Promise<ApprovalPermit | Permit> {\n return protectPricingAction({ ...opts, action: \"pricing.rule.publish\" });\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type SecurityActionType =\n | \"security.incident.escalate\"\n | \"security.access.quarantine\";\n\nconst SECURITY_ACTION_RISK: Record<SecurityActionType, \"critical\"> = {\n \"security.incident.escalate\": \"critical\",\n \"security.access.quarantine\": \"critical\",\n};\n\n// All security actions are non-machine-executable and fail-closed.\nconst MACHINE_EXECUTABLE_ACTIONS = new Set<SecurityActionType>();\n\nexport interface SecurityActionOptions {\n action: SecurityActionType;\n authorizedBy: string;\n // security.incident.escalate — required\n incidentId?: string;\n severity?: \"low\" | \"medium\" | \"high\" | \"critical\";\n // security.access.quarantine — required\n targetId?: string;\n quarantineReason?: string;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectSecurityAction(\n opts: SecurityActionOptions,\n): Promise<ApprovalPermit> {\n if (opts.action === \"security.incident.escalate\") {\n if (!opts.incidentId) {\n throw new TypeError(\n `Security action 'security.incident.escalate' requires 'incidentId'`,\n );\n }\n if (!opts.severity) {\n throw new TypeError(\n `Security action 'security.incident.escalate' requires 'severity'`,\n );\n }\n }\n\n if (opts.action === \"security.access.quarantine\") {\n if (!opts.targetId) {\n throw new TypeError(\n `Security action 'security.access.quarantine' requires 'targetId'`,\n );\n }\n if (!opts.quarantineReason) {\n throw new TypeError(\n `Security action 'security.access.quarantine' requires 'quarantineReason'`,\n );\n }\n }\n\n const riskLevel = SECURITY_ACTION_RISK[opts.action];\n\n const resourceId =\n opts.action === \"security.incident.escalate\"\n ? opts.incidentId!\n : opts.targetId!;\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: resourceId,\n type:\n opts.action === \"security.incident.escalate\"\n ? \"security_incident\"\n : \"access_principal\",\n sensitivity: \"restricted\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: \"irreversible\",\n description: `Security action '${opts.action}' on resource '${resourceId}'`,\n },\n extra: {\n security_action: opts.action,\n machine_executable: false,\n fail_closed: true,\n ...(opts.incidentId !== undefined ? { incident_id: opts.incidentId } : {}),\n ...(opts.severity !== undefined ? { severity: opts.severity } : {}),\n ...(opts.targetId !== undefined ? { target_id: opts.targetId } : {}),\n ...(opts.quarantineReason !== undefined\n ? { quarantine_reason: opts.quarantineReason }\n : {}),\n },\n });\n\n const request = {\n action: opts.action,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n };\n\n return protectOrEscalate(request, {\n escalationReason: `Security action '${opts.action}' on '${resourceId}' requires human review (machine_executable: false, fail_closed: true)`,\n assignedToRole: \"security-approver\",\n quorumRequired: \"simple_majority\",\n waitMs: 3_600_000,\n ...(opts.onEscalationCreated !== undefined\n ? { onEscalationCreated: opts.onEscalationCreated }\n : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n}\n\nexport async function protectSecurityIncidentEscalate(\n opts: Omit<SecurityActionOptions, \"action\"> & {\n incidentId: string;\n severity: \"low\" | \"medium\" | \"high\" | \"critical\";\n },\n): Promise<ApprovalPermit> {\n return protectSecurityAction({\n ...opts,\n action: \"security.incident.escalate\",\n });\n}\n\nexport async function protectSecurityAccessQuarantine(\n opts: Omit<SecurityActionOptions, \"action\"> & {\n targetId: string;\n quarantineReason: string;\n },\n): Promise<ApprovalPermit> {\n return protectSecurityAction({\n ...opts,\n action: \"security.access.quarantine\",\n });\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type AccessCertActionType = \"access.cert.revoke\";\n\nconst ACCESS_CERT_ACTION_RISK: Record<AccessCertActionType, \"high\"> = {\n \"access.cert.revoke\": \"high\",\n};\n\n// access.cert.revoke is non-machine-executable.\nconst MACHINE_EXECUTABLE_ACTIONS = new Set<AccessCertActionType>();\n\nexport interface AccessCertOptions {\n action: AccessCertActionType;\n certId: string;\n revocationReason: string;\n authorizedBy?: string;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectAccessCertAction(\n opts: AccessCertOptions,\n): Promise<ApprovalPermit> {\n if (!opts.certId) {\n throw new TypeError(\n `Access cert action 'access.cert.revoke' requires 'certId'`,\n );\n }\n if (!opts.revocationReason) {\n throw new TypeError(\n `Access cert action 'access.cert.revoke' requires 'revocationReason'`,\n );\n }\n\n const riskLevel = ACCESS_CERT_ACTION_RISK[opts.action];\n const actor = opts.authorizedBy ?? \"system\";\n\n const ctx = buildActionContext({\n actor: {\n id: actor,\n type: \"human\",\n },\n resource: {\n id: opts.certId,\n type: \"access_certificate\",\n sensitivity: \"restricted\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: \"irreversible\",\n description: `Access cert action '${opts.action}' on cert '${opts.certId}'`,\n },\n extra: {\n access_cert_action: opts.action,\n machine_executable: false,\n cert_id: opts.certId,\n revocation_reason: opts.revocationReason,\n },\n });\n\n const request = {\n action: opts.action,\n agent: actor,\n context: flattenActionContext(ctx),\n };\n\n return protectOrEscalate(request, {\n escalationReason: `Access cert action '${opts.action}' on cert '${opts.certId}' requires human review (machine_executable: false)`,\n assignedToRole: \"security-approver\",\n quorumRequired: \"single_approver\",\n waitMs: 86_400_000,\n ...(opts.onEscalationCreated !== undefined\n ? { onEscalationCreated: opts.onEscalationCreated }\n : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n}\n\nexport async function protectAccessCertRevoke(\n opts: Omit<AccessCertOptions, \"action\">,\n): Promise<ApprovalPermit> {\n return protectAccessCertAction({ ...opts, action: \"access.cert.revoke\" });\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type FinancialCloseActionType = \"period.close.certify\";\n\nconst FINANCIAL_CLOSE_ACTION_RISK: Record<\n FinancialCloseActionType,\n \"critical\"\n> = {\n \"period.close.certify\": \"critical\",\n};\n\n// period.close.certify is non-machine-executable and fail-closed.\nconst MACHINE_EXECUTABLE_ACTIONS = new Set<FinancialCloseActionType>();\n\nexport interface FinancialCloseOptions {\n action: FinancialCloseActionType;\n periodId: string;\n certifiedBy: string;\n financialController: string;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectFinancialCloseAction(\n opts: FinancialCloseOptions,\n): Promise<ApprovalPermit> {\n if (!opts.periodId) {\n throw new TypeError(\n `Financial close action 'period.close.certify' requires 'periodId'`,\n );\n }\n if (!opts.certifiedBy) {\n throw new TypeError(\n `Financial close action 'period.close.certify' requires 'certifiedBy'`,\n );\n }\n if (!opts.financialController) {\n throw new TypeError(\n `Financial close action 'period.close.certify' requires 'financialController'`,\n );\n }\n\n const riskLevel = FINANCIAL_CLOSE_ACTION_RISK[opts.action];\n\n const ctx = buildActionContext({\n actor: {\n id: opts.certifiedBy,\n type: \"human\",\n },\n resource: {\n id: opts.periodId,\n type: \"financial_period\",\n sensitivity: \"restricted\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: \"irreversible\",\n description: `Financial close action '${opts.action}' for period '${opts.periodId}'`,\n },\n extra: {\n financial_close_action: opts.action,\n machine_executable: false,\n fail_closed: true,\n period_id: opts.periodId,\n certified_by: opts.certifiedBy,\n financial_controller: opts.financialController,\n },\n });\n\n const request = {\n action: opts.action,\n agent: opts.certifiedBy,\n context: flattenActionContext(ctx),\n };\n\n return protectOrEscalate(request, {\n escalationReason: `Financial close action '${opts.action}' for period '${opts.periodId}' requires human review (machine_executable: false, fail_closed: true)`,\n assignedToRole: \"financial-controller\",\n quorumRequired: \"simple_majority\",\n waitMs: 172_800_000,\n ...(opts.onEscalationCreated !== undefined\n ? { onEscalationCreated: opts.onEscalationCreated }\n : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n}\n\nexport async function protectPeriodCloseCertify(\n opts: Omit<FinancialCloseOptions, \"action\">,\n): Promise<ApprovalPermit> {\n return protectFinancialCloseAction({\n ...opts,\n action: \"period.close.certify\",\n });\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport { AtlaSentDeniedError } from \"../errors.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type DatabaseMigrationActionType = \"database.migration.apply\";\nexport type DatabaseDestructiveActionType =\n | \"database.schema.drop\"\n | \"database.table.delete\";\nexport type DatabaseActionType =\n | DatabaseMigrationActionType\n | DatabaseDestructiveActionType;\n\nexport interface PermitEvidence {\n action: DatabaseActionType;\n databaseId: string;\n authorizedBy: string;\n permitToken: string;\n timestamp: string;\n context: Record<string, unknown>;\n}\n\nexport interface DenialEvidence {\n action: DatabaseActionType;\n databaseId: string;\n authorizedBy: string;\n denialReason: string;\n evaluationId?: string;\n timestamp: string;\n context: Record<string, unknown>;\n}\n\nexport interface DatabaseActionOptions {\n action: DatabaseActionType;\n databaseId: string;\n authorizedBy: string;\n environment: \"production\" | \"staging\" | \"development\";\n // migration-specific\n migrationId?: string;\n migrationChecksum?: string;\n rollbackPlan?: string;\n // destructive-specific (schema.drop / table.delete)\n schemaName?: string;\n tableName?: string;\n backupVerified?: boolean;\n recoveryPointId?: string;\n // evidence callbacks — called after the gate resolves\n onPermitEvidence?: (evidence: PermitEvidence) => void | Promise<void>;\n onDenialEvidence?: (evidence: DenialEvidence) => void | Promise<void>;\n // escalation overrides\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectDatabaseAction(\n opts: DatabaseActionOptions,\n): Promise<ApprovalPermit | Permit> {\n // ── Validate required fields ─────────────────────────────────────────────\n\n if (opts.action === \"database.migration.apply\") {\n if (!opts.migrationId) {\n throw new TypeError(\n `Database action 'database.migration.apply' requires 'migrationId'`,\n );\n }\n if (!opts.migrationChecksum) {\n throw new TypeError(\n `Database action 'database.migration.apply' requires 'migrationChecksum'`,\n );\n }\n if (opts.environment === \"production\" && !opts.rollbackPlan) {\n throw new TypeError(\n `Database action 'database.migration.apply' in production requires 'rollbackPlan'`,\n );\n }\n }\n\n if (opts.action === \"database.schema.drop\") {\n if (!opts.schemaName) {\n throw new TypeError(\n `Database action 'database.schema.drop' requires 'schemaName'`,\n );\n }\n if (!opts.backupVerified) {\n throw new TypeError(\n `Database action 'database.schema.drop' requires 'backupVerified: true'`,\n );\n }\n if (!opts.recoveryPointId) {\n throw new TypeError(\n `Database action 'database.schema.drop' requires 'recoveryPointId'`,\n );\n }\n }\n\n if (opts.action === \"database.table.delete\") {\n if (!opts.tableName) {\n throw new TypeError(\n `Database action 'database.table.delete' requires 'tableName'`,\n );\n }\n if (!opts.backupVerified) {\n throw new TypeError(\n `Database action 'database.table.delete' requires 'backupVerified: true'`,\n );\n }\n if (!opts.recoveryPointId) {\n throw new TypeError(\n `Database action 'database.table.delete' requires 'recoveryPointId'`,\n );\n }\n }\n\n // ── Determine risk profile ────────────────────────────────────────────────\n\n const isDestructive =\n opts.action === \"database.schema.drop\" ||\n opts.action === \"database.table.delete\";\n const riskLevel = isDestructive ? \"critical\" : \"high\";\n\n // migration in production is not machine-executable; destructive never is\n const machineExecutable =\n opts.action === \"database.migration.apply\" &&\n opts.environment !== \"production\";\n\n // ── Build context ─────────────────────────────────────────────────────────\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: opts.databaseId,\n type: \"database\",\n sensitivity: \"restricted\",\n },\n environment: opts.environment,\n action_meta: {\n risk_level: riskLevel,\n reversibility: isDestructive ? \"irreversible\" : \"reversible\",\n description: `Database action '${opts.action}' on database '${opts.databaseId}'`,\n },\n extra: {\n database_action: opts.action,\n database_id: opts.databaseId,\n machine_executable: machineExecutable,\n ...(isDestructive ? { deny_by_default: true } : {}),\n ...(opts.migrationId !== undefined\n ? { migration_id: opts.migrationId }\n : {}),\n ...(opts.migrationChecksum !== undefined\n ? { migration_checksum: opts.migrationChecksum }\n : {}),\n ...(opts.rollbackPlan !== undefined\n ? { rollback_plan: opts.rollbackPlan }\n : {}),\n ...(opts.schemaName !== undefined\n ? { schema_name: opts.schemaName }\n : {}),\n ...(opts.tableName !== undefined ? { table_name: opts.tableName } : {}),\n ...(opts.backupVerified !== undefined\n ? { backup_verified: opts.backupVerified }\n : {}),\n ...(opts.recoveryPointId !== undefined\n ? { recovery_point_id: opts.recoveryPointId }\n : {}),\n },\n });\n\n const request = {\n action: opts.action,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n };\n\n // ── Route through gate ────────────────────────────────────────────────────\n\n if (machineExecutable) {\n // staging/development migration: direct protect()\n try {\n const result = await protect(request);\n if (opts.onPermitEvidence) {\n const permitToken = result.permitId;\n await opts.onPermitEvidence({\n action: opts.action,\n databaseId: opts.databaseId,\n authorizedBy: opts.authorizedBy,\n permitToken,\n timestamp: new Date().toISOString(),\n context: request.context as Record<string, unknown>,\n });\n }\n return result;\n } catch (err) {\n if (err instanceof AtlaSentDeniedError && opts.onDenialEvidence) {\n await opts.onDenialEvidence({\n action: opts.action,\n databaseId: opts.databaseId,\n authorizedBy: opts.authorizedBy,\n denialReason: err.reason ?? \"denied\",\n evaluationId: err.evaluationId,\n timestamp: new Date().toISOString(),\n context: request.context as Record<string, unknown>,\n });\n }\n throw err;\n }\n }\n\n // non-machine-executable: escalation required\n const quorum = isDestructive ? \"two_thirds\" : \"single_approver\";\n const defaultWaitMs = isDestructive\n ? 24 * 60 * 60 * 1000 // 24h for destructive\n : 4 * 60 * 60 * 1000; // 4h for production migration\n\n const escalationOpts = {\n escalationReason: `Database action '${opts.action}' on '${opts.databaseId}' requires human review (machine_executable: false)`,\n assignedToRole: \"database-admin\",\n quorumRequired: quorum as \"single_approver\" | \"two_thirds\",\n waitMs: opts.waitMs ?? defaultWaitMs,\n ...(opts.onEscalationCreated !== undefined\n ? { onEscalationCreated: opts.onEscalationCreated }\n : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n };\n\n try {\n const result = await protectOrEscalate(request, escalationOpts);\n if (opts.onPermitEvidence) {\n const permitToken =\n \"permit_token\" in result\n ? (result as { permit_token: string }).permit_token\n : result.escalationId || result.permitId;\n await opts.onPermitEvidence({\n action: opts.action,\n databaseId: opts.databaseId,\n authorizedBy: opts.authorizedBy,\n permitToken,\n timestamp: new Date().toISOString(),\n context: request.context as Record<string, unknown>,\n });\n }\n return result;\n } catch (err) {\n if (err instanceof AtlaSentDeniedError && opts.onDenialEvidence) {\n await opts.onDenialEvidence({\n action: opts.action,\n databaseId: opts.databaseId,\n authorizedBy: opts.authorizedBy,\n denialReason: err.reason ?? \"denied\",\n evaluationId: err.evaluationId,\n timestamp: new Date().toISOString(),\n context: request.context as Record<string, unknown>,\n });\n }\n throw err;\n }\n}\n\nexport async function protectDatabaseMigration(\n opts: Omit<DatabaseActionOptions, \"action\"> & {\n migrationId: string;\n migrationChecksum: string;\n },\n): Promise<ApprovalPermit | Permit> {\n return protectDatabaseAction({ ...opts, action: \"database.migration.apply\" });\n}\n\nexport async function protectDatabaseSchemaDrop(\n opts: Omit<DatabaseActionOptions, \"action\"> & {\n schemaName: string;\n backupVerified: true;\n recoveryPointId: string;\n },\n): Promise<ApprovalPermit | Permit> {\n return protectDatabaseAction({ ...opts, action: \"database.schema.drop\" });\n}\n\nexport async function protectDatabaseTableDelete(\n opts: Omit<DatabaseActionOptions, \"action\"> & {\n tableName: string;\n backupVerified: true;\n recoveryPointId: string;\n },\n): Promise<ApprovalPermit | Permit> {\n return protectDatabaseAction({ ...opts, action: \"database.table.delete\" });\n}\n","/**\n * Wire types for `POST /v1-decisions-replay/:id/replay`.\n *\n * Re-evaluates a recorded decision against its originally-pinned policy\n * bundle and engine version, then reports whether the result agrees with\n * what was recorded. Side-effect-free: no audit chain row is written and\n * no permit is issued (see ADR-016).\n *\n * Mirrors `_handleReplayPost` in atlasent-api's\n * `supabase/functions/v1-decisions-replay/handler.ts`. Variance kinds and\n * envelope-verification states are pinned to the API contract — keep this\n * file aligned with `_shared/decision-replay.ts` if the surface evolves.\n *\n * Per AtlaSent's versioning doctrine `/v1/decisions/:id/replay` is an\n * **alpha** endpoint; shapes can change without a deprecation cycle until\n * it graduates to stable v1 (see atlasent-api `docs/STABLE_V2_PROMOTION.md`).\n */\n\n/**\n * Replay variance — superset covering both the raw wire values used by\n * `replayDecision()` and the SDK-canonical values used by `replay()`.\n *\n * Raw wire values (replayDecision): NONE, DECISION_CHANGED, ENVELOPE_DRIFT\n * SDK-canonical values (replay): NONE, POLICY_DRIFT, ENVELOPE_DRIFT,\n * ENGINE_DRIFT, CHAIN_TAMPER, BUNDLE_MISSING\n */\nexport type ReplayVarianceKind =\n | \"NONE\"\n | \"DECISION_CHANGED\"\n | \"POLICY_DRIFT\"\n | \"ENVELOPE_DRIFT\"\n | \"ENGINE_DRIFT\"\n | \"CHAIN_TAMPER\"\n | \"BUNDLE_MISSING\";\n\n/** Engine-version registry classification (ADR-017). `unknown` covers\n * NULL engine_version (pre-replay-era rows) and registry-misses. */\nexport type EngineVersionKind =\n | \"active\"\n | \"retired\"\n | \"archival\"\n | \"unknown\";\n\n/** Envelope hash verification outcome for the recorded request envelope.\n * `verified` = recomputed hash matched; `drift` = mismatch; `envelope_missing`\n * = recorded hash points at a content_envelopes row that no longer exists;\n * `absent` = the original evaluation predates envelope_hash capture. */\nexport type EnvelopeVerification =\n | \"verified\"\n | \"drift\"\n | \"absent\"\n | \"envelope_missing\";\n\n/** Mirror of `decision` enum on the original evaluation. */\nexport type ReplayDecisionValue = \"allow\" | \"deny\" | \"hold\" | \"escalate\";\n\n/** Envelope-drift diagnostic. Present only when `variance === \"ENVELOPE_DRIFT\"`. */\nexport interface EnvelopeDriftDetail {\n recorded_hash: string;\n recomputed_hash: string;\n}\n\n/**\n * Successful POST /v1-decisions-replay/:id/replay response. The shape is\n * additive — additional fields may appear in future API versions.\n */\nexport interface ReplayDecisionResponse {\n decision_id: string;\n /** What the original decision was at evaluate time. */\n original_decision: ReplayDecisionValue;\n /** Recorded deny code from the original decision, if any. */\n original_deny_code?: string;\n /** Re-evaluated decision. Absent when replay short-circuits on\n * ENVELOPE_DRIFT — in that case the original decision is the only\n * authoritative value and no replay was run. */\n replay_decision?: ReplayDecisionValue;\n replay_deny_code?: string;\n /** Engine version string recorded with the original decision, or\n * `undefined` for pre-replay-era rows. */\n engine_version?: string;\n engine_version_kind: EngineVersionKind;\n /** Always `true` on a 200 — the handler refuses replay (409) when the\n * engine version does not accept replay. */\n accepts_replay: boolean;\n variance: ReplayVarianceKind;\n envelope_verification: EnvelopeVerification;\n envelope_drift_detail?: EnvelopeDriftDetail;\n replayed_at: string;\n}\n\n// ── ADR-015 Phase C — SDK-canonical replay surface ────────────────────────────\n\n/** Input to {@link AtlaSentClient.replay}. */\nexport interface ReplayRequest {\n /** The evaluation/decision ID to replay. */\n evaluationId: string;\n}\n\nimport { createHash } from \"node:crypto\";\nimport type { RateLimitState } from \"./types.js\";\nimport type { DecisionCanonical } from \"./types.js\";\n\n/**\n * Result of {@link AtlaSentClient.replay}.\n *\n * Uses SDK-canonical variance kinds (see {@link ReplayVarianceKind}).\n * `DECISION_CHANGED` on the wire maps to `POLICY_DRIFT` here.\n * 409 responses map to `ENGINE_DRIFT` or `BUNDLE_MISSING` and are never\n * thrown — callers can always switch on `varianceKind`.\n */\nexport interface ReplayResponse {\n /** The decision/evaluation ID that was replayed. */\n decisionId: string;\n /** SDK-canonical variance outcome. */\n varianceKind: ReplayVarianceKind;\n /** The original recorded decision. */\n originalDecision: DecisionCanonical;\n /** Original deny code, if any. */\n originalDenyCode?: string;\n /** Re-evaluated decision. Absent when `varianceKind === \"ENVELOPE_DRIFT\"`. */\n replayedDecision?: DecisionCanonical;\n replayedDenyCode?: string;\n engineVersion?: string;\n engineVersionKind?: string;\n /** Whether the evaluation was eligible for replay. `false` for 409 responses. */\n acceptsReplay: boolean;\n envelopeVerification?: string;\n /** ISO-8601 timestamp of the replay. */\n replayedAt: string;\n /** Rate-limit state from response headers. */\n rateLimit: RateLimitState | null;\n}\n\n// ── Phase 3 offline bundle verification ───────────────────────────────────────\n\n/**\n * Result of offline evidence bundle verification via {@link verifyEvidenceBundle}.\n *\n * Named distinctly from {@link BundleVerificationResult} in `auditBundle.ts`\n * which carries chain-integrity and signature fields for audit export bundles.\n * This result covers the lighter-weight structural + hash-integrity check used\n * by the Phase 3 replay client.\n */\nexport interface EvidenceBundleVerifyResult {\n /** `true` when all checks passed. */\n valid: boolean;\n /** The `bundle_id` from the top-level bundle object, if present. */\n bundleId: string | undefined;\n /** The first `permit_id` found in the permits array (convenience). */\n permitId: string | undefined;\n /** Human-readable failure description; `undefined` when `valid` is `true`. */\n reason: string | undefined;\n}\n\n/**\n * Offline shape of an evidence bundle as returned by\n * `GET /v1/evidence-bundles/:id` and downloaded for replay verification.\n */\nexport interface OfflineEvidenceBundleData {\n bundle_id?: string;\n org_id?: string;\n status?: string;\n permits?: Array<{ permit_id?: string; evaluation_id?: string }>;\n hash_chain?: { root_hash?: string; entry_count?: number };\n [key: string]: unknown;\n}\n\n/**\n * Verify an evidence bundle offline without a backend round-trip.\n *\n * Checks:\n * 1. Bundle has required fields (`bundle_id`, `org_id`, `status`).\n * 2. `status` is `\"ready\"`.\n * 3. Root hash integrity if `hash_chain` is present (SHA-256 via Node crypto).\n *\n * Does **not** require `AtlaSentClient` or network access.\n *\n * @example\n * ```ts\n * import { verifyEvidenceBundle } from \"@atlasent/sdk\";\n *\n * const result = verifyEvidenceBundle(bundleJson);\n * if (result.valid) {\n * console.log(\"verified, first permit:\", result.permitId);\n * } else {\n * console.error(\"verification failed:\", result.reason);\n * }\n * ```\n */\nexport function verifyEvidenceBundle(\n bundle: OfflineEvidenceBundleData,\n): EvidenceBundleVerifyResult {\n if (!bundle || typeof bundle !== \"object\" || Array.isArray(bundle)) {\n return {\n valid: false,\n bundleId: undefined,\n permitId: undefined,\n reason: \"bundle must be a non-null object\",\n };\n }\n\n for (const field of [\"bundle_id\", \"org_id\", \"status\"] as const) {\n if (!(field in bundle)) {\n return {\n valid: false,\n bundleId: bundle.bundle_id,\n permitId: undefined,\n reason: `missing required field: ${field}`,\n };\n }\n }\n\n if (bundle.status !== \"ready\") {\n return {\n valid: false,\n bundleId: bundle.bundle_id,\n permitId: undefined,\n reason: `bundle status is '${bundle.status}', expected 'ready'`,\n };\n }\n\n const permits = bundle.permits ?? [];\n\n if (bundle.hash_chain?.root_hash !== undefined) {\n const computed = _computeEvidenceRootHash(permits);\n if (computed !== bundle.hash_chain.root_hash) {\n return {\n valid: false,\n bundleId: bundle.bundle_id,\n permitId: undefined,\n reason: \"root hash mismatch — bundle may have been tampered\",\n };\n }\n }\n\n return {\n valid: true,\n bundleId: bundle.bundle_id,\n permitId: permits[0]?.permit_id,\n reason: undefined,\n };\n}\n\n/**\n * Compute a deterministic SHA-256 root hash over the permits list.\n * Uses `JSON.stringify` with sorted keys via a replacer for canonical form.\n *\n * @internal\n */\nexport function _computeEvidenceRootHash(\n permits: OfflineEvidenceBundleData[\"permits\"],\n): string {\n const list = permits ?? [];\n // Sort keys deterministically at every depth using JSON + replacer pattern\n const canonical = JSON.stringify(list, (_, value) => {\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).sort(([a], [b]) =>\n a < b ? -1 : a > b ? 1 : 0,\n ),\n );\n }\n return value;\n });\n return createHash(\"sha256\").update(canonical).digest(\"hex\");\n}\n","/**\n * Human-in-the-loop (HITL) types — wire shape for `/v1/hitl/*`.\n *\n * Mirrors `supabase/functions/_shared/hitl-policy.ts` and the\n * `hitl_escalations` row shape after migration 20260507060000.\n * Treat as wire-types only: do not embed business logic that the\n * server-side resolver owns (quorum math, status transitions).\n */\n\nexport type HitlQuorumTier =\n | \"single_approver\"\n | \"simple_majority\"\n | \"two_thirds\"\n | \"unanimous\";\n\nexport type HitlStatus =\n | \"pending\"\n | \"escalated\"\n | \"approved\"\n | \"rejected\"\n | \"auto_approved\"\n | \"timed_out\";\n\nexport type HitlFallbackDecision = \"reject\" | \"approve\";\n\nexport interface HitlQuorumProgress {\n required: number;\n approved: number;\n rejected: number;\n remaining: number;\n satisfied: boolean;\n rejected_terminal: boolean;\n}\n\nexport interface HitlEscalation {\n id: string;\n org_id: string;\n agent_id: string;\n sandbox_run_id: string | null;\n status: HitlStatus;\n escalation_reason: string;\n proposed_action: Record<string, unknown> | null;\n risk_score: number | null;\n assigned_to_user_id: string | null;\n assigned_to_role: string | null;\n resolved_by: string | null;\n resolution_note: string | null;\n auto_approved_reason: string | null;\n resolved_at: string | null;\n timeout_at: string | null;\n created_at: string;\n\n quorum_required: HitlQuorumTier;\n min_approvers: number;\n approver_pool_size: number;\n escalation_depth: number;\n max_escalation_depth: number;\n fallback_decision: HitlFallbackDecision;\n governance_advisory_id: string | null;\n expired_reason: \"sla_expired\" | \"escalation_chain_exhausted\" | \"manual_expire\" | null;\n\n /**\n * Arbitrary key/value metadata attached at creation time.\n * `null` when none was provided.\n */\n metadata: Record<string, unknown> | null;\n\n quorum_progress?: HitlQuorumProgress;\n\n // Heterogeneous N-of-M extension. Empty `approver_pool` means the\n // legacy single-pool path applies (server-side resolver decides).\n approver_pool?: HitlApproverPoolEntry[];\n quorum_threshold?: number | null;\n ai_unavailable_fallback?: HitlAiUnavailableFallback;\n fallback_human_role?: string | null;\n pool_unavailable_at?: string | null;\n\n /** Populated when the server attaches a heterogeneous-quorum tally. */\n heterogeneous_tally?: HitlHeterogeneousQuorumTally;\n}\n\nexport interface HitlApprovalRecord {\n id: string;\n user_id: string | null;\n actor_label: string | null;\n decision: \"approve\" | \"reject\";\n note: string | null;\n quorum_at_vote: HitlQuorumTier;\n created_at: string;\n /** Which kind of approver cast this vote (default `\"human\"`). */\n approver_type?: HitlApproverType;\n}\n\nexport interface HitlChainHop {\n id: string;\n depth: number;\n from_user_id: string | null;\n from_role: string | null;\n to_user_id: string | null;\n to_role: string | null;\n escalated_by: string | null;\n reason: string | null;\n created_at: string;\n}\n\nexport interface ListHitlEscalationsRequest {\n status?: HitlStatus;\n agentId?: string;\n assignedToUserId?: string;\n limit?: number;\n cursor?: string;\n}\n\nexport interface ListHitlEscalationsResponse {\n escalations: HitlEscalation[];\n total: number;\n next_cursor?: string;\n}\n\n/**\n * Wire shape for `POST /v1/hitl` — open a new escalation.\n *\n * The agent-side bridge between a `hold` outcome from `protect()`\n * and the approval queue. Only `agent_id` and `escalation_reason`\n * are required; the rest map to defaults configured on the\n * server-side policy. Pass `approver_pool` to use the heterogeneous\n * N-of-M extension instead of the homogeneous quorum tier.\n */\nexport interface HitlCreateRequest {\n agent_id: string;\n escalation_reason: string;\n\n sandbox_run_id?: string;\n proposed_action?: Record<string, unknown>;\n risk_score?: number;\n assigned_to_user_id?: string;\n assigned_to_role?: string;\n\n quorum_required?: HitlQuorumTier;\n min_approvers?: number;\n approver_pool_size?: number;\n max_escalation_depth?: number;\n fallback_decision?: HitlFallbackDecision;\n timeout_at?: string;\n governance_advisory_id?: string;\n\n approver_pool?: HitlApproverPoolEntry[];\n quorum_threshold?: number;\n ai_unavailable_fallback?: HitlAiUnavailableFallback;\n fallback_human_role?: string;\n\n /** Arbitrary key/value metadata to attach to the escalation record. */\n metadata?: Record<string, unknown>;\n}\n\nexport interface HitlApproveRequest {\n note?: string;\n}\n\nexport interface HitlRejectRequest {\n note?: string;\n}\n\nexport interface HitlEscalateRequest {\n to_role?: string;\n to_user_id?: string;\n reason?: string;\n}\n\n/**\n * Wire shape for `POST /v1/escalations/:id/respond` — cast a vote on an\n * existing escalation. Mirrors the `RespondBody` schema in\n * atlasent-control-plane `api/src/routes/hitl.ts`.\n */\nexport interface HitlRespondRequest {\n /** The approver's decision. */\n decision: \"approve\" | \"reject\";\n /** Optional human-readable note attached to the approval record. */\n note?: string;\n}\n\n/**\n * Translate a quorum tier and approver-pool size to the minimum\n * number of `approve` votes required to resolve the escalation.\n *\n * Mirrors the canonical `requiredApproverCount()` in\n * atlasent-api `_shared/hitl-policy.ts` and the SQL\n * `public.hitl_required_approver_count()` helper. Provided here so\n * SDK consumers can render a \"you are the Nth of M approvers\" hint\n * without a server round-trip; the authoritative count still comes\n * from the server's `quorum_progress` payload.\n */\nexport function hitlRequiredApproverCount(\n quorum: HitlQuorumTier,\n poolSize: number,\n): number {\n const n = Number.isFinite(poolSize) && poolSize >= 1 ? Math.floor(poolSize) : 1;\n switch (quorum) {\n case \"single_approver\":\n return 1;\n case \"simple_majority\":\n return Math.floor(n / 2) + 1;\n case \"two_thirds\":\n return Math.ceil((2 * n) / 3);\n case \"unanimous\":\n return n;\n }\n}\n\n// ── Heterogeneous N-of-M quorum (migration 20260509120002) ───────────\n//\n// Mirrors the SQL `approver_pool` jsonb shape and\n// `evaluate_heterogeneous_quorum()` row shape. The legacy\n// homogeneous path (`approver_pool_size` + `quorum_required` tier) is\n// still authoritative when `approver_pool` is empty; these types\n// describe the new path only.\n\nexport type HitlApproverType =\n | \"human\"\n | \"ai_supervisor\"\n | \"automated_compliance\"\n | \"hardware_signer\"\n | \"service_account\";\n\nexport type HitlAiUnavailableFallback =\n | \"escalate_to_human\"\n | \"reduce_pool\"\n | \"fail_closed\";\n\nexport interface HitlApproverPoolEntry {\n type: HitlApproverType;\n principal_id: string;\n role?: string;\n weight?: number;\n required?: boolean;\n /** Marker for slots inserted by the AI-unavailable fallback. */\n origin?: string;\n}\n\nexport interface HitlHeterogeneousQuorumExtension {\n approver_pool: HitlApproverPoolEntry[];\n quorum_threshold: number | null;\n ai_unavailable_fallback: HitlAiUnavailableFallback;\n fallback_human_role: string | null;\n pool_unavailable_at: string | null;\n}\n\nexport interface HitlHeterogeneousQuorumTally {\n pool_size: number;\n effective_pool_size: number;\n required_threshold: number;\n approve_count: number;\n reject_count: number;\n unavailable_count: number;\n /** Per-approver-type breakdown: `{ ai_supervisor: { approve: 1, reject: 0 } }` */\n by_type: Record<HitlApproverType, { approve: number; reject: number }>;\n meets_threshold: boolean;\n any_required_reject: boolean;\n any_required_missing: boolean;\n}\n\n/**\n * Detail response returned by `GET /v1/escalations/:id`.\n *\n * Mirrors `HitlDetailResponse` in atlasent-control-plane\n * `api/src/schemas/hitl.ts`.\n */\nexport interface HitlDetailResponse {\n escalation: HitlEscalation;\n approval_records: HitlApprovalRecord[];\n}\n\n/**\n * Paginated list response returned by `GET /v1/escalations`.\n *\n * Mirrors `HitlListResponse` in atlasent-control-plane\n * `api/src/schemas/hitl.ts`.\n */\nexport interface HitlListResponse {\n escalations: HitlEscalation[];\n total: number;\n next_cursor: string | null;\n}\n","/**\n * Sandbox simulation diff — wire shape for `GET /v1/agent-sandbox/:id/diff`.\n *\n * Mirrors the `export_sandbox_diff()` SQL function added in migration\n * 20260509120000. Lets a caller render a sandbox-vs-live preview\n * before promoting a simulation to a real execution. Once a sandbox\n * run reaches a terminal status it is auto-torn-down; a follow-up\n * call returns the {@link SandboxDiffEmpty} shape so the UI can\n * surface \"this run has been finalised\" without a 404.\n */\n\nexport type SandboxRunMode =\n | \"dry_run\"\n | \"simulation\"\n | \"constrained_execution\"\n | \"production_execution\";\n\nexport type SandboxRunStatus =\n | \"pending\"\n | \"running\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\"\n | \"timed_out\";\n\nexport type SandboxWriteOp = \"insert\" | \"update\" | \"delete\";\n\nexport interface SandboxRunWrite {\n sequence: number;\n live_table: string;\n live_pk: string | null;\n op: SandboxWriteOp;\n payload_before: Record<string, unknown> | null;\n payload_after: Record<string, unknown> | null;\n metadata: Record<string, unknown>;\n created_at: string;\n}\n\nexport interface SandboxDiffPerTable {\n total: number;\n insert: number;\n update: number;\n delete: number;\n}\n\n/** Returned when staging rows are still present for the run. */\nexport interface SandboxDiff {\n simulation_run_id: string;\n org_id: string;\n final_status: SandboxRunStatus;\n mode: SandboxRunMode;\n total_writes: number;\n /** Keyed by live table name. */\n summary: Record<string, SandboxDiffPerTable>;\n writes: SandboxRunWrite[];\n}\n\n/**\n * Returned when the run has been torn down — staging rows are gone\n * and the audit-log `agent_sandbox.teardown` event is the only\n * post-mortem record.\n */\nexport interface SandboxDiffEmpty {\n simulation_run_id: string;\n status: SandboxRunStatus;\n mode: SandboxRunMode;\n torn_down: boolean;\n total_writes: 0;\n summary: Record<string, never>;\n writes: [];\n}\n\nexport type SandboxDiffResponse = SandboxDiff | SandboxDiffEmpty;\n\n/**\n * `true` when the response carries staging rows (i.e. the run has not\n * been torn down yet). Narrow before reading `summary` / `writes`.\n */\nexport function isSandboxDiffPopulated(\n r: SandboxDiffResponse,\n): r is SandboxDiff {\n return r.total_writes > 0 || (r as SandboxDiff).org_id !== undefined;\n}\n","/**\n * Delegation revocation propagation — wire shape for the\n * `propagate_delegation_revocation()` summary returned by\n * `/v1/authority-delegations/:id/revoke` (and emitted as the\n * `authority_delegation.propagated` audit event).\n *\n * Mirrors migration 20260509120001. The propagator is invoked\n * automatically on `status -> revoked` via DB trigger; consumers\n * see the summary either as the audit-event payload (asynchronous)\n * or attached to the revoke response (synchronous).\n */\n\nexport interface DelegationPropagationSummary {\n delegation_id: string;\n /** `[delegator_user_id, delegate_user_id]` — uuids as strings. */\n principals: [string, string];\n /** Phase-B role-justified delegations carry the role; user-justified\n * delegations omit it. */\n delegator_role?: string | null;\n hitl_reassigned: number;\n financial_invalidated: number;\n policies_flagged: number;\n revoked_reason?: string | null;\n}\n\n/**\n * Convenience predicate: `true` when the revocation produced any\n * downstream effect. Useful for \"are we sure?\" UI guards before\n * surfacing the summary toast.\n */\nexport function delegationPropagationHadEffect(\n s: DelegationPropagationSummary,\n): boolean {\n return (\n s.hitl_reassigned > 0 ||\n s.financial_invalidated > 0 ||\n s.policies_flagged > 0\n );\n}\n","/**\n * Context Envelope types — structured input set for execution-time\n * authorization decisions.\n *\n * These types mirror the `context_envelopes` + `context_signals` +\n * `context_namespace_registry` DB schema introduced in migration\n * `20260522070000_context_envelope_v1.sql`.\n *\n * A V1 envelope has a fixed top-level keyset (the canonical namespace\n * catalog). The recorder validates incoming envelopes against this catalog\n * and rejects unknown top-level keys in strict mode (V2+).\n */\n\n/** Canonical V1 envelope top-level namespace keys. */\nexport const CONTEXT_NAMESPACES = [\n \"intent\",\n \"actor\",\n \"resource\",\n \"environment\",\n \"history\",\n \"evidence_refs\",\n \"signals\",\n \"compatibility_overrides\",\n] as const;\n\nexport type ContextNamespaceKey = (typeof CONTEXT_NAMESPACES)[number];\n\n/** One row from `context_namespace_registry`. */\nexport interface ContextNamespaceEntry {\n namespace: ContextNamespaceKey;\n purpose: string;\n owner: string;\n /** `true` for the `signals` namespace — derived / inferred inputs. */\n is_signal: boolean;\n introduced_in_version: string;\n}\n\n/** One signal attached to a context envelope. */\nexport interface ContextSignal {\n /** Dotted path under the `signals` namespace (e.g. `\"signals.actor_anomaly\"`). */\n namespace: string;\n /** Named source that produced this signal. */\n source: string;\n /** Confidence in [0.0, 1.0]. `null` when not reported. */\n confidence: number | null;\n /** Arbitrary signal payload. */\n payload: Record<string, unknown>;\n /** ISO-8601 timestamp when the signal was produced. */\n produced_at: string;\n /** Seconds until the signal is considered stale. `null` = no expiry. */\n ttl_seconds: number | null;\n}\n\n/**\n * A canonical V1 context envelope — the deterministic input set that\n * powers execution-time authorization decisions.\n *\n * Envelopes are append-only and hash-committed: `envelope_hash` is\n * SHA-256 of the canonical JSON form. The permit issued by the evaluator\n * commits to this hash so the audit chain, the permit, and a verifier all\n * agree on what was evaluated.\n *\n * ```ts\n * import type { ContextEnvelope } from \"@atlasent/sdk\";\n *\n * const envelope: ContextEnvelope = {\n * request_id: \"req_abc123\",\n * org_id: \"org_xyz\",\n * envelope_version: \"atlasent.v1\",\n * protected_action: \"production.deploy\",\n * envelope: {\n * intent: { action: \"deploy\", summary: \"Release v1.2.0\" },\n * actor: { id: \"agent:deploy-bot\", roles: [\"deploy\"] },\n * environment: { name: \"production\", freeze_window: false },\n * },\n * envelope_hash: \"a3f...\",\n * evidence_refs: [],\n * recorded_by: \"v1-evaluate\",\n * received_at: \"2026-06-02T00:00:00Z\",\n * signals: [],\n * };\n * ```\n */\nexport interface ContextEnvelope {\n /** Caller-supplied idempotency / correlation key. */\n request_id: string;\n org_id: string;\n envelope_version: \"atlasent.v1\";\n /** The namespaced action type this envelope covers. */\n protected_action: string;\n /**\n * The full validated envelope payload. Top-level keys must be in\n * {@link CONTEXT_NAMESPACES}. Unknown keys are warn-only in V1.\n */\n envelope: Partial<Record<ContextNamespaceKey, unknown>>;\n /**\n * SHA-256 hex of `canonical-JSON(envelope)`. Three points of truth\n * (permit, audit chain, verifier) reduce to this single hash.\n */\n envelope_hash: string;\n /** UUIDs of governance evidence rows referenced by this envelope. */\n evidence_refs: string[];\n /** Which handler wrote this row (e.g. `\"v1-evaluate\"`). */\n recorded_by: string;\n /** ISO-8601 timestamp. */\n received_at: string;\n /** Signals attached to this envelope. */\n signals: ContextSignal[];\n}\n\n/**\n * Minimal input shape for recording a context envelope via\n * `context_record_envelope()`. The hash is computed by the caller\n * before submitting.\n */\nexport interface RecordContextEnvelopeInput {\n request_id: string;\n org_id: string;\n envelope_version: \"atlasent.v1\";\n protected_action: string;\n envelope: Partial<Record<ContextNamespaceKey, unknown>>;\n envelope_hash: string;\n evidence_refs?: string[];\n recorded_by?: string;\n signals?: Omit<ContextSignal, never>[];\n}\n","/**\n * Trust-root Phase 2 — hybrid snapshot bootstrap + revocation enforcement.\n *\n * Provides a lightweight TrustSnapshot type (numeric epoch timestamps,\n * JWK-array keys, flat revoked_kids list) alongside three helpers that\n * the verify() path and application code can call directly.\n *\n * Design decisions (ADR-005):\n *\n * - D3 (fail-closed expiry): isTrustSnapshotExpired() defaults to a 24-hour\n * TTL and returns true when the snapshot is older than that or when\n * expires_at has already passed. Callers in verify() must treat an expired\n * snapshot as a denial.\n *\n * - D4 (R2/R3 split): revoked_kids is a flat allowlist consulted for ANY\n * KID regardless of role. Role enforcement belongs in auditBundle.ts;\n * this module only answers \"is this KID revoked?\"\n *\n * - Bootstrap: bootstrapTrust() fetches the .well-known endpoint and merges\n * the response with an optional pinned snapshot. The pinned snapshot is\n * returned as-is if the fetch fails (silent fallback).\n *\n * - Refresh: background scheduling is handled by TrustRootManager in\n * trustRoot.ts. bootstrapTrust() is intentionally a one-shot function\n * for callers that need an explicit initial snapshot without wiring up\n * the full manager.\n */\n\n/**\n * Minimal JWK key entry as returned by the .well-known endpoint.\n *\n * Deliberately loose — additional vendor-defined fields (kid, use,\n * alg, crv, x, …) are preserved but not enumerated here so the type\n * survives forward additions to the key document.\n */\nexport interface JWK {\n /** Key identifier — used for revocation checks. */\n kid: string;\n /** Key type, e.g. \"OKP\", \"EC\", \"RSA\". */\n kty: string;\n [key: string]: unknown;\n}\n\n/**\n * Trust snapshot in the Phase 2 wire format.\n *\n * Uses numeric epoch-millisecond timestamps so callers can compare\n * directly with Date.now() without parsing ISO-8601 strings.\n */\nexport interface TrustSnapshot {\n /** Active verification keys from the trust root. */\n keys: JWK[];\n /** KIDs that have been revoked; any permit signed by these must be rejected. */\n revoked_kids: string[];\n /**\n * Unix epoch (ms) when this snapshot was fetched from the server.\n * Used as the reference point for TTL expiry checks.\n */\n fetched_at: number;\n /**\n * Unix epoch (ms) at which this snapshot expires regardless of TTL.\n * bootstrapTrust() derives this from the `valid_until` field in the\n * server response when available, otherwise from fetched_at + TTL.\n */\n expires_at: number;\n}\n\n/** Default snapshot TTL: 24 hours in milliseconds. */\nexport const DEFAULT_TRUST_TTL_MS = 24 * 60 * 60 * 1000;\n\n/** Wire shape of GET /.well-known/atlasent-verifier-keys.json */\ninterface VerifierKeysWire {\n keys?: unknown[];\n}\n\n/** Wire shape of GET /.well-known/atlasent-revocations.json */\ninterface RevocationsWire {\n revoked_keys?: Array<{ kid: string; [k: string]: unknown }>;\n}\n\n/** Wire shape of GET /.well-known/atlasent-trust-root.json */\ninterface TrustRootWire {\n valid_until?: string;\n issued_at?: string;\n}\n\n/**\n * Fetch a fresh TrustSnapshot from the AtlaSent trust-root documents.\n *\n * Fetches three documents from `${baseUrl}/.well-known/` in parallel:\n * - `atlasent-verifier-keys.json` — active verification keys\n * - `atlasent-revocations.json` — revoked KIDs\n * - `atlasent-trust-root.json` — validity window (valid_until, issued_at)\n *\n * Uses a 10-second timeout across all three fetches. On any failure\n * (network error, non-2xx, malformed response) the function returns the\n * `pinnedSnapshot` if provided, or re-throws the underlying error when no\n * fallback is available.\n *\n * The `expires_at` field is derived from the trust-root document's\n * `valid_until` field when present; otherwise it is set to\n * `fetched_at + ttlMs`.\n *\n * @param baseUrl Root URL of the AtlaSent keys host (no trailing slash).\n * @param pinnedSnapshot Optional pre-loaded snapshot to use as fallback.\n * @param ttlMs TTL for the snapshot in ms (default: 24 hours).\n * @param fetchImpl Custom fetch implementation (for tests/environments\n * without a global fetch).\n */\nexport async function bootstrapTrust(\n baseUrl: string,\n pinnedSnapshot?: TrustSnapshot,\n ttlMs: number = DEFAULT_TRUST_TTL_MS,\n fetchImpl: typeof fetch = globalThis.fetch,\n): Promise<TrustSnapshot> {\n let base = baseUrl;\n while (base.endsWith(\"/\")) base = base.slice(0, -1);\n const wk = `${base}/.well-known`;\n\n try {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 10_000);\n\n let keysRes: Response, revocRes: Response, indexRes: Response;\n try {\n [keysRes, revocRes] = await Promise.all([\n fetchImpl(`${wk}/atlasent-verifier-keys.json`, { signal: controller.signal }),\n fetchImpl(`${wk}/atlasent-revocations.json`, { signal: controller.signal }),\n ]);\n indexRes = await fetchImpl(`${wk}/atlasent-trust-root.json`, { signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n\n if (!keysRes.ok || !revocRes.ok || !indexRes.ok) {\n if (pinnedSnapshot !== undefined) return pinnedSnapshot;\n const failedStatus = !keysRes.ok\n ? keysRes.status\n : !revocRes.ok\n ? revocRes.status\n : indexRes.status;\n throw new Error(\n `bootstrapTrust: server returned HTTP ${failedStatus} from ${wk}`,\n );\n }\n\n const [keysWire, revocWire, indexWire] = await Promise.all([\n keysRes.json() as Promise<VerifierKeysWire>,\n revocRes.json() as Promise<RevocationsWire>,\n indexRes.json() as Promise<TrustRootWire>,\n ]);\n\n // Coerce keys to JWK[]: accept any array entry that has a `kid` string.\n const rawKeys: unknown[] = Array.isArray(keysWire.keys) ? keysWire.keys : [];\n const keys: JWK[] = rawKeys.filter(\n (k): k is JWK =>\n k !== null &&\n typeof k === \"object\" &&\n typeof (k as Record<string, unknown>).kid === \"string\" &&\n typeof (k as Record<string, unknown>).kty === \"string\",\n ) as JWK[];\n\n // Revoked KIDs from the dedicated revocations document.\n const revokedKids: string[] = Array.isArray(revocWire.revoked_keys)\n ? revocWire.revoked_keys\n .filter(\n (r): r is { kid: string } =>\n r !== null &&\n typeof r === \"object\" &&\n typeof (r as Record<string, unknown>).kid === \"string\",\n )\n .map((r) => r.kid)\n : [];\n\n const fetchedAt = Date.now();\n const expiresAt =\n typeof indexWire.valid_until === \"string\" && indexWire.valid_until.length > 0\n ? new Date(indexWire.valid_until).getTime()\n : fetchedAt + ttlMs;\n\n return {\n keys,\n revoked_kids: revokedKids,\n fetched_at: fetchedAt,\n expires_at: Number.isFinite(expiresAt) ? expiresAt : fetchedAt + ttlMs,\n };\n } catch (err) {\n if (pinnedSnapshot !== undefined) {\n // Silent fallback to the pinned snapshot (ADR-005 D2 refresh-failure policy).\n return pinnedSnapshot;\n }\n throw err;\n }\n}\n\n/**\n * Returns true when the snapshot should be treated as expired.\n *\n * A snapshot is expired when EITHER:\n * 1. `expires_at` is in the past, OR\n * 2. `fetched_at + ttlMs` is in the past (age-based eviction).\n *\n * The stricter of the two checks wins so a snapshot that was fetched\n * recently but carries an already-expired `expires_at` is still rejected.\n *\n * ADR-005 D3: callers in the verify() path MUST treat an expired\n * snapshot as a denial (`failClosedOnExpiry` is honoured by the client\n * integration — see verify.ts).\n *\n * @param snapshot The snapshot to check.\n * @param ttlMs Maximum age in ms from `fetched_at` (default: 24 hours).\n * @param nowMs Override for `Date.now()` (for testing).\n */\nexport function isTrustSnapshotExpired(\n snapshot: TrustSnapshot,\n ttlMs: number = DEFAULT_TRUST_TTL_MS,\n nowMs: number = Date.now(),\n): boolean {\n // Check explicit expiry timestamp\n if (nowMs > snapshot.expires_at) return true;\n // Check age-based TTL from when the snapshot was fetched\n if (nowMs > snapshot.fetched_at + ttlMs) return true;\n return false;\n}\n\n/**\n * Returns true when the given KID appears in the snapshot's revocation list.\n *\n * Used by the verify() path before accepting a permit's signature:\n * ```ts\n * if (isKidRevoked(snapshot, permit.kid)) {\n * return { valid: false, reason: 'SIGNING_KEY_REVOKED' };\n * }\n * ```\n *\n * @param snapshot Trust snapshot to consult.\n * @param kid Key identifier from the permit or audit bundle header.\n */\nexport function isKidRevoked(snapshot: TrustSnapshot, kid: string): boolean {\n return snapshot.revoked_kids.includes(kid);\n}\n","/**\n * Financial Action Model — canonical types for financial execution authority.\n *\n * Defines the core vocabulary for all financial actions governed by\n * AtlaSent's economic governance layer. Every consequential financial\n * operation must be classified here before execution authorization.\n *\n * Wire-stable as `financial_action.v1`.\n */\n\n/** ISO 4217 currency code. */\nexport type CurrencyCode =\n | \"USD\" | \"EUR\" | \"GBP\" | \"JPY\" | \"CAD\" | \"AUD\" | \"CHF\"\n | \"CNY\" | \"SEK\" | \"NZD\" | string;\n\n/**\n * Risk tier for a financial action.\n *\n * - low: < $1,000 — single-approver sufficient\n * - medium: $1,000–$50,000 — dual-control typically required\n * - high: $50,000–$1,000,000 — CFO-level required\n * - critical: > $1,000,000 or irreversible — board-level or emergency protocol\n */\nexport type FinancialRiskTier = \"low\" | \"medium\" | \"high\" | \"critical\";\n\n/** How accountability is distributed across parties for a financial action. */\nexport type LiabilityClassification =\n | \"individual\" // Single party bears full liability\n | \"shared\" // Multiple parties share liability proportionally\n | \"delegated\" // Liability flows to the delegate, not delegator\n | \"supervisory\" // Supervisors bear liability for team actions\n | \"emergency_override\"; // Special liability regime for emergency bypasses\n\n/** Canonical set of financial action types. */\nexport type FinancialActionType =\n | \"refund\"\n | \"payment_release\"\n | \"invoice_approval\"\n | \"payroll_execution\"\n | \"procurement_approval\"\n | \"wire_transfer\"\n | \"trading_execution\"\n | \"budget_override\"\n | \"spending_authorization\"\n | \"vendor_payment\"\n | \"subscription_cancellation\"\n | \"credit_issuance\"\n | \"fee_waiver\"\n | \"chargeback\"\n | \"contract_commitment\"\n | string;\n\n/**\n * Canonical definition of a financial action class.\n *\n * Stored in `financial_action_classes`. Drives quorum policy,\n * liability classification, and risk tier assignment.\n */\nexport interface FinancialActionClass {\n /** Stable identifier (e.g. \"wire_transfer.domestic\"). */\n readonly action_class_id: string;\n readonly name: string;\n readonly action_type: FinancialActionType;\n readonly risk_tier: FinancialRiskTier;\n /** Minimum number of approvals before execution is permitted. */\n readonly required_approvals: number;\n readonly liability_classification: LiabilityClassification;\n /** Whether this action is reversible post-execution. */\n readonly reversible: boolean;\n /** Maximum allowed execution value for autonomous agents (null = no ceiling). */\n readonly autonomous_ceiling: number | null;\n readonly ceiling_currency: CurrencyCode | null;\n readonly created_at: string;\n readonly description?: string;\n}\n\n/** Status of a financial execution record. */\nexport type FinancialExecutionStatus =\n | \"pending_approval\"\n | \"approved\"\n | \"executing\"\n | \"completed\"\n | \"failed\"\n | \"reversed\"\n | \"disputed\"\n | \"frozen\";\n\n/**\n * Immutable record of a financial action execution.\n *\n * Written at authorization time. Stored in `financial_execution_records`.\n */\nexport interface FinancialExecutionRecord {\n readonly execution_id: string;\n readonly action_class_id: string;\n readonly org_id: string;\n readonly action_value: number;\n readonly currency: CurrencyCode;\n readonly risk_tier: FinancialRiskTier;\n readonly liability_classification: LiabilityClassification;\n readonly initiator_id: string;\n readonly executor_id: string;\n /** Ordered list of approver IDs. */\n readonly approver_ids: readonly string[];\n /** AtlaSent permit IDs — one per approval stage. */\n readonly permit_ids: readonly string[];\n readonly override_applied: boolean;\n readonly override_id: string | null;\n readonly status: FinancialExecutionStatus;\n readonly authorized_at: string;\n readonly executed_at: string | null;\n /** Hash-chained audit trail entry. */\n readonly audit_hash: string;\n readonly context: Record<string, unknown>;\n}\n\n/** Threshold configuration for risk-tier escalation. */\nexport interface RiskTierThreshold {\n readonly tier: FinancialRiskTier;\n /** Inclusive lower bound in the reference currency. */\n readonly lower_bound: number;\n /** Exclusive upper bound; null means unbounded. */\n readonly upper_bound: number | null;\n readonly reference_currency: CurrencyCode;\n}\n\n/** Default risk tier thresholds (USD-denominated). */\nexport const DEFAULT_RISK_TIER_THRESHOLDS: readonly RiskTierThreshold[] = [\n { tier: \"low\", lower_bound: 0, upper_bound: 1_000, reference_currency: \"USD\" },\n { tier: \"medium\", lower_bound: 1_000, upper_bound: 50_000, reference_currency: \"USD\" },\n { tier: \"high\", lower_bound: 50_000, upper_bound: 1_000_000, reference_currency: \"USD\" },\n { tier: \"critical\", lower_bound: 1_000_000, upper_bound: null, reference_currency: \"USD\" },\n] as const;\n\n/**\n * Classify a financial action's risk tier based on its value.\n */\nexport function classifyRiskTier(\n value: number,\n thresholds: readonly RiskTierThreshold[] = DEFAULT_RISK_TIER_THRESHOLDS,\n): FinancialRiskTier {\n for (const t of thresholds) {\n if (value >= t.lower_bound && (t.upper_bound === null || value < t.upper_bound)) {\n return t.tier;\n }\n }\n return \"critical\";\n}\n\n/**\n * Return true when the action value is within the autonomous execution ceiling.\n * A null ceiling means no ceiling is configured (always within bounds).\n */\nexport function withinAutonomousCeiling(\n actionValue: number,\n ceiling: number | null,\n): boolean {\n if (ceiling === null) return true;\n return actionValue <= ceiling;\n}\n","/**\n * Liability Attribution Engine.\n *\n * Tracks and computes liability across the full chain of parties involved\n * in a financial action: who authorized, delegated, executed, overrode,\n * and approved exceptions.\n *\n * Supports shared, delegated, supervisory, and emergency-override liability\n * regimes. Every attribution record is immutable once written.\n *\n * Wire-stable as `liability_attribution.v1`.\n */\n\nimport type { FinancialRiskTier, LiabilityClassification } from \"./financialAction.js\";\n\n/** The role a party played in a financial action. */\nexport type LiabilityPartyRole =\n | \"authorizer\" // Granted initial authorization\n | \"delegator\" // Delegated authority to another party\n | \"delegate\" // Received delegated authority\n | \"executor\" // Performed the actual execution\n | \"approver\" // Approved at a quorum stage\n | \"override_actor\" // Applied an override or exception\n | \"supervisor\" // Bears supervisory liability for the action\n | \"exception_approver\"; // Approved a policy exception\n\n/** A single party in the liability chain. */\nexport interface LiabilityParty {\n readonly party_id: string;\n readonly party_label: string;\n readonly party_type: \"human\" | \"agent\" | \"system\";\n readonly role: LiabilityPartyRole;\n /** Fractional liability weight (0–1); all parties in chain sum to 1. */\n readonly liability_weight: number;\n readonly acted_at: string;\n readonly permit_id: string | null;\n}\n\n/**\n * Immutable liability attribution record for a financial execution.\n *\n * Stored in `liability_attribution_records`. One record per execution.\n */\nexport interface LiabilityAttributionRecord {\n readonly attribution_id: string;\n readonly execution_id: string;\n readonly org_id: string;\n readonly classification: LiabilityClassification;\n readonly risk_tier: FinancialRiskTier;\n /** Ordered liability chain. First party = primary. */\n readonly liability_chain: readonly LiabilityParty[];\n readonly delegation_present: boolean;\n readonly supervisory_present: boolean;\n readonly emergency_override: boolean;\n readonly override_justification: string | null;\n readonly created_at: string;\n /** SHA-256 hash of the canonical chain for integrity verification. */\n readonly chain_hash: string;\n}\n\n/** Input required to build a liability attribution record. */\nexport interface LiabilityAttributionInput {\n readonly execution_id: string;\n readonly org_id: string;\n readonly classification: LiabilityClassification;\n readonly risk_tier: FinancialRiskTier;\n readonly authorizer: Omit<LiabilityParty, \"role\" | \"liability_weight\">;\n readonly executor: Omit<LiabilityParty, \"role\" | \"liability_weight\">;\n readonly approvers: readonly Omit<LiabilityParty, \"role\" | \"liability_weight\">[];\n readonly delegations?: readonly {\n readonly delegator_id: string;\n readonly delegate_id: string;\n readonly delegator_label: string;\n readonly delegate_label: string;\n readonly delegator_type: \"human\" | \"agent\" | \"system\";\n readonly delegate_type: \"human\" | \"agent\" | \"system\";\n readonly permit_id: string | null;\n readonly acted_at: string;\n }[];\n readonly supervisors?: readonly Omit<LiabilityParty, \"role\" | \"liability_weight\">[];\n readonly override?: {\n readonly actor_id: string;\n readonly actor_label: string;\n readonly actor_type: \"human\" | \"agent\" | \"system\";\n readonly justification: string;\n readonly permit_id: string | null;\n readonly acted_at: string;\n };\n}\n\n/** Weight distribution strategy. */\nexport type WeightDistribution = \"equal\" | \"role_weighted\";\n\n/** Role weights for role_weighted distribution. */\nconst ROLE_WEIGHTS: Record<LiabilityPartyRole, number> = {\n authorizer: 0.30,\n delegator: 0.15,\n delegate: 0.15,\n executor: 0.25,\n approver: 0.05,\n override_actor: 0.40,\n supervisor: 0.10,\n exception_approver: 0.05,\n};\n\n/**\n * Compute liability weights for all parties in a chain.\n * Normalizes weights to sum to 1.0.\n */\nexport function computeLiabilityWeights(\n parties: readonly { role: LiabilityPartyRole }[],\n distribution: WeightDistribution = \"role_weighted\",\n): number[] {\n if (parties.length === 0) return [];\n\n let raw: number[];\n if (distribution === \"equal\") {\n raw = parties.map(() => 1);\n } else {\n raw = parties.map((p) => ROLE_WEIGHTS[p.role] ?? 0.05);\n }\n\n const total = raw.reduce((s, w) => s + w, 0);\n if (total <= 0) return parties.map(() => 1 / parties.length);\n return raw.map((w) => w / total);\n}\n\n/**\n * Build a liability chain from attribution input.\n * Assigns roles and computes normalized weights for each party.\n */\nexport function buildLiabilityChain(\n input: LiabilityAttributionInput,\n distribution: WeightDistribution = \"role_weighted\",\n): LiabilityParty[] {\n type Raw = Omit<LiabilityParty, \"liability_weight\">;\n const raw: Raw[] = [];\n\n raw.push({ ...input.authorizer, role: \"authorizer\" });\n\n for (const d of input.delegations ?? []) {\n raw.push({\n party_id: d.delegator_id,\n party_label: d.delegator_label,\n party_type: d.delegator_type,\n role: \"delegator\",\n acted_at: d.acted_at,\n permit_id: d.permit_id,\n });\n raw.push({\n party_id: d.delegate_id,\n party_label: d.delegate_label,\n party_type: d.delegate_type,\n role: \"delegate\",\n acted_at: d.acted_at,\n permit_id: d.permit_id,\n });\n }\n\n for (const a of input.approvers) {\n raw.push({ ...a, role: \"approver\" });\n }\n\n for (const s of input.supervisors ?? []) {\n raw.push({ ...s, role: \"supervisor\" });\n }\n\n raw.push({ ...input.executor, role: \"executor\" });\n\n if (input.override) {\n raw.push({\n party_id: input.override.actor_id,\n party_label: input.override.actor_label,\n party_type: input.override.actor_type,\n role: \"override_actor\",\n acted_at: input.override.acted_at,\n permit_id: input.override.permit_id,\n });\n }\n\n const weights = computeLiabilityWeights(raw, distribution);\n return raw.map((p, i) => ({ ...p, liability_weight: weights[i] ?? 0 }));\n}\n\n/**\n * Find all parties bearing primary liability (weight >= threshold).\n * Used in dispute workflows and regulatory reporting.\n */\nexport function findPrimaryLiabilityParties(\n chain: readonly LiabilityParty[],\n threshold = 0.20,\n): LiabilityParty[] {\n return chain.filter((p) => p.liability_weight >= threshold);\n}\n\n/** Result of validating a liability chain. */\nexport interface LiabilityChainValidation {\n readonly valid: boolean;\n readonly errors: readonly string[];\n}\n\n/**\n * Validate structural correctness of a liability chain:\n * - At least one party present\n * - Weights sum to ~1.0\n * - No duplicate party_id+role pairs\n * - override_actor present when hasEmergencyOverride is true\n */\nexport function validateLiabilityChain(\n chain: readonly LiabilityParty[],\n hasEmergencyOverride: boolean,\n): LiabilityChainValidation {\n const errors: string[] = [];\n\n if (chain.length === 0) {\n errors.push(\"liability chain must have at least one party\");\n }\n\n const weightSum = chain.reduce((s, p) => s + p.liability_weight, 0);\n if (Math.abs(weightSum - 1.0) > 0.01) {\n errors.push(`liability weights sum to ${weightSum.toFixed(4)}, expected 1.0`);\n }\n\n const seen = new Set<string>();\n for (const p of chain) {\n const key = `${p.party_id}:${p.role}`;\n if (seen.has(key)) errors.push(`duplicate party+role: ${key}`);\n seen.add(key);\n }\n\n if (hasEmergencyOverride && !chain.some((p) => p.role === \"override_actor\")) {\n errors.push(\"emergency_override is true but no override_actor in chain\");\n }\n\n return { valid: errors.length === 0, errors };\n}\n","/**\n * Economic Risk Engine.\n *\n * Computes financial exposure, approval concentration risk, override\n * frequency risk, budgetary drift, and execution anomaly risk for an\n * organization's financial governance posture.\n *\n * All computation is pure (no I/O). Inputs are derived from the\n * financial_execution_records and liability_attribution_records tables.\n *\n * Wire-stable as `economic_risk.v1`.\n */\n\nimport type { FinancialExecutionRecord, FinancialRiskTier } from \"./financialAction.js\";\n\n/** Aggregate financial risk score for an organization or scope. */\nexport interface FinancialRiskScore {\n readonly scope_id: string;\n /** Overall risk score (0–100; higher = riskier). */\n readonly overall_score: number;\n readonly exposure_score: number;\n readonly concentration_score: number;\n readonly override_score: number;\n readonly drift_score: number;\n readonly anomaly_score: number;\n readonly implied_tier: FinancialRiskTier;\n readonly computed_at: string;\n readonly factors: readonly RiskFactor[];\n}\n\n/** A single contributing risk factor. */\nexport interface RiskFactor {\n readonly name: string;\n readonly score: number;\n readonly weight: number;\n readonly description: string;\n readonly evidence?: readonly string[];\n}\n\n/** Alert raised when approval authority is too concentrated. */\nexport interface ConcentrationAlert {\n readonly approver_id: string;\n /** Percentage of total approvals (0–100). */\n readonly approval_share_pct: number;\n readonly total_value_approved: number;\n readonly approval_count: number;\n readonly severity: \"warn\" | \"critical\";\n readonly window_start: string;\n readonly window_end: string;\n}\n\n/** Per-approver breakdown within a concentration analysis. */\nexport interface ApproverBreakdown {\n readonly approver_id: string;\n readonly approval_count: number;\n readonly total_value: number;\n /** Share as a percentage (0–100). */\n readonly share_pct: number;\n}\n\n/** Result of approval concentration analysis. */\nexport interface ApprovalConcentrationAnalysis {\n readonly scope_id: string;\n readonly analysis_window_days: number;\n readonly total_approvals: number;\n readonly total_value: number;\n readonly approver_breakdown: readonly ApproverBreakdown[];\n readonly alerts: readonly ConcentrationAlert[];\n /** Herfindahl-Hirschman Index (0–10000). */\n readonly concentration_hhi: number;\n readonly computed_at: string;\n}\n\n/** Budgetary drift analysis for a scope/period. */\nexport interface BudgetaryDriftAnalysis {\n readonly scope_id: string;\n readonly department_id: string | null;\n readonly period_start: string;\n readonly period_end: string;\n readonly budgeted_amount: number;\n readonly actual_amount: number;\n readonly variance_amount: number;\n readonly variance_pct: number;\n readonly drift_detected: boolean;\n readonly drift_severity: \"none\" | \"minor\" | \"moderate\" | \"severe\";\n readonly override_contribution_pct: number;\n readonly unauthorized_escalation_detected: boolean;\n}\n\n/** A single execution anomaly signal. */\nexport interface ExecutionAnomaly {\n readonly anomaly_id: string;\n readonly execution_id: string;\n readonly anomaly_type: AnomalyType;\n readonly description: string;\n readonly severity: \"low\" | \"medium\" | \"high\";\n readonly detected_at: string;\n readonly evidence: Record<string, unknown>;\n}\n\n/** Known anomaly types detected by the risk engine. */\nexport type AnomalyType =\n | \"unusual_amount\" // Value significantly outside historical baseline\n | \"unusual_frequency\" // Too many executions in a short period\n | \"off_hours_execution\" // Outside normal business hours\n | \"rapid_sequential\" // Rapid sequential approvals (rubber-stamping signal)\n | \"self_approval\" // Initiator and approver are the same party\n | \"jurisdiction_mismatch\" // Currency/amount inconsistent with counterparty locale\n | \"dormant_approver\" // Approver who hasn't approved in a long time\n | \"velocity_spike\" // Sudden spike in total daily value\n | string;\n\n/** Sub-score weights for overall risk computation. */\nconst SCORE_WEIGHTS = {\n exposure: 0.25,\n concentration: 0.25,\n override: 0.20,\n drift: 0.15,\n anomaly: 0.15,\n} as const;\n\n/**\n * Compute the overall financial risk score from sub-scores.\n * Returns a value in [0, 100].\n */\nexport function computeOverallRiskScore(subScores: {\n exposure: number;\n concentration: number;\n override: number;\n drift: number;\n anomaly: number;\n}): number {\n return Math.min(\n 100,\n Math.max(\n 0,\n subScores.exposure * SCORE_WEIGHTS.exposure +\n subScores.concentration * SCORE_WEIGHTS.concentration +\n subScores.override * SCORE_WEIGHTS.override +\n subScores.drift * SCORE_WEIGHTS.drift +\n subScores.anomaly * SCORE_WEIGHTS.anomaly,\n ),\n );\n}\n\n/**\n * Infer a risk tier from an overall score.\n * 0–25: low | 26–55: medium | 56–80: high | 81–100: critical\n */\nexport function scoreToRiskTier(score: number): FinancialRiskTier {\n if (score <= 25) return \"low\";\n if (score <= 55) return \"medium\";\n if (score <= 80) return \"high\";\n return \"critical\";\n}\n\n/**\n * Compute the Herfindahl-Hirschman Index from a list of shares (0–100 each).\n * HHI > 2500 indicates high concentration.\n */\nexport function computeHHI(shares: readonly number[]): number {\n return shares.reduce((acc, s) => acc + s * s, 0);\n}\n\n/** Map HHI (0–10000) to a concentration score (0–100). */\nexport function hhiToConcentrationScore(hhi: number): number {\n return Math.min(100, (hhi / 10_000) * 100);\n}\n\n/**\n * Compute an exposure score (0–100) from execution records.\n * Total active-state value as a fraction of a reference ceiling.\n */\nexport function computeExposureScore(\n records: readonly Pick<FinancialExecutionRecord, \"action_value\" | \"status\" | \"risk_tier\">[],\n exposureCeilingUSD = 10_000_000,\n): number {\n const activeStatuses = new Set<FinancialExecutionRecord[\"status\"]>(\n [\"pending_approval\", \"approved\", \"executing\"],\n );\n const totalExposure = records\n .filter((r) => activeStatuses.has(r.status))\n .reduce((acc, r) => acc + r.action_value, 0);\n return Math.min(100, (totalExposure / exposureCeilingUSD) * 100);\n}\n\n/**\n * Compute an override frequency score (0–100).\n * More than 10% override rate → score = 100.\n */\nexport function computeOverrideScore(\n totalExecutions: number,\n overriddenExecutions: number,\n): number {\n if (totalExecutions === 0) return 0;\n const rate = overriddenExecutions / totalExecutions;\n return Math.min(100, rate * 1000); // 10% rate maps to 100\n}\n\n/**\n * Detect self-approval: initiator and approver are the same party.\n */\nexport function detectSelfApproval(\n initiatorId: string,\n approverIds: readonly string[],\n): boolean {\n return approverIds.includes(initiatorId);\n}\n\n/** Compute an approval risk score from concentration analysis. */\nexport function computeApprovalRiskScore(analysis: ApprovalConcentrationAnalysis): number {\n return hhiToConcentrationScore(analysis.concentration_hhi);\n}\n","/**\n * Financial Quorum — extends the AtlaSent approval quorum model with\n * monetary thresholds, dynamic escalation, and emergency freeze support.\n *\n * Builds on the base QuorumPolicy in approvalQuorum.ts. Every financial\n * quorum check MUST first satisfy base quorum requirements before\n * financial-layer policy is evaluated.\n *\n * Wire-stable as `financial_quorum.v1`.\n */\n\nimport type { QuorumPolicy, QuorumProof } from \"./approvalQuorum.js\";\nimport type { CurrencyCode, FinancialRiskTier } from \"./financialAction.js\";\n\n/** A financial role requirement with optional monetary and tier filters. */\nexport interface FinancialRoleRequirement {\n readonly role: string;\n readonly min: number;\n /** Only apply this requirement when action value >= this amount. */\n readonly applies_above?: number;\n /** Only apply when the action's risk_tier is in this set. */\n readonly applies_to_tiers?: readonly FinancialRiskTier[];\n}\n\n/** Amount-based threshold that triggers additional quorum requirements. */\nexport interface AmountThreshold {\n readonly value: number;\n readonly currency: CurrencyCode;\n readonly additional_approvals: number;\n readonly additional_roles: readonly FinancialRoleRequirement[];\n readonly senior_review_required: boolean;\n}\n\n/**\n * Financial quorum policy.\n *\n * Extends the base QuorumPolicy with amount thresholds, financial role\n * requirements, regulator approval thresholds, and emergency freeze.\n */\nexport interface FinancialQuorumPolicy extends QuorumPolicy {\n readonly financial_role_requirements: readonly FinancialRoleRequirement[];\n readonly amount_thresholds: readonly AmountThreshold[];\n readonly reference_currency: CurrencyCode;\n readonly emergency_freeze_active: boolean;\n /** Regulator approval required above this value (null = not required). */\n readonly regulator_approval_threshold: number | null;\n /** Customer + vendor dual-release required above this value. */\n readonly dual_release_threshold: number | null;\n}\n\n/** Emergency freeze record — applied org-wide or per scope. */\nexport interface EmergencyFreeze {\n readonly freeze_id: string;\n readonly scope_id: string;\n readonly scope_type: \"org\" | \"department\" | \"action_class\";\n readonly triggered_by: string;\n readonly reason: string;\n readonly triggered_at: string;\n readonly expires_at: string | null;\n readonly lifted: boolean;\n readonly lifted_at: string | null;\n readonly lifted_by: string | null;\n}\n\n/** Result of evaluating a financial quorum. */\nexport interface FinancialQuorumResult {\n readonly passed: boolean;\n readonly base_quorum_passed: boolean;\n readonly amount_threshold_satisfied: boolean;\n readonly financial_roles_satisfied: boolean;\n readonly regulator_approval_missing: boolean;\n readonly blocked_by_freeze: boolean;\n readonly base_quorum_proof: QuorumProof | null;\n readonly denial_reason: string | null;\n readonly unmet_requirements: readonly string[];\n}\n\n/** Input to financial quorum evaluation. */\nexport interface FinancialQuorumInput {\n readonly policy: FinancialQuorumPolicy;\n readonly action_value: number;\n readonly risk_tier: FinancialRiskTier;\n /** Roles present in the approval set (role → count). */\n readonly present_roles: Record<string, number>;\n readonly approval_count: number;\n readonly regulator_approval_present: boolean;\n readonly base_quorum_proof: QuorumProof | null;\n readonly active_freezes: readonly EmergencyFreeze[];\n}\n\n/**\n * Evaluate a financial quorum policy.\n *\n * Checks in order: emergency freeze → base count → amount thresholds\n * → financial roles → regulator approval.\n */\nexport function evaluateFinancialQuorum(input: FinancialQuorumInput): FinancialQuorumResult {\n const unmet: string[] = [];\n\n // Hard block: emergency freeze\n const activeFreeze = input.active_freezes.find((f) => !f.lifted);\n if (activeFreeze) {\n return {\n passed: false,\n base_quorum_passed: false,\n amount_threshold_satisfied: false,\n financial_roles_satisfied: false,\n regulator_approval_missing: false,\n blocked_by_freeze: true,\n base_quorum_proof: null,\n denial_reason: `action blocked by emergency freeze (${activeFreeze.freeze_id}): ${activeFreeze.reason}`,\n unmet_requirements: [`emergency_freeze:${activeFreeze.freeze_id}`],\n };\n }\n\n // Base quorum\n const baseQuorumPassed =\n input.base_quorum_proof !== null ||\n input.approval_count >= input.policy.required_count;\n if (!baseQuorumPassed) {\n unmet.push(\n `base quorum requires ${input.policy.required_count} approvals, have ${input.approval_count}`,\n );\n }\n\n // Amount threshold escalation\n let amountThresholdSatisfied = true;\n for (const threshold of input.policy.amount_thresholds) {\n if (input.action_value >= threshold.value) {\n const needed = input.policy.required_count + threshold.additional_approvals;\n if (input.approval_count < needed) {\n amountThresholdSatisfied = false;\n unmet.push(\n `amount threshold ${threshold.value} ${threshold.currency} requires ${needed} approvals`,\n );\n }\n for (const req of threshold.additional_roles) {\n const present = input.present_roles[req.role] ?? 0;\n if (present < req.min) {\n amountThresholdSatisfied = false;\n unmet.push(`amount threshold requires ${req.min} ${req.role} approver(s), have ${present}`);\n }\n }\n if (threshold.senior_review_required && !(input.present_roles[\"senior_finance\"] ?? 0)) {\n amountThresholdSatisfied = false;\n unmet.push(\"amount threshold requires senior_finance review\");\n }\n }\n }\n\n // Financial role requirements\n let financialRolesSatisfied = true;\n for (const req of input.policy.financial_role_requirements) {\n if (req.applies_to_tiers && !req.applies_to_tiers.includes(input.risk_tier)) continue;\n if (req.applies_above !== undefined && input.action_value < req.applies_above) continue;\n const present = input.present_roles[req.role] ?? 0;\n if (present < req.min) {\n financialRolesSatisfied = false;\n unmet.push(`financial role ${req.role} requires ${req.min} approver(s), have ${present}`);\n }\n }\n\n // Regulator approval\n const regulatorMissing =\n input.policy.regulator_approval_threshold !== null &&\n input.action_value >= input.policy.regulator_approval_threshold &&\n !input.regulator_approval_present;\n if (regulatorMissing) {\n unmet.push(\"regulator approval required for this action value\");\n }\n\n const passed =\n baseQuorumPassed &&\n amountThresholdSatisfied &&\n financialRolesSatisfied &&\n !regulatorMissing;\n\n return {\n passed,\n base_quorum_passed: baseQuorumPassed,\n amount_threshold_satisfied: amountThresholdSatisfied,\n financial_roles_satisfied: financialRolesSatisfied,\n regulator_approval_missing: regulatorMissing,\n blocked_by_freeze: false,\n base_quorum_proof: input.base_quorum_proof,\n denial_reason: passed ? null : (unmet[0] ?? \"financial quorum not satisfied\"),\n unmet_requirements: unmet,\n };\n}\n\n/**\n * Determine the escalated minimum approval count for a given action value.\n * Returns base count plus the largest additional_approvals from matching thresholds.\n */\nexport function computeEscalatedApprovalCount(\n baseCount: number,\n actionValue: number,\n thresholds: readonly AmountThreshold[],\n): number {\n let additional = 0;\n for (const t of thresholds) {\n if (actionValue >= t.value) {\n additional = Math.max(additional, t.additional_approvals);\n }\n }\n return baseCount + additional;\n}\n","/**\n * Budgetary Governance — policy and constraint infrastructure for\n * organizational financial limits.\n *\n * Prevents budget overruns, unauthorized escalations, and hidden approvals\n * by enforcing declared spending constraints before financial actions\n * are authorized.\n *\n * Wire-stable as `budget_governance.v1`.\n */\n\nimport type { CurrencyCode, FinancialActionType, FinancialRiskTier } from \"./financialAction.js\";\n\n/** Scope a budget limit applies to. */\nexport type BudgetScope =\n | \"org\" // Entire organization\n | \"department\" // Named department\n | \"team\" // Named team within a department\n | \"environment\" // Deployment environment (prod, staging, etc.)\n | \"action_class\" // Specific financial action class\n | \"project\" // Project or cost center code\n | \"time_bounded\"; // Time-bounded budget (sprint, quarter, etc.)\n\n/** A declared budget limit for a scope. */\nexport interface BudgetLimit {\n readonly limit_id: string;\n readonly org_id: string;\n readonly scope_type: BudgetScope;\n readonly scope_id: string;\n readonly limit_amount: number;\n readonly currency: CurrencyCode;\n /** Hard limits block execution; soft limits warn only. */\n readonly enforcement: \"hard\" | \"soft\";\n readonly period_start: string | null;\n readonly period_end: string | null;\n readonly active: boolean;\n readonly created_by: string;\n readonly created_at: string;\n}\n\n/** Current spending state against a budget limit. */\nexport interface BudgetSpendingState {\n readonly limit_id: string;\n readonly spent_amount: number;\n readonly remaining_amount: number;\n readonly exceeded: boolean;\n /** Utilization percentage (0–100+). */\n readonly utilization_pct: number;\n readonly updated_at: string;\n}\n\n/** A spending constraint on a financial action class or type. */\nexport interface SpendingConstraint {\n readonly constraint_id: string;\n readonly org_id: string;\n /** \"*\" matches all action types. */\n readonly action_type: FinancialActionType | \"*\";\n readonly max_single_transaction: number;\n readonly max_daily_aggregate: number | null;\n readonly max_monthly_aggregate: number | null;\n readonly currency: CurrencyCode;\n readonly applies_to_tier_gte: FinancialRiskTier | null;\n readonly allow_anonymous_agents: boolean;\n readonly active: boolean;\n}\n\n/** A specific budget violation. */\nexport interface BudgetViolation {\n readonly violation_type:\n | \"limit_exceeded\"\n | \"single_transaction_exceeds\"\n | \"daily_aggregate_exceeds\"\n | \"monthly_aggregate_exceeds\"\n | \"anonymous_agent_blocked\"\n | \"period_expired\";\n readonly limit_id?: string;\n readonly constraint_id?: string;\n readonly description: string;\n readonly overage_amount?: number;\n}\n\n/** Result of checking an action against budget constraints. */\nexport interface BudgetConstraintCheckResult {\n readonly permitted: boolean;\n readonly hard_blocks: readonly BudgetViolation[];\n readonly soft_warnings: readonly BudgetViolation[];\n readonly limits_checked: readonly string[];\n readonly constraints_checked: readonly string[];\n}\n\n/** A complete budget policy document for an organization. */\nexport interface BudgetPolicy {\n readonly policy_id: string;\n readonly org_id: string;\n readonly name: string;\n readonly limits: readonly BudgetLimit[];\n readonly constraints: readonly SpendingConstraint[];\n readonly override_requires_exception: boolean;\n readonly allow_approved_escalation: boolean;\n readonly version: string;\n readonly effective_from: string;\n readonly expires_at: string | null;\n}\n\n/**\n * Check an action value against applicable budget limits and constraints.\n *\n * Hard limits block execution; soft limits surface as warnings.\n */\nexport function checkBudgetConstraints(params: {\n actionValue: number;\n currency: CurrencyCode;\n actionType: FinancialActionType;\n riskTier: FinancialRiskTier;\n isAnonymousAgent: boolean;\n currentDailySpend: number;\n currentMonthlySpend: number;\n applicableLimits: readonly (BudgetLimit & { spending: BudgetSpendingState })[];\n applicableConstraints: readonly SpendingConstraint[];\n now?: Date;\n}): BudgetConstraintCheckResult {\n const hardBlocks: BudgetViolation[] = [];\n const softWarnings: BudgetViolation[] = [];\n const limitsChecked: string[] = [];\n const constraintsChecked: string[] = [];\n const nowIso = (params.now ?? new Date()).toISOString();\n\n for (const limit of params.applicableLimits) {\n limitsChecked.push(limit.limit_id);\n\n if (limit.period_end && nowIso > limit.period_end) {\n const v: BudgetViolation = {\n violation_type: \"period_expired\",\n limit_id: limit.limit_id,\n description: `Budget limit ${limit.limit_id} period expired at ${limit.period_end}`,\n };\n if (limit.enforcement === \"hard\") hardBlocks.push(v); else softWarnings.push(v);\n continue;\n }\n\n const projected = limit.spending.spent_amount + params.actionValue;\n if (projected > limit.limit_amount) {\n const v: BudgetViolation = {\n violation_type: \"limit_exceeded\",\n limit_id: limit.limit_id,\n description: `Action would exceed ${limit.scope_type} limit (${limit.limit_amount} ${limit.currency})`,\n overage_amount: projected - limit.limit_amount,\n };\n if (limit.enforcement === \"hard\") hardBlocks.push(v); else softWarnings.push(v);\n }\n }\n\n for (const constraint of params.applicableConstraints) {\n constraintsChecked.push(constraint.constraint_id);\n\n if (constraint.action_type !== \"*\" && constraint.action_type !== params.actionType) continue;\n\n if (!constraint.allow_anonymous_agents && params.isAnonymousAgent) {\n hardBlocks.push({\n violation_type: \"anonymous_agent_blocked\",\n constraint_id: constraint.constraint_id,\n description: `Anonymous agents are not permitted to execute ${params.actionType}`,\n });\n }\n\n if (params.actionValue > constraint.max_single_transaction) {\n hardBlocks.push({\n violation_type: \"single_transaction_exceeds\",\n constraint_id: constraint.constraint_id,\n description: `Value ${params.actionValue} exceeds single-transaction limit ${constraint.max_single_transaction} ${constraint.currency}`,\n overage_amount: params.actionValue - constraint.max_single_transaction,\n });\n }\n\n if (\n constraint.max_daily_aggregate !== null &&\n params.currentDailySpend + params.actionValue > constraint.max_daily_aggregate\n ) {\n hardBlocks.push({\n violation_type: \"daily_aggregate_exceeds\",\n constraint_id: constraint.constraint_id,\n description: `Action would exceed daily aggregate limit ${constraint.max_daily_aggregate} ${constraint.currency}`,\n overage_amount: params.currentDailySpend + params.actionValue - constraint.max_daily_aggregate,\n });\n }\n\n if (\n constraint.max_monthly_aggregate !== null &&\n params.currentMonthlySpend + params.actionValue > constraint.max_monthly_aggregate\n ) {\n hardBlocks.push({\n violation_type: \"monthly_aggregate_exceeds\",\n constraint_id: constraint.constraint_id,\n description: `Action would exceed monthly aggregate limit ${constraint.max_monthly_aggregate} ${constraint.currency}`,\n overage_amount: params.currentMonthlySpend + params.actionValue - constraint.max_monthly_aggregate,\n });\n }\n }\n\n return {\n permitted: hardBlocks.length === 0,\n hard_blocks: hardBlocks,\n soft_warnings: softWarnings,\n limits_checked: limitsChecked,\n constraints_checked: constraintsChecked,\n };\n}\n\n/**\n * Determine budget utilization severity for dashboard display.\n */\nexport function budgetUtilizationSeverity(\n utilizationPct: number,\n): \"normal\" | \"warn\" | \"critical\" {\n if (utilizationPct >= 100) return \"critical\";\n if (utilizationPct >= 80) return \"warn\";\n return \"normal\";\n}\n","/**\n * Autonomous Financial Execution — governance for AI-driven financial actions.\n *\n * Defines bounded authority, execution ceilings, and runtime verification\n * requirements for autonomous agents performing financial operations:\n * refunds, procurement, cloud-cost optimization, vendor payments, etc.\n *\n * Wire-stable as `autonomous_financial.v1`.\n */\n\nimport type { CurrencyCode, FinancialActionType, FinancialRiskTier } from \"./financialAction.js\";\n\n/** Authority bounds for an autonomous financial agent. */\nexport interface AutonomousExecutionBounds {\n readonly bounds_id: string;\n readonly org_id: string;\n readonly agent_id: string;\n readonly agent_name: string;\n /** Action types this agent is permitted to execute autonomously. */\n readonly permitted_action_types: readonly FinancialActionType[];\n readonly ceilings: readonly ExecutionCeiling[];\n readonly daily_aggregate_ceiling: number;\n readonly aggregate_currency: CurrencyCode;\n /** Maximum risk tier the agent may autonomously execute. */\n readonly max_risk_tier: FinancialRiskTier;\n readonly require_runtime_verification: boolean;\n readonly anomaly_detection_enabled: boolean;\n readonly created_at: string;\n readonly expires_at: string | null;\n readonly active: boolean;\n}\n\n/** Per-action-type execution ceiling. */\nexport interface ExecutionCeiling {\n readonly action_type: FinancialActionType;\n readonly per_execution_max: number;\n readonly currency: CurrencyCode;\n readonly max_daily_count: number | null;\n readonly require_permit: boolean;\n}\n\n/** Record of an autonomous execution attempt. */\nexport interface AutonomousExecutionRecord {\n readonly record_id: string;\n readonly agent_id: string;\n readonly org_id: string;\n readonly action_type: FinancialActionType;\n readonly action_value: number;\n readonly currency: CurrencyCode;\n readonly permitted: boolean;\n readonly denial_reason: string | null;\n readonly permit_id: string | null;\n readonly anomaly_detected: boolean;\n readonly anomaly_description: string | null;\n readonly attempted_at: string;\n readonly executed_at: string | null;\n}\n\n/** Result of checking whether an autonomous execution is within bounds. */\nexport interface AutonomousExecutionCheckResult {\n readonly permitted: boolean;\n readonly action_type_permitted: boolean;\n readonly within_execution_ceiling: boolean;\n readonly within_daily_aggregate: boolean;\n readonly within_risk_tier: boolean;\n readonly bounds_active: boolean;\n readonly bounds_not_expired: boolean;\n readonly applicable_ceiling: ExecutionCeiling | null;\n readonly denial_reason: string | null;\n readonly violations: readonly string[];\n}\n\nconst RISK_TIER_ORDER: Record<FinancialRiskTier, number> = {\n low: 1,\n medium: 2,\n high: 3,\n critical: 4,\n};\n\n/**\n * Check whether an autonomous execution is within declared bounds.\n */\nexport function checkAutonomousBounds(params: {\n bounds: AutonomousExecutionBounds;\n actionType: FinancialActionType;\n actionValue: number;\n currency: CurrencyCode;\n riskTier: FinancialRiskTier;\n currentDailyAggregate: number;\n currentDailyCount: Partial<Record<string, number>>;\n now?: Date;\n}): AutonomousExecutionCheckResult {\n const violations: string[] = [];\n const nowIso = (params.now ?? new Date()).toISOString();\n\n const boundsActive = params.bounds.active;\n if (!boundsActive) violations.push(\"agent execution bounds are inactive\");\n\n const boundsNotExpired =\n params.bounds.expires_at === null || params.bounds.expires_at > nowIso;\n if (!boundsNotExpired) {\n violations.push(`agent bounds expired at ${params.bounds.expires_at}`);\n }\n\n const actionTypePermitted = (params.bounds.permitted_action_types as string[]).includes(\n params.actionType,\n );\n if (!actionTypePermitted) {\n violations.push(`action type ${params.actionType} not in agent's permitted set`);\n }\n\n const applicableCeiling =\n params.bounds.ceilings.find((c) => c.action_type === params.actionType) ?? null;\n\n let withinExecutionCeiling = true;\n if (applicableCeiling !== null) {\n if (params.actionValue > applicableCeiling.per_execution_max) {\n withinExecutionCeiling = false;\n violations.push(\n `value ${params.actionValue} exceeds per-execution ceiling ${applicableCeiling.per_execution_max} ${applicableCeiling.currency}`,\n );\n }\n if (applicableCeiling.max_daily_count !== null) {\n const todayCount = params.currentDailyCount[params.actionType] ?? 0;\n if (todayCount >= applicableCeiling.max_daily_count) {\n withinExecutionCeiling = false;\n violations.push(\n `daily count ${todayCount} at or exceeds limit ${applicableCeiling.max_daily_count} for ${params.actionType}`,\n );\n }\n }\n }\n\n const withinDailyAggregate =\n params.currentDailyAggregate + params.actionValue <= params.bounds.daily_aggregate_ceiling;\n if (!withinDailyAggregate) {\n violations.push(\n `daily aggregate ${params.currentDailyAggregate + params.actionValue} would exceed ceiling ${params.bounds.daily_aggregate_ceiling} ${params.bounds.aggregate_currency}`,\n );\n }\n\n const withinRiskTier =\n RISK_TIER_ORDER[params.riskTier] <= RISK_TIER_ORDER[params.bounds.max_risk_tier];\n if (!withinRiskTier) {\n violations.push(\n `action risk tier ${params.riskTier} exceeds agent max ${params.bounds.max_risk_tier}`,\n );\n }\n\n const permitted =\n boundsActive &&\n boundsNotExpired &&\n actionTypePermitted &&\n withinExecutionCeiling &&\n withinDailyAggregate &&\n withinRiskTier;\n\n return {\n permitted,\n action_type_permitted: actionTypePermitted,\n within_execution_ceiling: withinExecutionCeiling,\n within_daily_aggregate: withinDailyAggregate,\n within_risk_tier: withinRiskTier,\n bounds_active: boundsActive,\n bounds_not_expired: boundsNotExpired,\n applicable_ceiling: applicableCeiling,\n denial_reason: permitted ? null : (violations[0] ?? \"execution out of bounds\"),\n violations,\n };\n}\n\n/**\n * Detect a potential anomaly in autonomous execution.\n * Returns a description when an anomaly is detected, or null.\n */\nexport function detectAutonomousAnomaly(params: {\n actionValue: number;\n historicalMeanValue: number;\n historicalStdDev: number;\n recentExecutionCount: number;\n burstThreshold: number;\n isOffHours: boolean;\n}): { anomalyDetected: boolean; description: string | null } {\n const zScore =\n params.historicalStdDev > 0\n ? Math.abs(params.actionValue - params.historicalMeanValue) / params.historicalStdDev\n : 0;\n\n if (zScore > 3) {\n return {\n anomalyDetected: true,\n description: `action value ${params.actionValue} is ${zScore.toFixed(1)}σ from mean (${params.historicalMeanValue})`,\n };\n }\n\n if (params.recentExecutionCount > params.burstThreshold) {\n return {\n anomalyDetected: true,\n description: `execution burst: ${params.recentExecutionCount} in window (threshold: ${params.burstThreshold})`,\n };\n }\n\n if (params.isOffHours && params.actionValue > params.historicalMeanValue * 2) {\n return {\n anomalyDetected: true,\n description: `off-hours execution with above-average value ${params.actionValue}`,\n };\n }\n\n return { anomalyDetected: false, description: null };\n}\n","/**\n * Incentive Alignment Engine.\n *\n * Detects governance anti-patterns that indicate misaligned incentives:\n * excessive overrides, rushed approvals, emergency bypass repetition,\n * authority concentration, and governance fatigue.\n *\n * These signals are leading indicators of systemic governance failure.\n * They do not block execution but feed into risk scoring and dashboards.\n *\n * Wire-stable as `incentive_alignment.v1`.\n */\n\n/** Categories of governance incentive signals. */\nexport type IncentiveSignalType =\n | \"excessive_overrides\"\n | \"rushed_approval\"\n | \"emergency_bypass_repeat\"\n | \"authority_concentration\"\n | \"rubber_stamping\"\n | \"approval_collusion\"\n | \"escalation_avoidance\"\n | \"governance_fatigue\"\n | \"delegation_chain_depth\"\n | \"approval_velocity_spike\";\n\n/** A detected incentive alignment signal. */\nexport interface IncentiveSignal {\n readonly signal_id: string;\n readonly signal_type: IncentiveSignalType;\n readonly party_id: string;\n readonly party_label: string;\n /** Severity (0–100). */\n readonly severity: number;\n readonly description: string;\n readonly evidence: readonly string[];\n readonly detected_at: string;\n readonly reviewed: boolean;\n readonly reviewed_by: string | null;\n}\n\n/** Behavior pattern analysis for a governance actor. */\nexport interface GovernanceBehaviorPattern {\n readonly party_id: string;\n readonly party_label: string;\n readonly observation_window_days: number;\n readonly total_approvals: number;\n readonly total_overrides: number;\n readonly total_emergency_bypasses: number;\n readonly mean_approval_latency_seconds: number;\n readonly min_approval_latency_seconds: number;\n readonly approval_concentration_score: number;\n readonly delegation_depth_max: number;\n readonly signals: readonly IncentiveSignal[];\n /** 0–100; higher = healthier governance posture. */\n readonly governance_health_score: number;\n}\n\n/** Misalignment alert for operator review. */\nexport interface MisalignmentAlert {\n readonly alert_id: string;\n readonly org_id: string;\n readonly severity: \"warn\" | \"critical\";\n readonly alert_type: IncentiveSignalType;\n readonly affected_party_ids: readonly string[];\n readonly description: string;\n readonly recommendation: string;\n readonly signals: readonly IncentiveSignal[];\n readonly created_at: string;\n readonly resolved: boolean;\n readonly resolved_at: string | null;\n}\n\n/** Thresholds for incentive alignment detection. */\nexport interface IncentiveAlignmentConfig {\n readonly max_override_rate: number;\n readonly min_approval_latency_seconds: number;\n readonly max_emergency_bypasses_30d: number;\n readonly max_concentration_share: number;\n readonly max_delegation_depth: number;\n}\n\nexport const DEFAULT_INCENTIVE_CONFIG: IncentiveAlignmentConfig = {\n max_override_rate: 0.05,\n min_approval_latency_seconds: 30,\n max_emergency_bypasses_30d: 3,\n max_concentration_share: 0.40,\n max_delegation_depth: 3,\n};\n\n/**\n * Analyze a governance actor's behavior to detect misaligned incentives.\n * Returns signals sorted by severity (highest first).\n */\nexport function detectMisalignedIncentives(params: {\n partyId: string;\n partyLabel: string;\n windowDays: number;\n totalActions: number;\n overrideCount: number;\n emergencyBypassCount: number;\n approvalLatencies: readonly number[];\n approvalShare: number;\n delegationDepthMax: number;\n config?: IncentiveAlignmentConfig;\n now?: Date;\n}): IncentiveSignal[] {\n const config = params.config ?? DEFAULT_INCENTIVE_CONFIG;\n const signals: IncentiveSignal[] = [];\n const now = (params.now ?? new Date()).toISOString();\n let signalIdx = 0;\n const makeId = () => `signal_${params.partyId}_${signalIdx++}`;\n\n // Excessive overrides\n const overrideRate = params.totalActions > 0 ? params.overrideCount / params.totalActions : 0;\n if (overrideRate > config.max_override_rate) {\n signals.push({\n signal_id: makeId(),\n signal_type: \"excessive_overrides\",\n party_id: params.partyId,\n party_label: params.partyLabel,\n severity: Math.min(100, (overrideRate / config.max_override_rate) * 50),\n description: `Override rate ${(overrideRate * 100).toFixed(1)}% exceeds threshold ${(config.max_override_rate * 100).toFixed(1)}%`,\n evidence: [`override_count:${params.overrideCount}`, `total_actions:${params.totalActions}`],\n detected_at: now,\n reviewed: false,\n reviewed_by: null,\n });\n }\n\n // Emergency bypass repeat\n if (params.emergencyBypassCount > config.max_emergency_bypasses_30d) {\n signals.push({\n signal_id: makeId(),\n signal_type: \"emergency_bypass_repeat\",\n party_id: params.partyId,\n party_label: params.partyLabel,\n severity: Math.min(100, (params.emergencyBypassCount / config.max_emergency_bypasses_30d) * 60),\n description: `${params.emergencyBypassCount} emergency bypasses in ${params.windowDays}d (threshold: ${config.max_emergency_bypasses_30d})`,\n evidence: [`bypass_count:${params.emergencyBypassCount}`],\n detected_at: now,\n reviewed: false,\n reviewed_by: null,\n });\n }\n\n // Rushed approvals\n const rushCount = params.approvalLatencies.filter((l) => l < config.min_approval_latency_seconds).length;\n if (rushCount > 0 && params.approvalLatencies.length > 0) {\n const minLatency = Math.min(...params.approvalLatencies);\n const rushRate = rushCount / params.approvalLatencies.length;\n signals.push({\n signal_id: makeId(),\n signal_type: \"rushed_approval\",\n party_id: params.partyId,\n party_label: params.partyLabel,\n severity: Math.min(100, rushRate * 80),\n description: `${rushCount} approvals in under ${config.min_approval_latency_seconds}s (min observed: ${minLatency.toFixed(0)}s)`,\n evidence: [`rushed_count:${rushCount}`, `total_approvals:${params.approvalLatencies.length}`],\n detected_at: now,\n reviewed: false,\n reviewed_by: null,\n });\n }\n\n // Authority concentration\n if (params.approvalShare > config.max_concentration_share) {\n signals.push({\n signal_id: makeId(),\n signal_type: \"authority_concentration\",\n party_id: params.partyId,\n party_label: params.partyLabel,\n severity: Math.min(100, (params.approvalShare / config.max_concentration_share) * 50),\n description: `Party controls ${(params.approvalShare * 100).toFixed(1)}% of approvals (threshold: ${(config.max_concentration_share * 100).toFixed(1)}%)`,\n evidence: [`approval_share:${params.approvalShare.toFixed(3)}`],\n detected_at: now,\n reviewed: false,\n reviewed_by: null,\n });\n }\n\n // Deep delegation chains\n if (params.delegationDepthMax > config.max_delegation_depth) {\n signals.push({\n signal_id: makeId(),\n signal_type: \"delegation_chain_depth\",\n party_id: params.partyId,\n party_label: params.partyLabel,\n severity: Math.min(100, ((params.delegationDepthMax - config.max_delegation_depth) / config.max_delegation_depth) * 60),\n description: `Delegation depth ${params.delegationDepthMax} exceeds threshold ${config.max_delegation_depth}`,\n evidence: [`depth:${params.delegationDepthMax}`],\n detected_at: now,\n reviewed: false,\n reviewed_by: null,\n });\n }\n\n return signals.sort((a, b) => b.severity - a.severity);\n}\n\n/**\n * Compute a governance health score (0–100).\n * 100 = perfect governance; 0 = extreme misalignment.\n */\nexport function computeGovernanceHealthScore(signals: readonly IncentiveSignal[]): number {\n if (signals.length === 0) return 100;\n const totalPenalty = signals.reduce((acc, s) => acc + s.severity * 0.5, 0);\n return Math.max(0, 100 - totalPenalty);\n}\n","/**\n * Economic Evidence Bundles.\n *\n * Generates signed evidence proving approval provenance, execution\n * authorization, runtime conformity, liability chain, and policy compliance\n * for regulatory review, insurance, financial audit, and legal discovery.\n *\n * Follows the same signing pattern as auditBundle.ts, scoped to financial\n * governance evidence.\n *\n * Wire-stable as `economic_evidence.v1`.\n */\n\nimport type { FinancialExecutionRecord } from \"./financialAction.js\";\nimport type { LiabilityAttributionRecord } from \"./liabilityAttribution.js\";\nimport type { FinancialQuorumResult } from \"./financialQuorum.js\";\nimport type { BudgetConstraintCheckResult } from \"./budgetaryGovernance.js\";\n\n/** Purpose for which an economic evidence bundle is generated. */\nexport type EvidencePurpose =\n | \"regulator_review\"\n | \"insurance_review\"\n | \"financial_audit\"\n | \"legal_discovery\"\n | \"internal_review\"\n | \"dispute_resolution\";\n\n/** Approval provenance record within the evidence bundle. */\nexport interface ApprovalProvenance {\n readonly approver_id: string;\n readonly approver_label: string;\n readonly permit_id: string;\n readonly approved_at: string;\n readonly audit_hash: string;\n readonly role: string;\n}\n\n/** Complete economic evidence bundle. */\nexport interface EconomicEvidenceBundle {\n readonly version: \"economic_evidence.v1\";\n readonly bundle_id: string;\n readonly org_id: string;\n readonly purpose: EvidencePurpose;\n readonly execution_record: FinancialExecutionRecord;\n readonly liability_attribution: LiabilityAttributionRecord;\n readonly quorum_result: FinancialQuorumResult;\n readonly budget_check: BudgetConstraintCheckResult;\n readonly approval_provenance: readonly ApprovalProvenance[];\n readonly runtime_conformity: boolean;\n readonly runtime_conformity_notes: readonly string[];\n readonly policy_compliant: boolean;\n readonly policy_violations: readonly string[];\n readonly generated_at: string;\n readonly requested_by: string;\n /** SHA-256 hex of the canonical signable content. */\n readonly content_hash: string;\n /** Base64url Ed25519 signature of the canonical content. */\n readonly signature: string | null;\n readonly signing_key_id: string | null;\n}\n\n/** Canonical content shape that gets hashed and signed. */\nexport interface EvidenceBundleSignableContent {\n readonly bundle_id: string;\n readonly org_id: string;\n readonly purpose: EvidencePurpose;\n readonly execution_id: string;\n readonly attribution_id: string;\n readonly liability_chain_hash: string;\n readonly approval_count: number;\n readonly permit_ids: readonly string[];\n readonly policy_compliant: boolean;\n readonly generated_at: string;\n}\n\n/** Verification result for an economic evidence bundle. */\nexport interface EvidenceBundleVerificationResult {\n readonly valid: boolean;\n readonly content_hash_valid: boolean;\n readonly signature_valid: boolean;\n readonly liability_chain_hash_matches: boolean;\n readonly permit_ids_match: boolean;\n readonly reason: string | null;\n}\n\n/**\n * Canonicalize a value to a stable string representation.\n *\n * Exported (rather than file-private) to enable cross-language\n * byte-equivalence verification against the Python implementation in\n * ``atlasent-sdk/python/atlasent/governance/_canonical.py``. The shared\n * fixture lives at ``compat/governance/fixtures/parity.json``.\n */\nexport function canonicalizeForEvidence(value: unknown): string {\n if (value === null || value === undefined) return \"null\";\n if (typeof value === \"number\") return Number.isFinite(value) ? String(value) : \"null\";\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n if (typeof value === \"string\") return JSON.stringify(value);\n if (Array.isArray(value)) return \"[\" + value.map(canonicalizeForEvidence).join(\",\") + \"]\";\n if (typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n return \"{\" + keys.map((k) => JSON.stringify(k) + \":\" + canonicalizeForEvidence(obj[k])).join(\",\") + \"}\";\n }\n return \"null\";\n}\n\n/**\n * Build the signable content object for a bundle.\n * Key order is load-bearing — must remain stable across versions.\n */\nexport function buildSignableContent(\n bundle: Omit<EconomicEvidenceBundle, \"content_hash\" | \"signature\" | \"signing_key_id\">,\n): EvidenceBundleSignableContent {\n return {\n bundle_id: bundle.bundle_id,\n org_id: bundle.org_id,\n purpose: bundle.purpose,\n execution_id: bundle.execution_record.execution_id,\n attribution_id: bundle.liability_attribution.attribution_id,\n liability_chain_hash: bundle.liability_attribution.chain_hash,\n approval_count: bundle.approval_provenance.length,\n permit_ids: bundle.approval_provenance.map((a) => a.permit_id),\n policy_compliant: bundle.policy_compliant,\n generated_at: bundle.generated_at,\n };\n}\n\n/**\n * Serialize signable content to canonical UTF-8 bytes.\n * Uses the same sort-keyed canonicalization as auditBundle.\n */\nexport function serializeSignableContent(\n content: EvidenceBundleSignableContent,\n): Uint8Array {\n return new TextEncoder().encode(canonicalizeForEvidence(content));\n}\n\n/**\n * Verify an economic evidence bundle's structural integrity.\n * Does NOT verify the Ed25519 signature (requires crypto keys).\n */\nexport function verifyEvidenceBundleStructure(\n bundle: EconomicEvidenceBundle,\n): EvidenceBundleVerificationResult {\n const errors: string[] = [];\n\n // Permit ID consistency between provenance and execution record\n const bundlePermitIds = new Set(bundle.execution_record.permit_ids);\n const provenancePermitIds = bundle.approval_provenance.map((a) => a.permit_id);\n const permitIdsMatch = provenancePermitIds.every((id) => bundlePermitIds.has(id));\n if (!permitIdsMatch) {\n errors.push(\"permit IDs in approval provenance do not all appear in execution record\");\n }\n\n // Content hash format check (SHA-256 hex = 64 chars)\n const contentHashValid = typeof bundle.content_hash === \"string\" && bundle.content_hash.length === 64;\n if (!contentHashValid) errors.push(\"content_hash appears invalid (expected 64-char hex)\");\n\n // Liability chain hash presence\n const liabilityChainHashMatches =\n typeof bundle.liability_attribution.chain_hash === \"string\" &&\n bundle.liability_attribution.chain_hash.length > 0;\n if (!liabilityChainHashMatches) errors.push(\"liability_attribution.chain_hash is missing or empty\");\n\n const signatureValid = bundle.signature !== null && bundle.signature.length > 0;\n\n return {\n valid: errors.length === 0 && contentHashValid,\n content_hash_valid: contentHashValid,\n signature_valid: signatureValid,\n liability_chain_hash_matches: liabilityChainHashMatches,\n permit_ids_match: permitIdsMatch,\n reason: errors.length === 0 ? null : errors[0] ?? \"bundle integrity check failed\",\n };\n}\n","/**\n * Dispute + Reversal Workflows.\n *\n * Manages disputed financial actions, rollback workflows, frozen actions,\n * and temporary suspensions. Tracks dispute origin, remediation timeline,\n * and reversal authority.\n *\n * Wire-stable as `dispute_reversal.v1`.\n */\n\nimport type { FinancialExecutionStatus } from \"./financialAction.js\";\n\n/** Who or what originated a dispute. */\nexport type DisputeOrigin =\n | \"counterparty\" // External counterparty challenged the action\n | \"regulator\" // Regulatory body flagged the action\n | \"internal_audit\" // Internal audit team\n | \"fraud_detection\" // Automated fraud detection\n | \"approver_retract\" // An approver retracted their approval\n | \"policy_violation\" // Policy violation detected post-execution\n | \"agent_error\"; // Autonomous agent error\n\n/** Current state of a dispute. */\nexport type DisputeStatus =\n | \"open\"\n | \"under_review\"\n | \"escalated\"\n | \"resolved_in_favor\"\n | \"resolved_against\"\n | \"reversed\"\n | \"withdrawn\";\n\n/** A dispute record for a financial action. */\nexport interface DisputeRecord {\n readonly dispute_id: string;\n readonly execution_id: string;\n readonly org_id: string;\n readonly origin: DisputeOrigin;\n readonly filed_by: string;\n readonly description: string;\n readonly status: DisputeStatus;\n readonly execution_frozen: boolean;\n readonly opened_at: string;\n readonly resolution_deadline: string | null;\n readonly resolved_at: string | null;\n readonly resolved_by: string | null;\n readonly resolution_notes: string | null;\n readonly reversal_initiated: boolean;\n readonly reversal_id: string | null;\n}\n\n/** Reversal workflow stage. */\nexport type ReversalStage =\n | \"initiated\"\n | \"authorization_pending\"\n | \"authorized\"\n | \"executing\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\";\n\n/** A reversal workflow for a financial execution. */\nexport interface ReversalWorkflow {\n readonly reversal_id: string;\n readonly execution_id: string;\n readonly dispute_id: string | null;\n readonly org_id: string;\n readonly initiated_by: string;\n readonly reason: string;\n readonly stage: ReversalStage;\n readonly authorized_by: string | null;\n readonly authorization_permit_id: string | null;\n readonly initiated_at: string;\n readonly authorized_at: string | null;\n readonly completed_at: string | null;\n readonly reversal_value: number;\n readonly partial: boolean;\n}\n\n/** Action freeze record. */\nexport interface ActionFreeze {\n readonly freeze_id: string;\n readonly execution_id: string;\n readonly org_id: string;\n readonly triggered_by: string;\n readonly reason: string;\n readonly triggered_at: string;\n readonly expires_at: string | null;\n readonly lifted: boolean;\n readonly lifted_at: string | null;\n readonly lifted_by: string | null;\n readonly frozen_status: FinancialExecutionStatus;\n}\n\nconst VALID_DISPUTE_TRANSITIONS: Record<DisputeStatus, readonly DisputeStatus[]> = {\n open: [\"under_review\", \"withdrawn\"],\n under_review: [\"escalated\", \"resolved_in_favor\", \"resolved_against\", \"reversed\"],\n escalated: [\"resolved_in_favor\", \"resolved_against\", \"reversed\"],\n resolved_in_favor: [],\n resolved_against: [],\n reversed: [],\n withdrawn: [],\n};\n\n/** Validate and apply a dispute status transition. */\nexport function transitionDispute(\n current: DisputeStatus,\n next: DisputeStatus,\n): { success: boolean; new_status: DisputeStatus | null; error: string | null } {\n const allowed = VALID_DISPUTE_TRANSITIONS[current];\n if (!allowed.includes(next)) {\n return { success: false, new_status: null, error: `invalid dispute transition: ${current} → ${next}` };\n }\n return { success: true, new_status: next, error: null };\n}\n\nconst VALID_REVERSAL_TRANSITIONS: Record<ReversalStage, readonly ReversalStage[]> = {\n initiated: [\"authorization_pending\", \"cancelled\"],\n authorization_pending: [\"authorized\", \"cancelled\"],\n authorized: [\"executing\", \"cancelled\"],\n executing: [\"completed\", \"failed\"],\n completed: [],\n failed: [\"initiated\"], // Allow retry\n cancelled: [],\n};\n\n/** Validate and apply a reversal workflow stage transition. */\nexport function transitionReversal(\n current: ReversalStage,\n next: ReversalStage,\n): { success: boolean; error: string | null } {\n const allowed = VALID_REVERSAL_TRANSITIONS[current];\n if (!allowed.includes(next)) {\n return { success: false, error: `invalid reversal transition: ${current} → ${next}` };\n }\n return { success: true, error: null };\n}\n\n/**\n * Return true when a freeze is currently active (not lifted and not expired).\n */\nexport function isFreezeActive(freeze: ActionFreeze, now?: Date): boolean {\n if (freeze.lifted) return false;\n if (freeze.expires_at !== null) {\n const nowIso = (now ?? new Date()).toISOString();\n if (nowIso >= freeze.expires_at) return false;\n }\n return true;\n}\n\n/**\n * Compute remediation urgency based on dispute deadline.\n * Returns 'overdue' when past deadline, 'urgent' within 24h, else 'normal'.\n */\nexport function computeRemediationUrgency(\n _openedAt: string,\n deadline: string | null,\n now?: Date,\n): \"normal\" | \"urgent\" | \"overdue\" {\n if (deadline === null) return \"normal\";\n const nowMs = (now ?? new Date()).getTime();\n const deadlineMs = new Date(deadline).getTime();\n const remaining = deadlineMs - nowMs;\n if (remaining < 0) return \"overdue\";\n if (remaining < 24 * 60 * 60 * 1000) return \"urgent\";\n return \"normal\";\n}\n","/**\n * Financial Control Dashboard — types for governance visualization.\n *\n * Covers approval concentration analysis, override analytics, budget drift,\n * economic risk timelines, and liability visualization.\n *\n * These are pure data types; rendering is left to UI consumers.\n *\n * Wire-stable as `financial_dashboard.v1`.\n */\n\nimport type { FinancialRiskTier } from \"./financialAction.js\";\nimport type { ApprovalConcentrationAnalysis, BudgetaryDriftAnalysis, FinancialRiskScore } from \"./economicRisk.js\";\nimport type { MisalignmentAlert } from \"./incentiveAlignment.js\";\nimport type { LiabilityParty } from \"./liabilityAttribution.js\";\nimport type { DisputeRecord, ReversalWorkflow } from \"./disputeReversal.js\";\n\n/** Top-level financial governance summary for a dashboard view. */\nexport interface FinancialGovernanceSummary {\n readonly org_id: string;\n readonly generated_at: string;\n readonly window_days: number;\n readonly current_risk_score: FinancialRiskScore;\n readonly total_actions: number;\n readonly total_value: number;\n readonly override_count: number;\n readonly emergency_bypass_count: number;\n readonly active_dispute_count: number;\n readonly pending_reversal_count: number;\n readonly active_freeze_count: number;\n readonly budget_warning_count: number;\n readonly budget_critical_count: number;\n readonly concentration_analysis: ApprovalConcentrationAnalysis;\n readonly budget_drift: readonly BudgetaryDriftAnalysis[];\n readonly misalignment_alerts: readonly MisalignmentAlert[];\n readonly risk_timeline: readonly RiskTimelinePoint[];\n}\n\n/** A single point on the economic risk timeline. */\nexport interface RiskTimelinePoint {\n readonly date: string;\n readonly risk_score: number;\n readonly risk_tier: FinancialRiskTier;\n readonly action_count: number;\n readonly total_value: number;\n readonly override_count: number;\n readonly anomaly_count: number;\n}\n\n/** Override analytics for operator review. */\nexport interface OverrideAnalytics {\n readonly org_id: string;\n readonly window_days: number;\n readonly total_overrides: number;\n readonly override_rate: number;\n readonly overrides_by_actor: readonly ActorOverrideStat[];\n readonly overrides_by_action_type: readonly ActionTypeOverrideStat[];\n readonly override_value_total: number;\n readonly repeat_override_actors: readonly string[];\n readonly emergency_override_count: number;\n readonly computed_at: string;\n}\n\nexport interface ActorOverrideStat {\n readonly actor_id: string;\n readonly actor_label: string;\n readonly override_count: number;\n readonly override_value_total: number;\n readonly last_override_at: string;\n}\n\nexport interface ActionTypeOverrideStat {\n readonly action_type: string;\n readonly override_count: number;\n readonly total_value: number;\n}\n\n/** Liability visualization data for graph/chart rendering. */\nexport interface LiabilityVisualization {\n readonly execution_id: string;\n readonly org_id: string;\n readonly nodes: readonly LiabilityNode[];\n readonly edges: readonly LiabilityEdge[];\n readonly total_weight: number;\n}\n\nexport interface LiabilityNode {\n readonly id: string;\n readonly label: string;\n readonly party_type: \"human\" | \"agent\" | \"system\";\n readonly role: string;\n readonly liability_weight: number;\n readonly acted_at: string;\n}\n\nexport interface LiabilityEdge {\n readonly from_id: string;\n readonly to_id: string;\n readonly relationship: \"authorized\" | \"delegated_to\" | \"approved_for\" | \"supervised\" | \"overrode\";\n readonly weight: number;\n}\n\n/** Active disputes and reversals dashboard summary. */\nexport interface DisputeReversalSummary {\n readonly org_id: string;\n readonly active_disputes: readonly DisputeRecord[];\n readonly pending_reversals: readonly ReversalWorkflow[];\n readonly resolved_last_30d: number;\n readonly average_resolution_days: number;\n readonly overdue_disputes: readonly DisputeRecord[];\n readonly total_disputed_value: number;\n readonly total_reversed_value: number;\n readonly generated_at: string;\n}\n\n/**\n * Build a liability visualization graph from a liability chain.\n */\nexport function buildLiabilityVisualization(\n executionId: string,\n orgId: string,\n chain: readonly LiabilityParty[],\n): LiabilityVisualization {\n const nodes: LiabilityNode[] = chain.map((p) => ({\n id: p.party_id,\n label: p.party_label,\n party_type: p.party_type,\n role: p.role,\n liability_weight: p.liability_weight,\n acted_at: p.acted_at,\n }));\n\n const edges: LiabilityEdge[] = [];\n for (let i = 0; i < chain.length - 1; i++) {\n const from = chain[i]!;\n const to = chain[i + 1]!;\n let relationship: LiabilityEdge[\"relationship\"] = \"authorized\";\n if (from.role === \"delegator\" && to.role === \"delegate\") relationship = \"delegated_to\";\n else if (from.role === \"supervisor\") relationship = \"supervised\";\n else if (to.role === \"approver\") relationship = \"approved_for\";\n else if (to.role === \"override_actor\") relationship = \"overrode\";\n edges.push({\n from_id: from.party_id,\n to_id: to.party_id,\n relationship,\n weight: Math.min(from.liability_weight, to.liability_weight),\n });\n }\n\n return {\n execution_id: executionId,\n org_id: orgId,\n nodes,\n edges,\n total_weight: chain.reduce((s, p) => s + p.liability_weight, 0),\n };\n}\n\n/**\n * Build a risk timeline from daily snapshot data.\n */\nexport function buildRiskTimeline(\n snapshots: readonly {\n date: string;\n riskScore: number;\n actionCount: number;\n totalValue: number;\n overrideCount: number;\n anomalyCount: number;\n }[],\n): RiskTimelinePoint[] {\n return snapshots.map((s) => {\n let tier: FinancialRiskTier = \"low\";\n if (s.riskScore > 80) tier = \"critical\";\n else if (s.riskScore > 55) tier = \"high\";\n else if (s.riskScore > 25) tier = \"medium\";\n return {\n date: s.date,\n risk_score: s.riskScore,\n risk_tier: tier,\n action_count: s.actionCount,\n total_value: s.totalValue,\n override_count: s.overrideCount,\n anomaly_count: s.anomalyCount,\n };\n });\n}\n","/**\n * Enforcement-layer helpers for the canonical economic governance primitives.\n *\n * The canonical EGAS modules (`financialQuorum`, `liabilityAttribution`,\n * `economicEvidence`, `budgetaryGovernance`, `autonomousFinancial`) are\n * **advisory**: they produce structured decision objects but never block\n * execution. This module converts \"not permitted\" advisory results into\n * thrown {@link GovernanceEnforcementError} so callers cannot silently\n * proceed when a governance gate refuses an action.\n *\n * Three gates, layered in this order at consumer call sites:\n *\n * ```ts\n * enforceFinancialQuorum(quorumResult);\n * enforceBudgetConstraint(budgetResult);\n * enforceAutonomousBounds(autonomousResult);\n * ```\n *\n * Each helper is a no-op when its result is permitted; otherwise it throws\n * with a stable {@link GovernanceEnforcementError.denyCode} matching a row\n * in `docs/APPROVAL_DENY_REASONS.md`. The deny-code taxonomy is locked\n * cross-language by the parity fixture at\n * `compat/governance/fixtures/parity.json`.\n */\n\nimport { AtlaSentError, type AtlaSentErrorInit } from \"./errors.js\";\nimport type { AutonomousExecutionCheckResult } from \"./autonomousFinancial.js\";\nimport type { BudgetConstraintCheckResult } from \"./budgetaryGovernance.js\";\nimport type { FinancialQuorumResult } from \"./financialQuorum.js\";\n\n/** Which enforcement gate fired. */\nexport type GovernanceGate = \"financial_quorum\" | \"budget\" | \"autonomous_bounds\";\n\n/** Stable deny codes for the financial-quorum gate. */\nexport type FinancialQuorumDenyCode =\n | \"blocked_by_emergency_freeze\"\n | \"base_count_unmet\"\n | \"amount_threshold_unmet\"\n | \"financial_role_unmet\"\n | \"regulator_approval_missing\";\n\n/** Stable deny codes for the budget gate. */\nexport type BudgetDenyCode =\n | \"limit_exceeded\"\n | \"single_transaction_exceeds\"\n | \"daily_aggregate_exceeds\"\n | \"monthly_aggregate_exceeds\"\n | \"anonymous_agent_blocked\"\n | \"period_expired\";\n\n/** Stable deny codes for the autonomous-bounds gate. */\nexport type AutonomousBoundsDenyCode =\n | \"inactive\"\n | \"expired\"\n | \"action_type_not_permitted\"\n | \"execution_ceiling_exceeded\"\n | \"daily_aggregate_exceeded\"\n | \"risk_tier_exceeded\";\n\n/** Initialization options for {@link GovernanceEnforcementError}. */\nexport interface GovernanceEnforcementErrorInit {\n gate: GovernanceGate;\n denyCode: string;\n reason: string;\n details: unknown;\n requestId?: string;\n}\n\n/**\n * Thrown when an EGAS advisory result fails an enforcement gate.\n *\n * Extends {@link AtlaSentError} so `instanceof AtlaSentError` catches\n * these too. Use `instanceof GovernanceEnforcementError` to distinguish\n * a governance refusal from a transport / config error.\n */\nexport class GovernanceEnforcementError extends AtlaSentError {\n override name: string = \"GovernanceEnforcementError\";\n\n /** Which gate fired (`financial_quorum` / `budget` / `autonomous_bounds`). */\n readonly gate: GovernanceGate;\n /** Stable taxonomy code; maps to a row in `docs/APPROVAL_DENY_REASONS.md`. */\n readonly denyCode: string;\n /** Human-readable explanation. Do NOT branch on this string — branch on `denyCode`. */\n readonly reason: string;\n /** The structured advisory result that produced the denial. */\n readonly details: unknown;\n\n constructor(init: GovernanceEnforcementErrorInit) {\n const errInit: AtlaSentErrorInit = { code: \"forbidden\" };\n if (init.requestId !== undefined) errInit.requestId = init.requestId;\n super(`[${init.gate}/${init.denyCode}] ${init.reason}`, errInit);\n this.gate = init.gate;\n this.denyCode = init.denyCode;\n this.reason = init.reason;\n this.details = init.details;\n }\n\n /** Combined `<gate>/<denyCode>` string used in audit records. */\n get fullyQualifiedCode(): string {\n return `${this.gate}/${this.denyCode}`;\n }\n}\n\n// ─── financial_quorum ─────────────────────────────────────────────────\n\nfunction financialQuorumDenyCode(\n result: FinancialQuorumResult,\n): FinancialQuorumDenyCode {\n // Order matches evaluateFinancialQuorum so first-failing-gate wins\n // produces the same code in TS and Python.\n if (result.blocked_by_freeze) return \"blocked_by_emergency_freeze\";\n if (!result.base_quorum_passed) return \"base_count_unmet\";\n if (!result.amount_threshold_satisfied) return \"amount_threshold_unmet\";\n if (!result.financial_roles_satisfied) return \"financial_role_unmet\";\n if (result.regulator_approval_missing) return \"regulator_approval_missing\";\n // Defensive fallback; unreachable when result.passed is false.\n return \"base_count_unmet\";\n}\n\n/**\n * Throw {@link GovernanceEnforcementError} when a quorum result fails.\n * Returns silently when `result.passed` is true.\n */\nexport function enforceFinancialQuorum(result: FinancialQuorumResult): void {\n if (result.passed) return;\n const denyCode = financialQuorumDenyCode(result);\n throw new GovernanceEnforcementError({\n gate: \"financial_quorum\",\n denyCode,\n reason: result.denial_reason ?? `financial quorum failed: ${denyCode}`,\n details: result,\n });\n}\n\n// ─── budget ─────────────────────────────────────────────────────────────────\n\n/**\n * Throw {@link GovernanceEnforcementError} on a budget hard block.\n *\n * Returns silently when `result.permitted` is true (no hard blocks; soft\n * warnings do not cause enforcement to fire).\n */\nexport function enforceBudgetConstraint(result: BudgetConstraintCheckResult): void {\n if (result.permitted) return;\n if (result.hard_blocks.length === 0) {\n // Defensive: permitted=false without a hard block is a contract bug.\n throw new GovernanceEnforcementError({\n gate: \"budget\",\n denyCode: \"limit_exceeded\",\n reason: \"budget enforcement failed without a structured violation\",\n details: result,\n });\n }\n const first = result.hard_blocks[0]!;\n throw new GovernanceEnforcementError({\n gate: \"budget\",\n denyCode: first.violation_type,\n reason: first.description,\n details: result,\n });\n}\n\n// ─── autonomous_bounds ────────────────────────────────────────────────────\n\nfunction autonomousBoundsDenyCode(\n result: AutonomousExecutionCheckResult,\n): AutonomousBoundsDenyCode {\n // Order matches checkAutonomousBounds.\n if (!result.bounds_active) return \"inactive\";\n if (!result.bounds_not_expired) return \"expired\";\n if (!result.action_type_permitted) return \"action_type_not_permitted\";\n if (!result.within_execution_ceiling) return \"execution_ceiling_exceeded\";\n if (!result.within_daily_aggregate) return \"daily_aggregate_exceeded\";\n if (!result.within_risk_tier) return \"risk_tier_exceeded\";\n return \"inactive\";\n}\n\n/**\n * Throw {@link GovernanceEnforcementError} when autonomous bounds fail.\n * Returns silently when `result.permitted` is true.\n */\nexport function enforceAutonomousBounds(\n result: AutonomousExecutionCheckResult,\n): void {\n if (result.permitted) return;\n const denyCode = autonomousBoundsDenyCode(result);\n throw new GovernanceEnforcementError({\n gate: \"autonomous_bounds\",\n denyCode,\n reason:\n result.denial_reason ??\n `autonomous execution out of bounds: ${denyCode}`,\n details: result,\n });\n}\n\n/**\n * Convenience: layer all three gates in canonical order.\n *\n * Order: quorum (who approved) → budget (does it fit policy spend) →\n * autonomous_bounds (is the agent allowed to do this autonomously). The\n * first failing gate throws; subsequent gates are not evaluated.\n *\n * Pass `undefined` for gates that don't apply (e.g. omit `autonomous` for\n * human-initiated actions).\n */\nexport function enforceEconomicGovernance(params: {\n quorum?: FinancialQuorumResult;\n budget?: BudgetConstraintCheckResult;\n autonomous?: AutonomousExecutionCheckResult;\n}): void {\n if (params.quorum !== undefined) enforceFinancialQuorum(params.quorum);\n if (params.budget !== undefined) enforceBudgetConstraint(params.budget);\n if (params.autonomous !== undefined) enforceAutonomousBounds(params.autonomous);\n}\n","/**\n * Governance and enforcement webhook types — wire shapes for\n * `v1-governance-webhooks` and `v1-enforcement-webhooks`.\n *\n * Covers subscription management, signed delivery callbacks, and\n * delivery receipt records. Use `verifyWebhookSignature` in your\n * receiver to authenticate payloads.\n */\n\nexport type GovernanceWebhookEvent =\n | \"enforcement.blocked\"\n | \"policy.violation\"\n | \"access_review.completed\"\n | \"mfa.enrollment_required\"\n | \"contract.activated\"\n | \"replay.drift_detected\";\n\nexport type EnforcementWebhookEvent =\n | \"enforcement.blocked\"\n | \"enforcement.pending_approval\"\n | \"enforcement.approved\"\n | \"enforcement.expired\";\n\nexport type WebhookDeliveryStatus = \"pending\" | \"delivered\" | \"failed\";\n\nexport interface WebhookSubscription {\n id: string;\n org_id: string;\n url: string;\n events: string[];\n enabled: boolean;\n description: string | null;\n created_at: string;\n}\n\nexport interface WebhookDelivery {\n id: string;\n subscription_id: string;\n event_type: string;\n payload: Record<string, unknown>;\n status: WebhookDeliveryStatus;\n response_status: number | null;\n response_body: string | null;\n attempted_at: string;\n}\n\nexport interface CreateWebhookSubscriptionRequest {\n url: string;\n events: string[];\n enabled?: boolean;\n description?: string;\n}\n\nexport interface ListWebhookSubscriptionsResponse {\n subscriptions: WebhookSubscription[];\n /** For governance webhooks, the server returns supported event names. */\n valid_events?: string[];\n}\n\nexport interface ListWebhookDeliveriesResponse {\n deliveries: WebhookDelivery[];\n}\n\n/**\n * Signed webhook payload delivered to subscriber endpoints.\n *\n * AtlaSent sets two headers on every delivery:\n * - `X-AtlaSent-Signature: sha256=<hex>` — HMAC-SHA256 of the raw body\n * - `X-AtlaSent-Event: <event_type>`\n *\n * Verify with `verifyWebhookSignature` before processing.\n */\nexport interface WebhookPayload<T = Record<string, unknown>> {\n id: string;\n org_id: string;\n event_type: string;\n source_id: string | null;\n data: T;\n created_at: string;\n}\n\n/**\n * Verify a webhook delivery signature using the subscription secret.\n *\n * Performs a constant-time HMAC-SHA256 comparison so timing attacks\n * cannot reveal secret length. Requires `globalThis.crypto.subtle`\n * (Node 20+, all modern browsers, Deno, Cloudflare Workers).\n *\n * @param payload Raw UTF-8 request body string.\n * @param signature Value of the `X-AtlaSent-Signature` header.\n * @param secret Webhook subscription secret from the AtlaSent console.\n * @returns `true` when the signature is valid.\n *\n * @example\n * ```ts\n * import { verifyWebhookSignature } from \"@atlasent/sdk\";\n *\n * app.post(\"/webhook\", async (req, res) => {\n * const ok = await verifyWebhookSignature(\n * req.rawBody,\n * req.headers[\"x-atlasent-signature\"],\n * process.env.WEBHOOK_SECRET!,\n * );\n * if (!ok) return res.status(401).send(\"invalid signature\");\n * // process req.body …\n * });\n * ```\n */\nexport async function verifyWebhookSignature(\n payload: string,\n signature: string,\n secret: string,\n): Promise<boolean> {\n const prefix = \"sha256=\";\n if (!signature.startsWith(prefix)) return false;\n const receivedHex = signature.slice(prefix.length);\n\n const encoder = new TextEncoder();\n const key = await crypto.subtle.importKey(\n \"raw\",\n encoder.encode(secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n const sigBuffer = await crypto.subtle.sign(\"HMAC\", key, encoder.encode(payload));\n const expectedHex = Array.from(new Uint8Array(sigBuffer))\n .map(b => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n\n if (receivedHex.length !== expectedHex.length) return false;\n let diff = 0;\n for (let i = 0; i < expectedHex.length; i++) {\n diff |= receivedHex.charCodeAt(i) ^ expectedHex.charCodeAt(i);\n }\n return diff === 0;\n}\n","/**\n * Compliance evidence types — wire shapes for `v1-compliance-evidence`.\n *\n * Supports on-demand SOC 2 Type II control evidence collection. The\n * same run shape is used for ISO 27001, GDPR, and HIPAA; control IDs\n * differ per framework.\n */\n\nexport type ComplianceFramework = \"soc2\" | \"iso27001\" | \"gdpr\" | \"hipaa\";\n\nexport type EvidenceControlStatus = \"pass\" | \"gap\" | \"finding\";\n\nexport type ComplianceRunStatus =\n | \"pending\"\n | \"running\"\n | \"completed\"\n | \"failed\";\n\n/**\n * A single evaluated control within an evidence run.\n * `evidence` is a free-form object whose keys are framework-specific\n * metric names (e.g. `mfa_enforced_policies`, `audit_events_last_30d`).\n */\nexport interface EvidenceControl {\n control_id: string;\n title: string;\n status: EvidenceControlStatus;\n evidence: Record<string, unknown>;\n}\n\nexport interface ComplianceEvidenceSummary {\n total: number;\n pass: number;\n gap: number;\n finding: number;\n}\n\nexport interface ComplianceEvidenceRun {\n id: string;\n org_id: string;\n framework: ComplianceFramework;\n period_start: string;\n period_end: string;\n status: ComplianceRunStatus;\n controls: EvidenceControl[];\n summary: ComplianceEvidenceSummary | null;\n applied_by: string | null;\n created_at: string;\n}\n\nexport interface TriggerEvidenceRunRequest {\n framework: ComplianceFramework;\n /** ISO 8601 date string; defaults to 30 days ago on the server. */\n period_start?: string;\n /** ISO 8601 date string; defaults to now on the server. */\n period_end?: string;\n}\n\nexport interface TriggerEvidenceRunResponse {\n run: ComplianceEvidenceRun;\n}\n\nexport interface ListEvidenceRunsResponse {\n runs: ComplianceEvidenceRun[];\n}\n\n/**\n * SOC 2 control IDs evaluated by `v1-compliance-evidence`.\n *\n * | ID | Area |\n * |--------|------|\n * | CC6.1 | MFA enforcement |\n * | CC6.3 | Periodic access reviews |\n * | CC7.2 | Audit trail completeness |\n * | CC8.1 | Change management / HITL |\n * | CC3.2 | Policy violations |\n */\nexport type SOC2ControlId = \"CC6.1\" | \"CC6.3\" | \"CC7.2\" | \"CC8.1\" | \"CC3.2\";\n\n/**\n * Returns `true` when every control in the run has `pass` or `gap`\n * status (no `finding`). A `gap` means a control is partially met;\n * a `finding` is a blocking deficiency that requires remediation.\n */\nexport function evidenceRunPasses(run: ComplianceEvidenceRun): boolean {\n return (run.controls ?? []).every(c => c.status !== \"finding\");\n}\n\n/**\n * Returns controls that do not have `pass` status, sorted so\n * `finding` controls appear before `gap` controls.\n */\nexport function nonPassingControls(run: ComplianceEvidenceRun): EvidenceControl[] {\n return (run.controls ?? [])\n .filter(c => c.status !== \"pass\")\n .sort((a, b) => {\n if (a.status === \"finding\" && b.status !== \"finding\") return -1;\n if (b.status === \"finding\" && a.status !== \"finding\") return 1;\n return 0;\n });\n}\n","/**\n * Policy-as-code GitOps sync types — wire shapes for `v1-policy-sync`.\n *\n * Supports a dry-run diff preview / apply workflow for pushing policy\n * bundles from CI/CD pipelines or the AtlaSent console.\n *\n * Typical flow:\n * 1. POST `{ policies, dry_run: true }` → receive `run` with `diff`\n * 2. Review diff, then POST `/{run.id}/apply` to execute\n *\n * Or POST `{ policies, dry_run: false }` for an immediate apply.\n */\n\nexport type PolicySyncStatus =\n | \"pending\" // dry-run complete; awaiting apply\n | \"validating\" // server is parsing the bundle\n | \"applying\" // writes in progress\n | \"completed\" // applied successfully\n | \"failed\" // apply error; see server logs\n | \"rejected\"; // validation failed (e.g. schema error)\n\nexport interface PolicyRef {\n name: string;\n /** SHA-256 hex of the policy body. */\n body_hash?: string;\n}\n\nexport interface PolicySyncDiff {\n added: PolicyRef[];\n updated: PolicyRef[];\n removed: PolicyRef[];\n}\n\nexport interface PolicySyncRun {\n id: string;\n org_id: string;\n /** Identifies the caller: `\"console\"`, `\"github-actions\"`, etc. */\n source: string;\n commit_sha: string | null;\n ref: string | null;\n bundle_hash: string | null;\n status: PolicySyncStatus;\n policies_added: number;\n policies_updated: number;\n policies_removed: number;\n /** Populated on dry-run; null after apply. */\n diff: PolicySyncDiff | null;\n applied_by: string | null;\n created_at: string;\n}\n\nexport interface PolicyBundleEntry {\n name: string;\n /** Policy body — OPA Rego, JSON schema, or custom DSL depending on config. */\n body: string;\n description?: string;\n tags?: string[];\n}\n\nexport interface SubmitPolicySyncRequest {\n policies: PolicyBundleEntry[];\n /** Identifies the caller (e.g. `\"github-actions\"`, `\"console\"`). */\n source?: string;\n commit_sha?: string;\n ref?: string;\n /**\n * When `true` (default), computes the diff without applying changes.\n * The returned run will have `status: \"pending\"` and a populated `diff`.\n * POST to `/{run.id}/apply` to execute.\n */\n dry_run?: boolean;\n}\n\nexport interface SubmitPolicySyncResponse {\n run: PolicySyncRun;\n}\n\nexport interface ListPolicySyncRunsResponse {\n runs: PolicySyncRun[];\n}\n\nexport interface ApplyPolicySyncResponse {\n run: PolicySyncRun;\n}\n\n/**\n * Returns a human-readable one-line diff summary suitable for CI logs.\n *\n * @example\n * formatPolicySyncDiff(run) // \"+3 added, ~1 updated, -2 removed\"\n * formatPolicySyncDiff(run) // \"no changes\"\n */\nexport function formatPolicySyncDiff(\n run: Pick<PolicySyncRun, \"policies_added\" | \"policies_updated\" | \"policies_removed\">,\n): string {\n const parts: string[] = [];\n if (run.policies_added > 0) parts.push(`+${run.policies_added} added`);\n if (run.policies_updated > 0) parts.push(`~${run.policies_updated} updated`);\n if (run.policies_removed > 0) parts.push(`-${run.policies_removed} removed`);\n return parts.length > 0 ? parts.join(\", \") : \"no changes\";\n}\n\n/**\n * Returns `true` when a sync run is in a terminal state\n * (completed, failed, or rejected) and no further transitions are expected.\n */\nexport function isPolicySyncTerminal(run: PolicySyncRun): boolean {\n return run.status === \"completed\" || run.status === \"failed\" || run.status === \"rejected\";\n}\n","/**\n * Webhook signature verification for AtlaSent.\n *\n * AtlaSent signs webhook payloads with HMAC-SHA256 using your webhook secret.\n * The signature is sent in the `X-AtlaSent-Signature` header as `sha256=<hex>`.\n *\n * Usage:\n * ```ts\n * import { verifyWebhook, assertWebhook, WebhookVerificationError } from \"@atlasent/sdk\";\n *\n * // Returns true/false — good for middleware that needs to continue on failure\n * const valid = verifyWebhook(rawBody, req.headers[\"x-atlasent-signature\"], secret);\n *\n * // Throws WebhookVerificationError on failure — good for middleware that throws\n * assertWebhook(rawBody, req.headers[\"x-atlasent-signature\"], secret);\n * ```\n */\n\n/**\n * Thrown by {@link assertWebhook} when the signature is missing,\n * malformed, or does not match the payload.\n */\nexport class WebhookVerificationError extends Error {\n override name = \"WebhookVerificationError\";\n\n constructor(message: string) {\n super(message);\n }\n}\n\n// ── Environment detection ─────────────────────────────────────────────────────\n\n/**\n * True when the Web Crypto API (`crypto.subtle`) is available.\n * This is the case in browsers, Cloudflare Workers, Deno, and Node ≥ 20\n * with the global `crypto` exposed. We also accept Node's\n * `require('node:crypto').webcrypto` shape, which exposes `subtle` at the\n * same path when running under Node 18/19.\n *\n * Evaluated once at module load to avoid per-call overhead.\n */\nconst _hasWebCrypto: boolean = (() => {\n try {\n return (\n typeof crypto !== \"undefined\" &&\n typeof (crypto as { subtle?: unknown }).subtle === \"object\" &&\n (crypto as { subtle?: unknown }).subtle !== null\n );\n } catch {\n return false;\n }\n})();\n\n// ── Hex helpers ───────────────────────────────────────────────────────────────\n\n/**\n * Extract the raw hex digest from a `sha256=<hex>` or bare `<hex>` signature\n * string. Returns `null` for any value that doesn't look like a valid\n * lowercase hex string of the expected length (64 chars = 32 bytes = SHA-256).\n */\nfunction _extractHex(signature: string): string | null {\n if (typeof signature !== \"string\") return null;\n\n const hex = signature.startsWith(\"sha256=\") ? signature.slice(7) : signature;\n\n // SHA-256 produces exactly 32 bytes → 64 hex characters.\n if (hex.length !== 64) return null;\n if (!/^[0-9a-f]+$/i.test(hex)) return null;\n\n return hex.toLowerCase();\n}\n\n// ── Timing-safe comparison ────────────────────────────────────────────────────\n\n/**\n * Constant-time string comparison for hex digests.\n *\n * In Node we delegate to `crypto.timingSafeEqual` which operates on\n * `Buffer`s. In browser / edge environments we implement a manual XOR\n * accumulator over the character codes. Both reject unequal-length strings\n * in constant time (length leak is acceptable for fixed-length hex digests).\n */\nasync function _timingSafeEqual(a: string, b: string): Promise<boolean> {\n // Different lengths cannot be equal; short-circuit without exposing which\n // characters differ.\n if (a.length !== b.length) return false;\n\n if (!_hasWebCrypto) {\n // Node.js path — dynamically import `node:crypto` to stay tree-shakeable\n // in browser bundles.\n const { timingSafeEqual, createHmac: _c } = await import(\"node:crypto\");\n const aBuf = Buffer.from(a, \"hex\");\n const bBuf = Buffer.from(b, \"hex\");\n return timingSafeEqual(aBuf, bBuf);\n }\n\n // Browser / edge path — manual XOR accumulator.\n let acc = 0;\n for (let i = 0; i < a.length; i++) {\n acc |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return acc === 0;\n}\n\n// ── HMAC computation ──────────────────────────────────────────────────────────\n\n/**\n * Compute HMAC-SHA256(`secret`, `payload`) and return the hex digest.\n */\nasync function _hmacSha256Hex(payload: string, secret: string): Promise<string> {\n if (_hasWebCrypto) {\n const enc = new TextEncoder();\n const key = await crypto.subtle.importKey(\n \"raw\",\n enc.encode(secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n const sig = await crypto.subtle.sign(\"HMAC\", key, enc.encode(payload));\n return Array.from(new Uint8Array(sig))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n // Node.js path.\n const { createHmac } = await import(\"node:crypto\");\n return createHmac(\"sha256\", secret).update(payload).digest(\"hex\");\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Verifies an AtlaSent webhook payload signature.\n *\n * AtlaSent signs webhook payloads with HMAC-SHA256 using your webhook secret.\n * The signature is sent in the `X-AtlaSent-Signature` header as `\"sha256=<hex>\"`.\n *\n * @param payload - Raw request body as a string (do **not** parse before verifying)\n * @param signature - Value of the `X-AtlaSent-Signature` header\n * @param secret - Your webhook signing secret\n * @returns `true` if the signature is valid, `false` otherwise\n *\n * @remarks\n * Returns `false` (does not throw) for malformed or missing signatures.\n * Use {@link assertWebhook} if you prefer exception-based control flow.\n */\nexport async function verifyWebhook(\n payload: string,\n signature: string,\n secret: string,\n): Promise<boolean> {\n try {\n const expectedHex = _extractHex(signature);\n if (expectedHex === null) return false;\n\n const actualHex = await _hmacSha256Hex(payload, secret);\n return await _timingSafeEqual(actualHex, expectedHex);\n } catch {\n return false;\n }\n}\n\n/**\n * Same as {@link verifyWebhook} but throws {@link WebhookVerificationError}\n * on failure instead of returning `false`. Useful in middleware where\n * throwing is cleaner than inspecting a boolean return value.\n *\n * @param payload - Raw request body as a string (do **not** parse before verifying)\n * @param signature - Value of the `X-AtlaSent-Signature` header\n * @param secret - Your webhook signing secret\n * @throws {@link WebhookVerificationError} if the signature is invalid or malformed\n */\nexport async function assertWebhook(\n payload: string,\n signature: string,\n secret: string,\n): Promise<void> {\n const valid = await verifyWebhook(payload, signature, secret);\n if (!valid) {\n throw new WebhookVerificationError(\n \"Webhook signature verification failed: the signature does not match the payload.\",\n );\n }\n}\n","/**\n * Cross-Org Permission Negotiation.\n *\n * Evaluates whether an identity in one organization is permitted to\n * perform an action on resources owned by another organization.\n * Resolves trust paths, conditions, and cross-org trust levels.\n *\n * Wire-stable as `cross_org_permission.v1`.\n */\n\n/** A single hop in the cross-org trust path. */\nexport interface CrossOrgTrustHop {\n org_id: string;\n trust_type: string;\n trust_level: string;\n}\n\n/** Request payload for a cross-org permission check. */\nexport interface CrossOrgPermissionCheckRequest {\n source_org_id: string;\n target_org_id: string;\n identity_id?: string;\n action: string;\n resource_type?: string;\n resource_id?: string;\n}\n\n/** Result of a cross-org permission evaluation. */\nexport interface CrossOrgPermissionCheckResult {\n check_id: string;\n allowed: boolean;\n reason: string;\n trust_path: Array<CrossOrgTrustHop>;\n conditions: string[];\n checked_at: string;\n}\n\n/** Parameters for listing previous cross-org permission checks. */\nexport interface CrossOrgPermissionCheckListParams {\n source_org_id?: string;\n target_org_id?: string;\n allowed?: boolean;\n limit?: number;\n}\n\n/**\n * Summarize whether a cross-org check result is unconditionally allowed,\n * conditionally allowed, or denied.\n */\nexport function summarizeCrossOrgPermission(\n result: CrossOrgPermissionCheckResult,\n): \"allowed\" | \"conditional\" | \"denied\" {\n if (!result.allowed) return \"denied\";\n if (result.conditions.length > 0) return \"conditional\";\n return \"allowed\";\n}\n","/**\n * Anomaly Response Automation.\n *\n * Rules-driven automated responses to governance anomalies detected\n * during agent execution. Supports freezing agents, creating incidents,\n * notifying administrators, requiring human-in-the-loop review,\n * rolling back executions, and escalating to regulators.\n *\n * Wire-stable as `anomaly_response.v1`.\n */\n\n/** The automated action type to take when an anomaly rule triggers. */\nexport type AnomalyActionType =\n | \"freeze_agent\"\n | \"create_incident\"\n | \"notify_admin\"\n | \"require_hitl\"\n | \"rollback_execution\"\n | \"escalate_to_regulator\";\n\n/** A rule that triggers an automated response when an anomaly threshold is crossed. */\nexport interface AnomalyResponseRule {\n id: string;\n org_id: string;\n name: string;\n description?: string;\n anomaly_score_threshold: number;\n action_type: AnomalyActionType;\n action_config: Record<string, unknown>;\n is_active: boolean;\n created_at: string;\n updated_at: string;\n}\n\n/** A record of an anomaly response that was triggered. */\nexport interface AnomalyResponseEvent {\n id: string;\n rule_id: string;\n execution_id: string;\n org_id: string;\n anomaly_score: number;\n action_type: AnomalyActionType;\n action_result: Record<string, unknown>;\n triggered_at: string;\n}\n\n/** Request body for creating a new anomaly response rule. */\nexport interface CreateAnomalyResponseRuleRequest {\n name: string;\n description?: string;\n anomaly_score_threshold: number;\n action_type: AnomalyActionType;\n action_config?: Record<string, unknown>;\n}\n\n/** Request body for manually triggering an anomaly response check. */\nexport interface TriggerAnomalyResponseRequest {\n execution_id: string;\n anomaly_score: number;\n context?: Record<string, unknown>;\n}\n\n/**\n * Determine which rules from a set would trigger for a given anomaly score.\n * Returns only active rules whose threshold is met or exceeded.\n */\nexport function matchAnomalyRules(\n rules: readonly AnomalyResponseRule[],\n anomalyScore: number,\n): AnomalyResponseRule[] {\n return rules\n .filter((r) => r.is_active && anomalyScore >= r.anomaly_score_threshold)\n .sort((a, b) => b.anomaly_score_threshold - a.anomaly_score_threshold);\n}\n\n/**\n * Determine the most severe action type from a set of triggered rules.\n * Severity order (highest first):\n * escalate_to_regulator > rollback_execution > freeze_agent >\n * require_hitl > create_incident > notify_admin\n */\nexport function highestSeverityAction(\n rules: readonly AnomalyResponseRule[],\n): AnomalyActionType | null {\n const ORDER: AnomalyActionType[] = [\n \"escalate_to_regulator\",\n \"rollback_execution\",\n \"freeze_agent\",\n \"require_hitl\",\n \"create_incident\",\n \"notify_admin\",\n ];\n for (const action of ORDER) {\n if (rules.some((r) => r.action_type === action)) return action;\n }\n return null;\n}\n","/**\n * Budget Exception Workflows.\n *\n * Structured request-and-approval process for temporary exceptions\n * to budget policy limits. Supports creation, review, approval,\n * rejection, and cancellation lifecycles with full audit trails.\n *\n * Wire-stable as `budget_exceptions.v1`.\n */\n\n/** Lifecycle status of a budget exception request. */\nexport type BudgetExceptionStatus =\n | \"pending\"\n | \"under_review\"\n | \"approved\"\n | \"rejected\"\n | \"expired\"\n | \"cancelled\";\n\n/** A formal request for a temporary exception to a budget policy limit. */\nexport interface BudgetExceptionRequest {\n id: string;\n org_id: string;\n budget_policy_id?: string;\n requested_by: string;\n amount_requested: number;\n currency: string;\n reason: string;\n justification?: string;\n business_impact?: string;\n status: BudgetExceptionStatus;\n reviewed_by?: string;\n reviewed_at?: string;\n review_notes?: string;\n effective_from?: string;\n effective_until?: string;\n approved_amount?: number;\n conditions: string[];\n created_at: string;\n updated_at: string;\n}\n\n/** Request body for creating a new budget exception request. */\nexport interface CreateBudgetExceptionRequest {\n budget_policy_id?: string;\n amount_requested: number;\n currency?: string;\n reason: string;\n justification?: string;\n business_impact?: string;\n effective_from?: string;\n effective_until?: string;\n}\n\n/** Request body for approving a budget exception. */\nexport interface ApproveBudgetExceptionRequest {\n review_notes?: string;\n approved_amount: number;\n conditions?: string[];\n effective_from?: string;\n effective_until?: string;\n}\n\n/**\n * Returns true when an approved exception is currently in effect.\n * An exception is in effect when:\n * - status is \"approved\"\n * - current time is within [effective_from, effective_until]\n */\nexport function isBudgetExceptionActive(\n exception: BudgetExceptionRequest,\n now?: Date,\n): boolean {\n if (exception.status !== \"approved\") return false;\n const ts = (now ?? new Date()).toISOString();\n if (exception.effective_from && ts < exception.effective_from) return false;\n if (exception.effective_until && ts > exception.effective_until) return false;\n return true;\n}\n\n/**\n * Returns true when a budget exception request is in a terminal state\n * (no further transitions are possible).\n */\nexport function isBudgetExceptionTerminal(\n status: BudgetExceptionStatus,\n): boolean {\n return status === \"approved\" || status === \"rejected\" || status === \"expired\" || status === \"cancelled\";\n}\n","/**\n * Regulatory Escalation Chain.\n *\n * Hierarchical escalation infrastructure for routing governance issues\n * through defined authority levels. Supports multi-jurisdiction\n * regulatory chains with SLA tracking and resolution workflows.\n *\n * Wire-stable as `regulatory_escalation.v1`.\n */\n\n/**\n * A defined level in the regulatory authority hierarchy.\n * Levels are ordered numerically — lower numbers = lower authority.\n */\nexport interface RegulatoryAuthorityLevel {\n id: string;\n org_id: string;\n name: string;\n level: number;\n description?: string;\n parent_level_id?: string;\n jurisdiction?: string;\n escalation_sla_hours: number;\n created_at: string;\n}\n\n/** Lifecycle status of a regulatory escalation. */\nexport type RegulatoryEscalationStatus =\n | \"pending\"\n | \"acknowledged\"\n | \"under_review\"\n | \"resolved\"\n | \"overridden\";\n\n/** A formal escalation between two regulatory authority levels. */\nexport interface RegulatoryEscalation {\n id: string;\n org_id: string;\n from_level_id: string;\n to_level_id: string;\n subject_type: string;\n subject_id: string;\n reason: string;\n details: Record<string, unknown>;\n status: RegulatoryEscalationStatus;\n escalated_by: string;\n acknowledged_by?: string;\n acknowledged_at?: string;\n resolved_by?: string;\n resolved_at?: string;\n resolution?: string;\n resolution_details?: Record<string, unknown>;\n created_at: string;\n updated_at: string;\n}\n\n/** Request body for creating a new regulatory escalation. */\nexport interface CreateRegulatoryEscalationRequest {\n from_level_id: string;\n to_level_id: string;\n subject_type: string;\n subject_id: string;\n reason: string;\n details?: Record<string, unknown>;\n}\n\n/**\n * Returns true when a regulatory escalation is in a terminal state.\n */\nexport function isRegulatoryEscalationTerminal(\n status: RegulatoryEscalationStatus,\n): boolean {\n return status === \"resolved\" || status === \"overridden\";\n}\n\n/**\n * Determine whether an escalation has breached its SLA.\n * Compares the SLA hours on the target authority level against the\n * elapsed time since creation.\n */\nexport function isEscalationSlaBreached(\n escalation: RegulatoryEscalation,\n targetLevel: RegulatoryAuthorityLevel,\n now?: Date,\n): boolean {\n if (isRegulatoryEscalationTerminal(escalation.status)) return false;\n const createdMs = new Date(escalation.created_at).getTime();\n const nowMs = (now ?? new Date()).getTime();\n const elapsedHours = (nowMs - createdMs) / (1000 * 60 * 60);\n return elapsedHours > targetLevel.escalation_sla_hours;\n}\n","/**\n * Incentive Signal Feedback Loop.\n *\n * Captures how governance actors respond to incentive alignment signals\n * and tracks outcomes. Feeds back into signal calibration and governance\n * health scoring over time.\n *\n * Wire-stable as `incentive_signal_feedback.v1`.\n */\n\n/** The type of action taken in response to a governance signal. */\nexport type SignalActionType =\n | \"accepted\"\n | \"dismissed\"\n | \"escalated\"\n | \"delegated\"\n | \"policy_updated\"\n | \"training_initiated\"\n | \"process_changed\"\n | \"monitoring_increased\"\n | \"auto_remediated\";\n\n/** A record of an action taken in response to a governance signal. */\nexport interface GovernanceSignalAction {\n id: string;\n signal_id: string;\n org_id: string;\n action_type: SignalActionType;\n action_description?: string;\n taken_by?: string;\n taken_at: string;\n outcome_score?: number;\n outcome_description?: string;\n outcome_recorded_at?: string;\n metadata: Record<string, unknown>;\n}\n\n/** Request body for recording a new signal action. */\nexport interface RecordSignalActionRequest {\n action_type: SignalActionType;\n action_description?: string;\n metadata?: Record<string, unknown>;\n}\n\n/** Request body for recording an outcome on a previous signal action. */\nexport interface RecordSignalOutcomeRequest {\n outcome_score: number;\n outcome_description?: string;\n}\n\n/** Aggregate summary of signal actions for an organization. */\nexport interface SignalActionSummary {\n total_signals: number;\n acted_on: number;\n dismissed: number;\n average_outcome_score: number;\n by_action_type: Record<SignalActionType, { count: number; avg_outcome: number }>;\n}\n\n/**\n * Compute a simple engagement rate from a signal action summary.\n * Returns the fraction of signals that received a non-dismissed response.\n */\nexport function computeSignalEngagementRate(\n summary: SignalActionSummary,\n): number {\n if (summary.total_signals === 0) return 0;\n return summary.acted_on / summary.total_signals;\n}\n\n/**\n * Determine whether a signal action represents a substantive governance\n * response (i.e. more than a dismissal or auto-remediation).\n */\nexport function isSubstantiveSignalResponse(\n actionType: SignalActionType,\n): boolean {\n return (\n actionType === \"policy_updated\" ||\n actionType === \"training_initiated\" ||\n actionType === \"process_changed\" ||\n actionType === \"monitoring_increased\" ||\n actionType === \"escalated\"\n );\n}\n","/**\n * Cross-Org Impersonation.\n *\n * Allows a service account in one organization to impersonate a role in\n * another organization under explicit, audited grants. Supports bounded\n * token issuance, grant revocation, and token validation.\n *\n * Wire-stable as `cross_org_impersonation.v1`.\n */\n\n/** An explicit grant allowing one org's service account to impersonate a role in another org. */\nexport interface CrossOrgImpersonationGrant {\n id: string;\n grantor_org_id: string;\n grantee_org_id: string;\n grantee_service_account_id: string;\n impersonated_role: string;\n allowed_actions: string[];\n allowed_resource_types: string[];\n max_token_duration_seconds: number;\n is_active: boolean;\n created_by: string;\n created_at: string;\n expires_at?: string;\n revoked_at?: string;\n}\n\n/** Request body for creating a new impersonation grant. */\nexport interface CreateImpersonationGrantRequest {\n grantee_org_id: string;\n grantee_service_account_id: string;\n impersonated_role: string;\n allowed_actions: string[];\n allowed_resource_types: string[];\n max_token_duration_seconds?: number;\n expires_at?: string;\n}\n\n/** A short-lived impersonation token issued under a grant. */\nexport interface ImpersonationToken {\n token: string;\n expires_at: string;\n grant_id: string;\n}\n\n/** Result of validating an impersonation token. */\nexport interface ImpersonationValidationResult {\n valid: boolean;\n grant?: CrossOrgImpersonationGrant;\n impersonated_role?: string;\n allowed_actions?: string[];\n allowed_resource_types?: string[];\n error?: string;\n}\n\n/**\n * Returns true when an impersonation grant is currently usable:\n * - is_active is true\n * - not yet expired\n * - not revoked\n */\nexport function isImpersonationGrantUsable(\n grant: CrossOrgImpersonationGrant,\n now?: Date,\n): boolean {\n if (!grant.is_active) return false;\n if (grant.revoked_at) return false;\n const ts = (now ?? new Date()).toISOString();\n if (grant.expires_at && ts > grant.expires_at) return false;\n return true;\n}\n\n/**\n * Clamp a requested token duration to the grant's maximum.\n * Returns the minimum of the requested duration and the grant ceiling.\n */\nexport function clampTokenDuration(\n grant: CrossOrgImpersonationGrant,\n requestedSeconds: number,\n): number {\n return Math.min(requestedSeconds, grant.max_token_duration_seconds);\n}\n","/**\n * V2 Wave-A endpoints (V2-D3, V2-D4, V2-D8) — additive on top of v1.\n *\n * Three additional methods on top of the v1 {@link AtlaSentClient}\n * surface that target the new wire endpoints landed in `atlasent-api`\n * PRs #742 (batch), #745 (stream), and #746 (graphql).\n *\n * The v1 substrate is frozen (post-GA 2026-05-17) — this module is\n * purely additive. Existing 1.x methods (`protect`, `requirePermit`,\n * `evaluate`, …) are untouched.\n *\n * ## Closed-by-default discipline\n *\n * Each tenant gates the new endpoints behind `v2_batch`,\n * `v2_streaming`, and `v2_graphql` flags. When the flag is off the\n * API returns HTTP 404, surfaced here as {@link FeatureNotEnabledError}\n * so callers can deterministically fall back (typically to a per-item\n * `/v1-evaluate` loop). The SDK never silently falls back — that would\n * change billing and audit semantics.\n */\n\nimport { AtlaSentError, type AtlaSentErrorInit } from \"./errors.js\";\n\n// ── Constants ────────────────────────────────────────────────────────\n\nexport const V2_BATCH_PATH = \"/v1/evaluate/batch\";\nexport const V2_STREAM_PATH = \"/v1/evaluate/stream\";\nexport const V2_GRAPHQL_PATH = \"/v1/graphql\";\n\n/** Maximum items per batch (mirrors the server-side cap, V2-D3). */\nexport const V2_MAX_BATCH_ITEMS = 100;\n/** Maximum request body size (mirrors the server-side 1MB cap). */\nexport const V2_MAX_BODY_BYTES = 1_000_000;\n/** GraphQL document depth cap (V2-D2). */\nexport const V2_GRAPHQL_MAX_DEPTH = 8;\n\n// ── Errors ───────────────────────────────────────────────────────────\n\n/**\n * Identifier of the tenant flag gating a V2 endpoint.\n */\nexport type V2Feature = \"batch\" | \"streaming\" | \"graphql\";\n\n/**\n * Initialization options for {@link FeatureNotEnabledError}.\n */\nexport interface FeatureNotEnabledErrorInit {\n feature: V2Feature;\n endpoint: string;\n requestId?: string;\n}\n\n/**\n * Thrown when a V2 endpoint returns 404 because the tenant feature\n * flag is off.\n *\n * The three V2 endpoints (`/v1/evaluate/batch`, `/v1/evaluate/stream`,\n * `/v1/graphql`) are close-by-default per tenant. When the\n * corresponding flag is unset, the API returns HTTP 404; the SDK\n * surfaces that as this distinct error so the caller can\n * deterministically fall back to the v1 per-item loop.\n *\n * Subclass of {@link AtlaSentError} so `instanceof AtlaSentError`\n * catches it alongside the SDK's other typed errors.\n */\nexport class FeatureNotEnabledError extends AtlaSentError {\n override name: string = \"FeatureNotEnabledError\";\n\n /** Which tenant flag is gating the endpoint. */\n readonly feature: V2Feature;\n /** The wire path the SDK attempted (for diagnostics). */\n readonly endpoint: string;\n\n constructor(init: FeatureNotEnabledErrorInit) {\n const message =\n `AtlaSent V2 feature '${init.feature}' is not enabled for this tenant ` +\n `(POST ${init.endpoint} returned 404). Enable the v2_${init.feature} ` +\n `flag or fall back to the v1 per-item /v1-evaluate loop.`;\n // `feature_disabled` (not `forbidden`): the request was not denied\n // on authorization grounds — the tenant lacks the v2_<feature> flag.\n // Callers branching on `err.code === \"forbidden\"` would otherwise\n // conflate this with real 403 auth failures.\n const errInit: AtlaSentErrorInit = { status: 404, code: \"feature_disabled\" };\n if (init.requestId !== undefined) errInit.requestId = init.requestId;\n super(message, errInit);\n this.feature = init.feature;\n this.endpoint = init.endpoint;\n }\n}\n\n// ── Response / event shapes ────────────────────────────────────────────────\n\n/**\n * One element of an {@link EvaluateBatchResponse.items} list.\n *\n * Preserves input order — `items[i]` corresponds to `request.items[i]`.\n * On a per-item RPC failure the server returns `decision: undefined`\n * and populates `errorCode` / `errorMessage` instead.\n */\nexport interface EvaluateBatchItem {\n index: number;\n decision?: string;\n decisionId?: string;\n permitToken?: string;\n reason?: string;\n errorCode?: string;\n errorMessage?: string;\n}\n\n/** Response shape for `POST /v1/evaluate/batch`. */\nexport interface EvaluateBatchResponse {\n batchId: string;\n items: ReadonlyArray<EvaluateBatchItem>;\n partial: boolean;\n}\n\n/** Request payload for {@link evaluateMany} and {@link authorizeStream}. */\nexport interface EvaluateManyRequest {\n items: ReadonlyArray<Record<string, unknown>>;\n batchId?: string;\n}\n\n/** `event: decision` frame surfaced via the `onDecision` callback. */\nexport interface StreamDecisionFrame {\n index: number;\n decision: string;\n decisionId?: string;\n permitToken?: string;\n reason?: string;\n}\n\n/** `event: error` frame surfaced via the `onError` callback. */\nexport interface StreamErrorFrame {\n index: number;\n errorCode: string;\n message: string;\n}\n\n/** Terminal `event: complete` payload returned by {@link authorizeStream}. */\nexport interface StreamComplete {\n batchId: string;\n count: number;\n partial: boolean;\n}\n\n/** GraphQL request body. */\nexport interface GraphQLRequest {\n query: string;\n variables?: Record<string, unknown>;\n operationName?: string;\n}\n\n/**\n * GraphQL response. Resolver errors land on `errors`; the SDK does\n * not throw on them — the caller branches.\n */\nexport interface GraphQLResponse<T = unknown> {\n data: T | null;\n errors?: ReadonlyArray<Record<string, unknown>>;\n}\n\n// ── Minimal client surface this module needs ──────────────────────────────────────\n\n/**\n * The minimal subset of an {@link AtlaSentClient}-like object this\n * module needs: a `fetch`-compatible HTTP function and a base URL.\n *\n * Passed explicitly so the v2 module never reaches into v1 internals\n * (and so callers can plug in a custom fetch for testing / edge\n * runtimes / Node fetch wrappers).\n */\nexport interface V2Transport {\n /** Base URL (no trailing slash), e.g. `https://api.atlasent.io`. */\n baseUrl: string;\n /** Bearer API key (without the `Bearer ` prefix). */\n apiKey: string;\n /** A `fetch`-like function. Defaults to global `fetch` if omitted. */\n fetch?: typeof fetch;\n}\n\n// ── UUID validation ──────────────────────────────────────────────────────────\n\nconst UUID_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nfunction assertValidBatchId(batchId: string | undefined): void {\n if (batchId === undefined) return;\n if (typeof batchId !== \"string\" || !UUID_RE.test(batchId)) {\n throw new TypeError(`batchId must be a valid UUID: ${String(batchId)}`);\n }\n}\n\nfunction assertItemsShape(items: ReadonlyArray<unknown>): void {\n if (!Array.isArray(items) || items.length === 0) {\n throw new TypeError(\"items must be a non-empty array\");\n }\n if (items.length > V2_MAX_BATCH_ITEMS) {\n throw new TypeError(\n `items length ${items.length} exceeds maximum of ${V2_MAX_BATCH_ITEMS}`,\n );\n }\n}\n\nfunction assertBodyWithinCap(raw: string): void {\n // UTF-8 byte length, not character length.\n const bytes = new TextEncoder().encode(raw).length;\n if (bytes > V2_MAX_BODY_BYTES) {\n throw new TypeError(\n `request body ${bytes} bytes exceeds maximum of ${V2_MAX_BODY_BYTES}`,\n );\n }\n}\n\nfunction commonHeaders(apiKey: string): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n };\n}\n\nfunction pickFetch(t: V2Transport): typeof fetch {\n if (t.fetch !== undefined) return t.fetch;\n if (typeof fetch !== \"undefined\") return fetch;\n throw new Error(\n \"v2: no fetch implementation available (set transport.fetch or run on Node ≥ 18)\",\n );\n}\n\n// ── evaluateMany ──────────────────────────────────────────────────────────\n\n/**\n * `POST /v1/evaluate/batch` — V2-D3.\n *\n * One round-trip for up to {@link V2_MAX_BATCH_ITEMS} evaluate items.\n * Items are returned in input order — `response.items[i].index === i`.\n *\n * @throws {FeatureNotEnabledError} When the tenant `v2_batch` flag is off (404).\n * @throws {AtlaSentError} For any other transport / HTTP failure.\n * @throws {TypeError} When `items` is empty, exceeds the cap, or\n * `batchId` is not a valid UUID.\n */\nexport async function evaluateMany(\n transport: V2Transport,\n req: EvaluateManyRequest,\n): Promise<EvaluateBatchResponse> {\n assertItemsShape(req.items);\n assertValidBatchId(req.batchId);\n\n const body: Record<string, unknown> = { items: req.items };\n if (req.batchId !== undefined) body[\"batch_id\"] = req.batchId;\n const raw = JSON.stringify(body);\n assertBodyWithinCap(raw);\n\n const url = `${transport.baseUrl}${V2_BATCH_PATH}`;\n const fetchImpl = pickFetch(transport);\n const response = await fetchImpl(url, {\n method: \"POST\",\n headers: commonHeaders(transport.apiKey),\n body: raw,\n });\n\n const requestId = response.headers.get(\"X-Request-ID\") ?? undefined;\n if (response.status === 404) {\n const init: FeatureNotEnabledErrorInit = {\n feature: \"batch\",\n endpoint: V2_BATCH_PATH,\n };\n if (requestId !== undefined) init.requestId = requestId;\n throw new FeatureNotEnabledError(init);\n }\n if (!response.ok) {\n throwHttpError(V2_BATCH_PATH, response.status, requestId);\n }\n\n const parsed = await safeJson(response, V2_BATCH_PATH, requestId);\n return parseBatchResponse(parsed);\n}\n\nfunction parseBatchResponse(data: unknown): EvaluateBatchResponse {\n const root = (data ?? {}) as Record<string, unknown>;\n const rawItems = (root[\"items\"] ?? []) as ReadonlyArray<\n Record<string, unknown>\n >;\n const items: EvaluateBatchItem[] = rawItems.map((it) => {\n const out: EvaluateBatchItem = {\n index: typeof it[\"index\"] === \"number\" ? (it[\"index\"] as number) : -1,\n };\n const decision = it[\"decision\"];\n if (typeof decision === \"string\") out.decision = decision;\n const decisionId = it[\"decision_id\"];\n if (typeof decisionId === \"string\") out.decisionId = decisionId;\n const permitToken = it[\"permit_token\"];\n if (typeof permitToken === \"string\") out.permitToken = permitToken;\n const reason = it[\"reason\"];\n if (typeof reason === \"string\") out.reason = reason;\n const errorCode = it[\"error_code\"];\n if (typeof errorCode === \"string\") out.errorCode = errorCode;\n const errorMessage = it[\"error_message\"];\n if (typeof errorMessage === \"string\") out.errorMessage = errorMessage;\n return out;\n });\n const batchId = root[\"batch_id\"];\n return {\n batchId: typeof batchId === \"string\" ? batchId : \"\",\n items,\n partial: Boolean(root[\"partial\"]),\n };\n}\n\n// ── authorizeStream ──────────────────────────────────────────────────────────\n\n/**\n * Callbacks consumed by {@link authorizeStream}.\n */\nexport interface AuthorizeStreamHandlers {\n onDecision?: (frame: StreamDecisionFrame) => void;\n onError?: (frame: StreamErrorFrame) => void;\n}\n\n/**\n * `POST /v1/evaluate/stream` — V2-D4.\n *\n * Streams `event: decision` frames in input order. Per-item RPC\n * failures arrive as `event: error` frames and do not tear down the\n * stream (V2-D7 async semantics). Resolves with the terminal\n * `event: complete` payload.\n *\n * @throws {FeatureNotEnabledError} When the tenant `v2_streaming` flag is off.\n * @throws {AtlaSentError} For transport failures, including the stream\n * closing without a `complete` frame.\n */\nexport async function authorizeStream(\n transport: V2Transport,\n req: EvaluateManyRequest,\n handlers: AuthorizeStreamHandlers = {},\n): Promise<StreamComplete> {\n assertItemsShape(req.items);\n assertValidBatchId(req.batchId);\n\n const body: Record<string, unknown> = { items: req.items };\n if (req.batchId !== undefined) body[\"batch_id\"] = req.batchId;\n const raw = JSON.stringify(body);\n assertBodyWithinCap(raw);\n\n const url = `${transport.baseUrl}${V2_STREAM_PATH}`;\n const fetchImpl = pickFetch(transport);\n const response = await fetchImpl(url, {\n method: \"POST\",\n headers: {\n ...commonHeaders(transport.apiKey),\n Accept: \"text/event-stream\",\n },\n body: raw,\n });\n\n const requestId = response.headers.get(\"X-Request-ID\") ?? undefined;\n if (response.status === 404) {\n const init: FeatureNotEnabledErrorInit = {\n feature: \"streaming\",\n endpoint: V2_STREAM_PATH,\n };\n if (requestId !== undefined) init.requestId = requestId;\n throw new FeatureNotEnabledError(init);\n }\n if (!response.ok) {\n throwHttpError(V2_STREAM_PATH, response.status, requestId);\n }\n if (response.body === null) {\n throw new AtlaSentError(\n `POST ${V2_STREAM_PATH} returned no response body`,\n { code: \"bad_response\", status: response.status },\n );\n }\n\n const complete = await consumeSseStream(response.body, handlers);\n if (complete === null) {\n throw new AtlaSentError(\n \"authorizeStream: stream closed without a `complete` event\",\n { code: \"bad_response\" },\n );\n }\n return complete;\n}\n\nasync function consumeSseStream(\n body: ReadableStream<Uint8Array>,\n handlers: AuthorizeStreamHandlers,\n): Promise<StreamComplete | null> {\n const reader = body.getReader();\n const decoder = new TextDecoder(\"utf-8\");\n let buffer = \"\";\n let eventName: string | undefined = undefined;\n let complete: StreamComplete | null = null;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const { value, done } = await reader.read();\n if (value !== undefined) {\n buffer += decoder.decode(value, { stream: !done });\n }\n if (done) {\n buffer += decoder.decode();\n }\n\n // Process complete lines (separator: \\n; tolerate \\r\\n).\n let nl: number;\n while ((nl = buffer.indexOf(\"\\n\")) !== -1) {\n let line = buffer.slice(0, nl);\n buffer = buffer.slice(nl + 1);\n if (line.endsWith(\"\\r\")) line = line.slice(0, -1);\n\n if (line === \"\") {\n eventName = undefined;\n continue;\n }\n if (line.startsWith(\":\")) continue; // keep-alive heartbeat\n if (line.startsWith(\"event:\")) {\n eventName = line.slice(\"event:\".length).trim();\n continue;\n }\n if (!line.startsWith(\"data:\")) continue;\n const dataText = line.slice(\"data:\".length).trim();\n let payload: unknown;\n try {\n payload = JSON.parse(dataText);\n } catch {\n continue;\n }\n if (typeof payload !== \"object\" || payload === null || Array.isArray(payload)) {\n continue;\n }\n const p = payload as Record<string, unknown>;\n if (eventName === \"decision\" && handlers.onDecision !== undefined) {\n const dIndex = p[\"index\"];\n const dDecision = p[\"decision\"];\n const frame: StreamDecisionFrame = {\n index: typeof dIndex === \"number\" ? dIndex : -1,\n decision: typeof dDecision === \"string\" ? dDecision : \"\",\n };\n const dId = p[\"decision_id\"];\n if (typeof dId === \"string\") frame.decisionId = dId;\n const pt = p[\"permit_token\"];\n if (typeof pt === \"string\") frame.permitToken = pt;\n const r = p[\"reason\"];\n if (typeof r === \"string\") frame.reason = r;\n handlers.onDecision(frame);\n } else if (eventName === \"error\" && handlers.onError !== undefined) {\n const eIndex = p[\"index\"];\n const eCode = p[\"error_code\"];\n const eMsg = p[\"message\"];\n handlers.onError({\n index: typeof eIndex === \"number\" ? eIndex : -1,\n errorCode: typeof eCode === \"string\" ? eCode : \"\",\n message: typeof eMsg === \"string\" ? eMsg : \"\",\n });\n } else if (eventName === \"complete\") {\n const cBatchId = p[\"batch_id\"];\n const cCount = p[\"count\"];\n complete = {\n batchId: typeof cBatchId === \"string\" ? cBatchId : \"\",\n count: typeof cCount === \"number\" ? cCount : 0,\n partial: Boolean(p[\"partial\"]),\n };\n try {\n await reader.cancel();\n } catch {\n // best-effort cancel\n }\n return complete;\n }\n }\n\n if (done) break;\n }\n\n return complete;\n}\n\n// ── graphql ───────────────────────────────────────────────────────────\n\n/**\n * `POST /v1/graphql` — V2-D2 + V2-D8.\n *\n * Bearer-only auth (no query-param). Wave A schema is read-only\n * (`recentEvaluations(limit)` + `activeBundle`). Server enforces the\n * V2-D8 OR-gate (`audit:read` OR `policy:read`) at request layer and\n * a per-resolver AND-gate at field resolution time.\n *\n * Resolver-level errors surface on `response.errors` — the SDK does\n * not throw on them so callers can inspect partial data.\n *\n * @throws {FeatureNotEnabledError} When the tenant `v2_graphql` flag is off.\n * @throws {AtlaSentError} For transport / HTTP failures.\n * @throws {TypeError} When `query` is empty or the body exceeds the 1MB cap.\n */\nexport async function graphql<T = unknown>(\n transport: V2Transport,\n req: GraphQLRequest,\n): Promise<GraphQLResponse<T>> {\n if (typeof req.query !== \"string\" || req.query.trim() === \"\") {\n throw new TypeError(\"query must be a non-empty string\");\n }\n const body: Record<string, unknown> = { query: req.query };\n if (req.variables !== undefined) body[\"variables\"] = req.variables;\n if (req.operationName !== undefined)\n body[\"operationName\"] = req.operationName;\n\n const raw = JSON.stringify(body);\n assertBodyWithinCap(raw);\n\n const url = `${transport.baseUrl}${V2_GRAPHQL_PATH}`;\n const fetchImpl = pickFetch(transport);\n const response = await fetchImpl(url, {\n method: \"POST\",\n headers: commonHeaders(transport.apiKey),\n body: raw,\n });\n const requestId = response.headers.get(\"X-Request-ID\") ?? undefined;\n if (response.status === 404) {\n const init: FeatureNotEnabledErrorInit = {\n feature: \"graphql\",\n endpoint: V2_GRAPHQL_PATH,\n };\n if (requestId !== undefined) init.requestId = requestId;\n throw new FeatureNotEnabledError(init);\n }\n if (!response.ok) {\n throwHttpError(V2_GRAPHQL_PATH, response.status, requestId);\n }\n\n const parsed = (await safeJson(response, V2_GRAPHQL_PATH, requestId)) as\n | Record<string, unknown>\n | null;\n const root = parsed ?? {};\n const out: GraphQLResponse<T> = {\n data: (root[\"data\"] ?? null) as T | null,\n };\n const errs = root[\"errors\"];\n if (Array.isArray(errs) && errs.length > 0) {\n out.errors = errs as ReadonlyArray<Record<string, unknown>>;\n }\n return out;\n}\n\n// ── helpers ───────────────────────────────────────────────────────────\n\nfunction throwHttpError(\n path: string,\n status: number,\n requestId: string | undefined,\n): never {\n const errInit: AtlaSentErrorInit = {\n status,\n code: status >= 500 ? \"server_error\" : \"bad_request\",\n };\n if (requestId !== undefined) errInit.requestId = requestId;\n throw new AtlaSentError(`POST ${path} returned ${status}`, errInit);\n}\n\nasync function safeJson(\n response: Response,\n path: string,\n requestId: string | undefined,\n): Promise<unknown> {\n try {\n return await response.json();\n } catch (cause) {\n const errInit: AtlaSentErrorInit = {\n status: response.status,\n code: \"bad_response\",\n cause,\n };\n if (requestId !== undefined) errInit.requestId = requestId;\n throw new AtlaSentError(`${path}: malformed JSON response`, errInit);\n }\n}\n","/**\n * Runtime v2 client — authorized-state-change lifecycle.\n *\n * Thin client over `/v2/orgs/:org_id/…` endpoints landed in\n * `atlasent-api` PR #1031. Accepts the same {@link V2Transport}\n * interface used by the existing v2 batch/stream/graphql module so\n * callers can reuse the same auth headers and fetch implementation.\n *\n * @example\n * ```ts\n * import { RuntimeV2Client } from \"@atlasent/sdk/runtime_v2\";\n *\n * const rt = new RuntimeV2Client({\n * baseUrl: \"https://api.atlasent.io\",\n * apiKey: process.env.ATLASENT_API_KEY!,\n * });\n * const decision = await rt.authorize(\"org_acme\", { transition: { … } });\n * ```\n */\n\nimport { AtlaSentError } from \"./errors.js\";\nimport type { V2Transport } from \"./v2.js\";\n\n// ── Wire types ────────────────────────────────────────────────────────────────\n\nexport interface VerificationFailure {\n code: string;\n message: string;\n field?: string;\n}\n\nexport interface VerificationResult {\n passed: boolean;\n verified_at: string;\n failures: VerificationFailure[];\n warnings: Array<Record<string, unknown>>;\n}\n\nexport interface ExecutionReceipt {\n receipt_id: string;\n permit_id: string;\n org_id: string;\n issued_at: string;\n post_state_fingerprint: string;\n evidence_id: string;\n}\n\nexport interface PostExecutionResult {\n verified: boolean;\n evidence_completeness: \"COMPLETE\" | \"PARTIAL\" | \"FAILED\";\n failures: VerificationFailure[];\n receipt?: ExecutionReceipt;\n}\n\nexport interface AuthorizationDecision {\n status: \"PERMITTED\" | \"PENDING_APPROVAL\" | \"DENIED\" | \"ERROR\";\n permit?: Record<string, unknown>;\n required_approvers?: string[];\n reasons?: string[];\n policy_ids?: string[];\n code?: string;\n message?: string;\n}\n\nexport interface AuthorityRecord {\n authority_id: string;\n org_id: string;\n name: string;\n action_classes: string[];\n public_key: string;\n key_id: string;\n status: string;\n created_at: string;\n [key: string]: unknown;\n}\n\nexport interface RuntimeAuditEntry {\n entry_id: string;\n org_id: string;\n sequence: number;\n receipt_id: string;\n prior_hash: string;\n entry_hash: string;\n appended_at: string;\n}\n\nexport interface AuditChainPage {\n entries: RuntimeAuditEntry[];\n total: number;\n page: number;\n page_size: number;\n}\n\nexport interface ChainIntegrityReport {\n valid: boolean;\n checked_entries: number;\n first_sequence: number;\n last_sequence: number;\n gaps: number[];\n invalid_hashes: number[];\n verified_at: string;\n}\n\nexport interface ComplianceExport {\n export_id: string;\n org_id: string;\n from: string;\n to: string;\n entry_count: number;\n format: string;\n content_ref: string;\n content_hash: string;\n generated_at: string;\n signed_by: string;\n}\n\nexport interface AuditChainFilters {\n action_class?: string;\n principal_did?: string;\n resource_locator?: string;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction orgPath(orgId: string, ...parts: string[]): string {\n const base = `/v2/orgs/${orgId}`;\n return parts.length ? `${base}/${parts.join(\"/\")}` : base;\n}\n\nfunction headers(apiKey: string): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n };\n}\n\nfunction pickFetch(t: V2Transport): typeof fetch {\n if (t.fetch !== undefined) return t.fetch;\n if (typeof fetch !== \"undefined\") return fetch;\n throw new Error(\n \"runtime_v2: no fetch available (set transport.fetch or run Node ≥ 18)\",\n );\n}\n\nasync function doPost(\n t: V2Transport,\n path: string,\n body: unknown,\n): Promise<Record<string, unknown>> {\n const f = pickFetch(t);\n const res = await f(`${t.baseUrl}${path}`, {\n method: \"POST\",\n headers: headers(t.apiKey),\n body: JSON.stringify(body),\n });\n const data = (await res.json()) as Record<string, unknown>;\n if (!res.ok) {\n const err = (data[\"error\"] as Record<string, unknown>) ?? {};\n throw new AtlaSentError(\n String(err[\"message\"] ?? `POST ${path} failed (${res.status})`),\n { status: res.status },\n );\n }\n return data;\n}\n\nasync function doGet(\n t: V2Transport,\n path: string,\n params?: Record<string, string>,\n): Promise<Record<string, unknown>> {\n const f = pickFetch(t);\n const url = new URL(`${t.baseUrl}${path}`);\n if (params) {\n for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);\n }\n const res = await f(url.toString(), {\n method: \"GET\",\n headers: headers(t.apiKey),\n });\n const data = (await res.json()) as Record<string, unknown>;\n if (!res.ok) {\n const err = (data[\"error\"] as Record<string, unknown>) ?? {};\n throw new AtlaSentError(\n String(err[\"message\"] ?? `GET ${path} failed (${res.status})`),\n { status: res.status },\n );\n }\n return data;\n}\n\nasync function doDelete(\n t: V2Transport,\n path: string,\n body: unknown,\n): Promise<void> {\n const f = pickFetch(t);\n const res = await f(`${t.baseUrl}${path}`, {\n method: \"DELETE\",\n headers: headers(t.apiKey),\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n const data = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n const err = (data[\"error\"] as Record<string, unknown>) ?? {};\n throw new AtlaSentError(\n String(err[\"message\"] ?? `DELETE ${path} failed (${res.status})`),\n { status: res.status },\n );\n }\n}\n\n// ── Client ────────────────────────────────────────────────────────────────────\n\n/** Runtime v2 client — four-plane authorized-state-change lifecycle. */\nexport class RuntimeV2Client {\n constructor(private readonly transport: V2Transport) {}\n\n // ── Control plane ────────────────────────────────────────────────────────────\n\n /** `POST /v2/orgs/:orgId/transitions` */\n async authorize(\n orgId: string,\n request: Record<string, unknown>,\n ): Promise<AuthorizationDecision> {\n const data = await doPost(this.transport, orgPath(orgId, \"transitions\"), request);\n const permit = data[\"permit\"] as Record<string, unknown> | undefined;\n const code = data[\"code\"] as string | undefined;\n const message = data[\"message\"] as string | undefined;\n return {\n status: data[\"status\"] as AuthorizationDecision[\"status\"],\n ...(permit !== undefined ? { permit } : {}),\n required_approvers: (data[\"required_approvers\"] as string[] | undefined) ?? [],\n reasons: (data[\"reasons\"] as string[] | undefined) ?? [],\n policy_ids: (data[\"policy_ids\"] as string[] | undefined) ?? [],\n ...(code !== undefined ? { code } : {}),\n ...(message !== undefined ? { message } : {}),\n };\n }\n\n // ── Permit plane ─────────────────────────────────────────────────────────────\n\n /** `GET /v2/orgs/:orgId/permits/:permitId` */\n async getPermit(\n orgId: string,\n permitId: string,\n ): Promise<Record<string, unknown> | null> {\n const data = await doGet(this.transport, orgPath(orgId, \"permits\", permitId));\n return (data[\"permit\"] as Record<string, unknown>) ?? null;\n }\n\n /** `POST /v2/orgs/:orgId/permits/:permitId/consume` */\n async consume(\n orgId: string,\n permitId: string,\n observedSourceFingerprint: string,\n ): Promise<VerificationResult> {\n const data = await doPost(\n this.transport,\n orgPath(orgId, \"permits\", permitId, \"consume\"),\n { observed_source_fingerprint: observedSourceFingerprint },\n );\n return {\n passed: Boolean(data[\"passed\"]),\n verified_at: String(data[\"verified_at\"] ?? \"\"),\n failures: ((data[\"failures\"] as VerificationFailure[]) ?? []),\n warnings: ((data[\"warnings\"] as Array<Record<string, unknown>>) ?? []),\n };\n }\n\n /** `POST /v2/orgs/:orgId/permits/:permitId/approve` */\n async approve(\n orgId: string,\n permitId: string,\n approverDid: string,\n signature: string,\n comment?: string,\n ): Promise<{ approved: boolean; status: string }> {\n const body: Record<string, unknown> = { approver_did: approverDid, signature };\n if (comment !== undefined) body[\"comment\"] = comment;\n const data = await doPost(\n this.transport,\n orgPath(orgId, \"permits\", permitId, \"approve\"),\n body,\n );\n return {\n approved: Boolean(data[\"approved\"]),\n status: String(data[\"status\"] ?? \"\"),\n };\n }\n\n /** `POST /v2/orgs/:orgId/permits/:permitId/complete` */\n async complete(\n orgId: string,\n permitId: string,\n evidenceId: string,\n observedPostFingerprint: string,\n ): Promise<PostExecutionResult> {\n const data = await doPost(\n this.transport,\n orgPath(orgId, \"permits\", permitId, \"complete\"),\n { evidence_id: evidenceId, observed_post_fingerprint: observedPostFingerprint },\n );\n const rd = data[\"receipt\"] as Record<string, unknown> | undefined;\n const receipt: ExecutionReceipt | undefined = rd\n ? {\n receipt_id: String(rd[\"receipt_id\"] ?? \"\"),\n permit_id: String(rd[\"permit_id\"] ?? \"\"),\n org_id: String(rd[\"org_id\"] ?? \"\"),\n issued_at: String(rd[\"issued_at\"] ?? \"\"),\n post_state_fingerprint: String(rd[\"post_state_fingerprint\"] ?? \"\"),\n evidence_id: String(rd[\"evidence_id\"] ?? \"\"),\n }\n : undefined;\n return {\n verified: Boolean(data[\"verified\"]),\n evidence_completeness: (data[\"evidence_completeness\"] as PostExecutionResult[\"evidence_completeness\"]) ?? \"FAILED\",\n failures: ((data[\"failures\"] as VerificationFailure[]) ?? []),\n ...(receipt !== undefined ? { receipt } : {}),\n };\n }\n\n /** `DELETE /v2/orgs/:orgId/permits/:permitId` */\n async revokePermit(\n orgId: string,\n permitId: string,\n revokedBy: string,\n reason: string,\n propagatesToChildren = false,\n ): Promise<void> {\n await doDelete(\n this.transport,\n orgPath(orgId, \"permits\", permitId),\n { revoked_by: revokedBy, reason, propagates_to_children: propagatesToChildren },\n );\n }\n\n // ── Authority plane ──────────────────────────────────────────────────────────\n\n /** `GET /v2/orgs/:orgId/authorities` */\n async listAuthorities(\n orgId: string,\n includeInactive = false,\n ): Promise<AuthorityRecord[]> {\n const params: Record<string, string> = {};\n if (includeInactive) params[\"include_inactive\"] = \"true\";\n const data = await doGet(this.transport, orgPath(orgId, \"authorities\"), params);\n return (data[\"authorities\"] as AuthorityRecord[]) ?? [];\n }\n\n /** `POST /v2/orgs/:orgId/authorities` */\n async createAuthority(\n orgId: string,\n record: Record<string, unknown>,\n ): Promise<AuthorityRecord> {\n const data = await doPost(this.transport, orgPath(orgId, \"authorities\"), record);\n return (data[\"authority\"] ?? data) as AuthorityRecord;\n }\n\n /** `GET /v2/orgs/:orgId/authorities/:authorityId` */\n async getAuthority(\n orgId: string,\n authorityId: string,\n ): Promise<AuthorityRecord | null> {\n const data = await doGet(this.transport, orgPath(orgId, \"authorities\", authorityId));\n return (data[\"authority\"] as AuthorityRecord) ?? null;\n }\n\n /** `POST /v2/orgs/:orgId/authorities/:authorityId/rotate` */\n async rotateAuthority(\n orgId: string,\n authorityId: string,\n newPublicKey: string,\n newKeyId: string,\n ): Promise<AuthorityRecord> {\n const data = await doPost(\n this.transport,\n orgPath(orgId, \"authorities\", authorityId, \"rotate\"),\n { new_public_key: newPublicKey, new_key_id: newKeyId },\n );\n return (data[\"authority\"] ?? data) as AuthorityRecord;\n }\n\n /** `POST /v2/orgs/:orgId/authorities/:authorityId/revoke` */\n async revokeAuthority(\n orgId: string,\n authorityId: string,\n reason: string,\n ): Promise<void> {\n await doPost(\n this.transport,\n orgPath(orgId, \"authorities\", authorityId, \"revoke\"),\n { reason },\n );\n }\n\n // ── Evidence plane ───────────────────────────────────────────────────────────\n\n /** `POST /v2/orgs/:orgId/evidence` */\n async submitEvidence(\n orgId: string,\n pkg: Record<string, unknown>,\n ): Promise<void> {\n await doPost(this.transport, orgPath(orgId, \"evidence\"), pkg);\n }\n\n /** `GET /v2/orgs/:orgId/evidence/:evidenceId` */\n async getEvidence(\n orgId: string,\n evidenceId: string,\n ): Promise<Record<string, unknown> | null> {\n const data = await doGet(\n this.transport,\n orgPath(orgId, \"evidence\", evidenceId),\n );\n return (data[\"evidence\"] as Record<string, unknown>) ?? null;\n }\n\n /** `GET /v2/orgs/:orgId/audit-chain` */\n async queryAuditChain(\n orgId: string,\n from: string,\n to: string,\n options?: AuditChainFilters & { page?: number; page_size?: number },\n ): Promise<AuditChainPage> {\n const params: Record<string, string> = { from, to };\n if (options?.page !== undefined) params[\"page\"] = String(options.page);\n if (options?.page_size !== undefined) params[\"page_size\"] = String(options.page_size);\n if (options?.action_class) params[\"action_class\"] = options.action_class;\n if (options?.principal_did) params[\"principal_did\"] = options.principal_did;\n if (options?.resource_locator) params[\"resource_locator\"] = options.resource_locator;\n const data = await doGet(this.transport, orgPath(orgId, \"audit-chain\"), params);\n return {\n entries: (data[\"entries\"] as RuntimeAuditEntry[]) ?? [],\n total: Number(data[\"total\"] ?? 0),\n page: Number(data[\"page\"] ?? 1),\n page_size: Number(data[\"page_size\"] ?? 100),\n };\n }\n\n /** `GET /v2/orgs/:orgId/audit-chain/integrity` */\n async verifyChainIntegrity(\n orgId: string,\n fromSequence: number,\n toSequence: number,\n ): Promise<ChainIntegrityReport> {\n const data = await doGet(\n this.transport,\n orgPath(orgId, \"audit-chain\", \"integrity\"),\n { from_sequence: String(fromSequence), to_sequence: String(toSequence) },\n );\n return {\n valid: Boolean(data[\"valid\"]),\n checked_entries: Number(data[\"checked_entries\"] ?? 0),\n first_sequence: Number(data[\"first_sequence\"] ?? fromSequence),\n last_sequence: Number(data[\"last_sequence\"] ?? toSequence),\n gaps: (data[\"gaps\"] as number[]) ?? [],\n invalid_hashes: (data[\"invalid_hashes\"] as number[]) ?? [],\n verified_at: String(data[\"verified_at\"] ?? \"\"),\n };\n }\n\n /** `POST /v2/orgs/:orgId/compliance-export` */\n async exportCompliance(\n orgId: string,\n from: string,\n to: string,\n format: \"JSON\" | \"CSV\" | \"CISA_SBOM\" = \"JSON\",\n ): Promise<ComplianceExport> {\n const data = await doPost(\n this.transport,\n orgPath(orgId, \"compliance-export\"),\n { from, to, format },\n );\n return {\n export_id: String(data[\"export_id\"] ?? \"\"),\n org_id: String(data[\"org_id\"] ?? orgId),\n from: String(data[\"from\"] ?? from),\n to: String(data[\"to\"] ?? to),\n entry_count: Number(data[\"entry_count\"] ?? 0),\n format: String(data[\"format\"] ?? format),\n content_ref: String(data[\"content_ref\"] ?? \"\"),\n content_hash: String(data[\"content_hash\"] ?? \"\"),\n generated_at: String(data[\"generated_at\"] ?? \"\"),\n signed_by: String(data[\"signed_by\"] ?? \"\"),\n };\n }\n}\n","export type EnforcementMode = \"observe\" | \"warn\" | \"enforce\";\n\nexport interface HealthReport {\n readonly healthy: boolean;\n readonly apiReachable: boolean;\n readonly authenticated: boolean;\n readonly latencyMs: number | null;\n readonly apiVersion: string | null;\n readonly checkedAt: string;\n readonly errors: string[];\n}\n\nexport interface EnforcementStatus {\n readonly actionClass: string;\n readonly mode: EnforcementMode;\n readonly blockRate: number | null;\n readonly totalEvaluations: number | null;\n readonly lastSeenAt: string | null;\n readonly schemaRegistered: boolean;\n}\n\nexport interface ProtectedActionEntry {\n readonly actionClass: string;\n readonly firstRegisteredAt: string;\n readonly lastUpdatedAt: string;\n readonly enforcementMode: EnforcementMode;\n readonly schemaId: string | null;\n readonly tags: string[];\n}\n\nexport interface OrgSummary {\n readonly orgId: string;\n readonly activePolicies: number;\n readonly totalPolicies: number;\n readonly activeOverrides: number;\n readonly pendingEscalations: number;\n readonly evidenceSigningEnabled: boolean;\n readonly shadowModeActions: number;\n readonly enforcedActions: number;\n readonly lastEvaluationAt: string | null;\n}\n\nexport interface ControlSurfaceConfig {\n apiKey?: string;\n baseUrl?: string;\n timeoutMs?: number;\n}\n\nlet _config: ControlSurfaceConfig = {};\n\nexport function configureControlSurface(config: ControlSurfaceConfig): void {\n _config = { ..._config, ...config };\n}\n\nfunction resolveConfig(opts?: ControlSurfaceConfig): Required<ControlSurfaceConfig> {\n return {\n apiKey: opts?.apiKey ?? _config.apiKey ?? process.env[\"ATLASENT_API_KEY\"] ?? \"\",\n baseUrl: opts?.baseUrl ?? _config.baseUrl ?? process.env[\"ATLASENT_BASE_URL\"] ?? \"https://api.atlasent.ai\",\n timeoutMs: opts?.timeoutMs ?? _config.timeoutMs ?? 10_000,\n };\n}\n\nasync function apiGet<T>(\n path: string,\n config: Required<ControlSurfaceConfig>,\n): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), config.timeoutMs);\n try {\n const res = await fetch(`${config.baseUrl}${path}`, {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${config.apiKey}`,\n Accept: \"application/json\",\n },\n signal: controller.signal,\n });\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}`);\n }\n return res.json() as Promise<T>;\n } finally {\n clearTimeout(timer);\n }\n}\n\nasync function apiPost<T>(\n path: string,\n body: unknown,\n config: Required<ControlSurfaceConfig>,\n): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), config.timeoutMs);\n try {\n const res = await fetch(`${config.baseUrl}${path}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${config.apiKey}`,\n },\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}`);\n }\n return res.json() as Promise<T>;\n } finally {\n clearTimeout(timer);\n }\n}\n\nexport async function checkIntegrationHealth(\n opts?: ControlSurfaceConfig,\n): Promise<HealthReport> {\n const config = resolveConfig(opts);\n const errors: string[] = [];\n let apiReachable = false;\n let authenticated = false;\n let latencyMs: number | null = null;\n let apiVersion: string | null = null;\n\n if (!config.apiKey) {\n errors.push(\"ATLASENT_API_KEY is not configured\");\n }\n\n const start = Date.now();\n try {\n const data = await apiGet<{ version?: string; status?: string }>(\"/v1/health\", config);\n latencyMs = Date.now() - start;\n apiReachable = true;\n apiVersion = data.version ?? null;\n if (data.status === \"ok\" || data.status === \"healthy\") {\n authenticated = true;\n } else {\n errors.push(`API health status: ${data.status ?? \"unknown\"}`);\n }\n } catch (err) {\n latencyMs = Date.now() - start;\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes(\"401\") || message.includes(\"403\")) {\n apiReachable = true;\n errors.push(\"API key is invalid or lacks required permissions\");\n } else {\n errors.push(`API unreachable: ${message}`);\n }\n }\n\n return {\n healthy: apiReachable && authenticated && errors.length === 0,\n apiReachable,\n authenticated,\n latencyMs,\n apiVersion,\n checkedAt: new Date().toISOString(),\n errors,\n };\n}\n\nexport interface ReportProtectedActionOptions extends ControlSurfaceConfig {\n actionClass: string;\n enforcementMode?: EnforcementMode;\n schemaId?: string;\n tags?: string[];\n}\n\nexport async function reportProtectedAction(\n opts: ReportProtectedActionOptions,\n): Promise<ProtectedActionEntry> {\n const config = resolveConfig(opts);\n return apiPost<ProtectedActionEntry>(\n \"/v1/control-surface/actions\",\n {\n action_class: opts.actionClass,\n enforcement_mode: opts.enforcementMode ?? \"observe\",\n schema_id: opts.schemaId ?? null,\n tags: opts.tags ?? [],\n },\n config,\n );\n}\n\nexport interface GetEnforcementStatusOptions extends ControlSurfaceConfig {\n actionClass: string;\n}\n\nexport async function getEnforcementStatus(\n opts: GetEnforcementStatusOptions,\n): Promise<EnforcementStatus> {\n const config = resolveConfig(opts);\n return apiGet<EnforcementStatus>(\n `/v1/control-surface/actions/${encodeURIComponent(opts.actionClass)}/status`,\n config,\n );\n}\n\nexport async function getOrgSummary(\n opts?: ControlSurfaceConfig,\n): Promise<OrgSummary> {\n const config = resolveConfig(opts);\n return apiGet<OrgSummary>(\"/v1/control-surface/summary\", config);\n}\n","/**\n * Claims → Evidence Lineage\n *\n * Builds and verifies {@link ClaimEvidenceLink} objects — signed, wire-stable\n * artifacts that tie a canonical claim row to its full evidence chain:\n *\n * 1. **`runtime_evidence`** — {@link DecisionReceipt} from `protectWithEvidence()`\n * 2. **`deploy_evidence`** — `protectDeploy()` gate record\n * 3. **`integration_evidence`** — `ComplianceEvidenceRun` summary\n * 4. **`approval_artifact`** — HITL chain or ApprovalArtifact summary\n * 5. **`delta`** — policy + schema drift since the claim was asserted\n * 6. **`verification_checklist`** — machine-auditable `all_pass` + per-slot status\n *\n * Wire schema: `contract/schemas/claim-evidence-link.schema.json`\n * Proposal: `contract/PROPOSALS/004-claims-evidence-links.md`\n *\n * @module\n */\n\nimport { createHmac, randomUUID } from \"node:crypto\";\nimport type { DecisionReceipt, DecisionReceiptAlgorithm } from \"./evidenceEngine.js\";\nimport type { ComplianceEvidenceRun } from \"./complianceEvidence.js\";\nimport type { HitlEscalation, HitlApprovalRecord } from \"./hitl.js\";\nimport { AtlaSentError } from \"./errors.js\";\n\n// ── Evidence slot wire types ──────────────────────────────────────────────────\n\nexport interface RuntimeEvidenceSlot {\n readonly permit_token: string;\n readonly audit_hash: string;\n readonly decision: \"allow\" | \"deny\" | \"escalate\";\n readonly decision_id: string;\n readonly evaluated_at: string;\n readonly algorithm: DecisionReceiptAlgorithm;\n readonly signature: string | null;\n readonly permit_revoked_at: string | null;\n readonly verified_at_claim_time: boolean;\n readonly verified_at_link_creation: boolean;\n}\n\nexport interface DeployEvidenceSlot {\n readonly deploy_id: string;\n readonly environment: string;\n readonly sha: string;\n readonly actor_id: string;\n readonly deployed_at: string;\n readonly gate_permit_token: string;\n}\n\nexport interface IntegrationEvidenceSlot {\n readonly run_id: string;\n readonly framework: \"soc2\" | \"iso27001\" | \"hipaa\" | \"pci_dss\" | \"gdpr\" | \"fedramp\";\n readonly period_start: string;\n readonly period_end: string;\n readonly status: \"pending\" | \"running\" | \"completed\" | \"failed\";\n readonly passing_control_count: number;\n readonly failing_control_count: number;\n readonly run_completed_at: string;\n}\n\nexport interface ApprovalArtifactSlot {\n readonly approval_id: string;\n readonly approval_kind: \"hitl_chain\" | \"approval_artifact\";\n readonly quorum_type: \"single_approver\" | \"simple_majority\" | \"two_thirds\" | \"unanimous\";\n readonly approver_count: number;\n readonly approver_ids: readonly string[];\n readonly approved_at: string;\n readonly artifact_hash: string;\n}\n\nexport type DriftChangeType =\n | \"rule_added\"\n | \"rule_removed\"\n | \"rule_modified\"\n | \"threshold_changed\"\n | \"policy_updated\"\n | \"schema_field_added\"\n | \"schema_field_removed\"\n | \"schema_field_type_changed\";\n\nexport type DriftSeverity = \"info\" | \"warning\" | \"critical\";\n\nexport interface DriftDetail {\n readonly change_type: DriftChangeType;\n readonly severity: DriftSeverity;\n readonly rule_id: string | null;\n readonly changed_at: string | null;\n readonly description: string;\n}\n\nexport type DeltaStatus = \"pending\" | \"computing\" | \"computed\" | \"failed\";\n\nexport interface DeltaSlot {\n readonly status: DeltaStatus;\n readonly computed_at: string | null;\n readonly policy_version_at_claim: string | null;\n readonly policy_version_current: string | null;\n readonly policy_drift_detected: boolean | null;\n readonly schema_version_at_claim: string;\n readonly schema_version_current: string;\n readonly schema_drift_detected: boolean;\n readonly drift_details: readonly DriftDetail[];\n}\n\nexport type EvidenceSlotStatus = \"present\" | \"not_applicable\" | \"missing\";\n\nexport interface VerificationChecklist {\n readonly runtime_evidence_present: boolean;\n readonly verified_at_claim_time: boolean;\n readonly verified_at_link_creation: boolean;\n readonly deploy_evidence_status: EvidenceSlotStatus;\n readonly integration_evidence_status: EvidenceSlotStatus;\n readonly approval_artifact_status: EvidenceSlotStatus;\n readonly delta_computed: boolean;\n readonly policy_drift_clean: boolean | null;\n readonly schema_drift_clean: boolean;\n readonly all_pass: boolean;\n readonly last_verified_at: string | null;\n readonly computed_at: string;\n}\n\nexport interface ClaimEvidenceLink {\n readonly version: \"claim_evidence_link.v1\";\n readonly link_id: string;\n readonly claim_id: string;\n readonly org_id: string;\n readonly linked_at: string;\n readonly updated_at: string;\n readonly revision: number;\n readonly link_algorithm: \"hmac-sha256\" | \"none\";\n readonly link_hash: string;\n readonly link_signature: string | null;\n readonly runtime_evidence: RuntimeEvidenceSlot;\n readonly deploy_evidence: DeployEvidenceSlot | null;\n readonly integration_evidence: IntegrationEvidenceSlot | null;\n readonly approval_artifact: ApprovalArtifactSlot | null;\n readonly delta: DeltaSlot;\n readonly verification_checklist: VerificationChecklist;\n}\n\n// ── Slot input types ──────────────────────────────────────────────────────────\n\n/** Caller signals evidence does not apply to this claim. */\nexport interface NotApplicable {\n readonly notApplicable: true;\n}\n\nexport const NOT_APPLICABLE: NotApplicable = { notApplicable: true };\n\nfunction isNotApplicable(v: unknown): v is NotApplicable {\n return typeof v === \"object\" && v !== null && (v as NotApplicable).notApplicable === true;\n}\n\n/** Raw deploy gate inputs — caller supplies at minimum environment + service. */\nexport interface DeployEvidenceInput {\n readonly deploy_id: string;\n readonly environment: string;\n readonly sha: string;\n readonly actor_id: string;\n readonly deployed_at: string;\n readonly gate_permit_token: string;\n}\n\n/** Summary from a HITL chain (derived from HitlEscalation + approval records). */\nexport interface HitlChainSummary {\n readonly escalation: HitlEscalation;\n readonly approvals: readonly HitlApprovalRecord[];\n /** SHA-256 hex of the canonical JSON of the full chain object. */\n readonly artifact_hash: string;\n}\n\n/** Out-of-band approval artifact (pre-signed). */\nexport interface SignedApprovalArtifact {\n readonly approval_id: string;\n readonly approval_kind: \"approval_artifact\";\n readonly quorum_type: \"single_approver\" | \"simple_majority\" | \"two_thirds\" | \"unanimous\";\n readonly approver_ids: readonly string[];\n readonly approved_at: string;\n /** SHA-256 hex of the canonical encoding of the full artifact. */\n readonly artifact_hash: string;\n}\n\nexport interface BuildClaimEvidenceLinkOpts {\n /** The canonical claim ID this link annotates. */\n readonly claimId: string;\n /**\n * The org that owns the claim. Defaults to `receipt.org_id` from\n * `runtimeEvidence` when omitted.\n */\n readonly orgId?: string;\n /** DecisionReceipt from `protectWithEvidence()`. Required. */\n readonly runtimeEvidence: DecisionReceipt;\n /**\n * Deploy gate record. Pass `NOT_APPLICABLE` for non-deployment actions.\n * Omit (or pass `undefined`) when the deploy record was expected but\n * unavailable — the slot status will be `\"missing\"` and `all_pass`\n * will be `false`.\n */\n readonly deployEvidence?: DeployEvidenceInput | NotApplicable;\n /**\n * Most recent compliance run covering the claim period. Pass\n * `NOT_APPLICABLE` when no compliance run applies.\n */\n readonly integrationEvidence?: ComplianceEvidenceRun | NotApplicable;\n /**\n * HITL chain summary or out-of-band approval artifact. Pass\n * `NOT_APPLICABLE` when no human approval was required.\n */\n readonly approvalArtifact?: HitlChainSummary | SignedApprovalArtifact | NotApplicable;\n /**\n * HMAC-SHA256 signing secret. When provided the link is signed and\n * `link_algorithm` is `\"hmac-sha256\"`. Omit for unsigned links\n * (`link_algorithm: \"none\"`).\n */\n readonly signingSecret?: string;\n /**\n * Override the schema version recorded in `delta.schema_version_at_claim`.\n * Defaults to the SDK package version embedded at build time.\n */\n readonly schemaVersion?: string;\n}\n\nexport interface VerifyClaimEvidenceLinkOpts {\n /**\n * Signing secret used to re-verify `link_signature`. Required when\n * `link.link_algorithm` is `\"hmac-sha256\"`.\n */\n readonly signingSecret?: string;\n /**\n * When true, skips re-calling `/v1-verify-permit` even if a client is\n * provided. Useful when the permit is known to be expired and you only\n * want to check structural integrity.\n */\n readonly skipPermitRecheck?: boolean;\n}\n\nexport interface VerifyClaimEvidenceLinkResult {\n /** Updated link with refreshed checklist, incremented revision, and recomputed hash. */\n readonly link: ClaimEvidenceLink;\n readonly valid: boolean;\n /** Names of verification_checklist fields that are false or \"missing\". */\n readonly failedSlots: readonly string[];\n}\n\n// ── Action bundle input types ─────────────────────────────────────────────────\n\n/**\n * Subset of an `ActionEvidenceBundle.receipt` produced by the AtlaSent\n * GitHub Action (atlasent-action `evidenceBundle.ts`).\n *\n * Only the fields consumed by {@link buildClaimEvidenceLinkFromActionBundle}\n * are required here; the full receipt shape lives in the action repo.\n */\nexport interface ActionBundleReceipt {\n readonly receipt_id: string;\n readonly evaluation_id: string;\n readonly permit_id: string | null;\n readonly audit_hash: string | null;\n readonly issued_at: string;\n readonly algorithm: \"hmac-sha256\" | \"none\";\n readonly signature: string | null;\n readonly decision: \"allow\";\n}\n\n/**\n * Minimal shape of an `ActionEvidenceBundle` emitted by the AtlaSent\n * GitHub Action as its `evidence-bundle` output. Pass the parsed JSON\n * directly; no re-shaping needed.\n */\nexport interface ActionBundleInput {\n readonly bundle_id: string;\n readonly action: string;\n readonly actor: string;\n readonly environment: string;\n readonly repository: string;\n readonly sha: string;\n readonly run_id: string;\n readonly generated_at: string;\n readonly receipt: ActionBundleReceipt;\n}\n\nexport interface BuildFromActionBundleOpts {\n /** The canonical claim ID this link annotates. */\n readonly claimId: string;\n /** Owning org. Defaults to `\"\"` for v1 (no org context on the action). */\n readonly orgId?: string;\n /**\n * Set to `true` when the bundle does NOT represent a deploy action.\n * The deploy slot will be `NOT_APPLICABLE` instead of auto-populated\n * from `bundle.sha` / `bundle.environment`.\n */\n readonly deployNotApplicable?: boolean;\n readonly signingSecret?: string;\n readonly schemaVersion?: string;\n}\n\n// ── SDK version ───────────────────────────────────────────────────────────────\n\nconst SDK_VERSION = \"@atlasent/sdk@1.4.2\";\n\n// ── Canonical serialisation ───────────────────────────────────────────────────\n\nfunction canonicalize(value: unknown): string {\n if (value === null || value === undefined) return \"null\";\n if (typeof value === \"number\") return Number.isFinite(value) ? String(value) : \"null\";\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n if (typeof value === \"string\") return JSON.stringify(value);\n if (Array.isArray(value)) return \"[\" + value.map(canonicalize).join(\",\") + \"]\";\n if (typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n return \"{\" + keys.map((k) => JSON.stringify(k) + \":\" + canonicalize(obj[k])).join(\",\") + \"}\";\n }\n return \"null\";\n}\n\nfunction sha256Hex(input: string): string {\n const { createHash } = require(\"node:crypto\") as typeof import(\"node:crypto\");\n return createHash(\"sha256\").update(input).digest(\"hex\");\n}\n\nfunction hmacSha256Base64url(payload: string, secret: string): string {\n return createHmac(\"sha256\", secret)\n .update(payload)\n .digest(\"base64url\");\n}\n\nfunction computeLinkHash(link: Omit<ClaimEvidenceLink, \"link_hash\" | \"link_signature\">): string {\n return sha256Hex(canonicalize(link));\n}\n\n// ── Slot converters ───────────────────────────────────────────────────────────\n\nfunction slotStatus(\n input: unknown | NotApplicable | undefined,\n slot: DeployEvidenceSlot | IntegrationEvidenceSlot | ApprovalArtifactSlot | null,\n): EvidenceSlotStatus {\n if (isNotApplicable(input)) return \"not_applicable\";\n if (slot !== null) return \"present\";\n return \"missing\";\n}\n\nfunction toDeploySlot(input: DeployEvidenceInput | NotApplicable | undefined): DeployEvidenceSlot | null {\n if (input === undefined || isNotApplicable(input)) return null;\n return {\n deploy_id: input.deploy_id,\n environment: input.environment,\n sha: input.sha,\n actor_id: input.actor_id,\n deployed_at: input.deployed_at,\n gate_permit_token: input.gate_permit_token,\n };\n}\n\nfunction toIntegrationSlot(\n input: ComplianceEvidenceRun | NotApplicable | undefined,\n): IntegrationEvidenceSlot | null {\n if (input === undefined || isNotApplicable(input)) return null;\n const run = input as ComplianceEvidenceRun;\n return {\n run_id: run.id,\n framework: run.framework as IntegrationEvidenceSlot[\"framework\"],\n period_start: run.period_start,\n period_end: run.period_end,\n status: run.status as IntegrationEvidenceSlot[\"status\"],\n passing_control_count: (run.controls ?? []).filter((c) => c.status === \"pass\").length,\n failing_control_count: (run.controls ?? []).filter((c) => c.status !== \"pass\").length,\n run_completed_at: run.created_at,\n };\n}\n\nfunction toApprovalSlot(\n input: HitlChainSummary | SignedApprovalArtifact | NotApplicable | undefined,\n): ApprovalArtifactSlot | null {\n if (input === undefined || isNotApplicable(input)) return null;\n\n if (\"escalation\" in input) {\n const chain = input as HitlChainSummary;\n const approvals = chain.approvals;\n const lastApproved = approvals\n .filter((a) => a.decision === \"approve\")\n .map((a) => a.created_at)\n .sort()\n .at(-1) ?? chain.escalation.created_at;\n return {\n approval_id: chain.escalation.id,\n approval_kind: \"hitl_chain\",\n quorum_type: hitlQuorumToSlotQuorum(chain.escalation.quorum_required),\n approver_count: approvals.filter((a) => a.decision === \"approve\").length,\n approver_ids: approvals\n .filter((a) => a.decision === \"approve\")\n .map((a) => a.user_id ?? a.actor_label ?? \"unknown\"),\n approved_at: lastApproved,\n artifact_hash: chain.artifact_hash,\n };\n }\n\n const artifact = input as SignedApprovalArtifact;\n return {\n approval_id: artifact.approval_id,\n approval_kind: \"approval_artifact\",\n quorum_type: artifact.quorum_type,\n approver_count: artifact.approver_ids.length,\n approver_ids: artifact.approver_ids,\n approved_at: artifact.approved_at,\n artifact_hash: artifact.artifact_hash,\n };\n}\n\nfunction hitlQuorumToSlotQuorum(\n tier: string,\n): ApprovalArtifactSlot[\"quorum_type\"] {\n switch (tier) {\n case \"single_approver\": return \"single_approver\";\n case \"two_thirds\": return \"two_thirds\";\n case \"unanimous\": return \"unanimous\";\n default: return \"simple_majority\";\n }\n}\n\nfunction toRuntimeSlot(receipt: DecisionReceipt, verifiedAtCreation: boolean): RuntimeEvidenceSlot {\n return {\n permit_token: receipt.permit_id ?? receipt.receipt_id,\n audit_hash: receipt.audit_hash,\n decision: receipt.decision === \"allow\" ? \"allow\"\n : receipt.decision === \"escalate\" ? \"escalate\"\n : \"deny\",\n decision_id: receipt.evaluation_id,\n evaluated_at: receipt.issued_at,\n algorithm: receipt.algorithm,\n signature: receipt.signature,\n permit_revoked_at: null,\n verified_at_claim_time: receipt.decision === \"allow\",\n verified_at_link_creation: verifiedAtCreation,\n };\n}\n\n// ── Checklist builder ─────────────────────────────────────────────────────────\n\nfunction buildChecklist(\n runtime: RuntimeEvidenceSlot,\n deployStatus: EvidenceSlotStatus,\n integrationStatus: EvidenceSlotStatus,\n approvalStatus: EvidenceSlotStatus,\n delta: DeltaSlot,\n lastVerifiedAt: string | null,\n now: string,\n): VerificationChecklist {\n const deltaComputed = delta.status === \"computed\";\n const policyDriftClean = deltaComputed ? !delta.policy_drift_detected : null;\n const schemaDriftClean = !delta.schema_drift_detected;\n\n const allPass =\n runtime.verified_at_claim_time &&\n runtime.verified_at_link_creation &&\n deltaComputed &&\n policyDriftClean === true &&\n schemaDriftClean &&\n deployStatus !== \"missing\" &&\n integrationStatus !== \"missing\" &&\n approvalStatus !== \"missing\";\n\n return {\n runtime_evidence_present: true,\n verified_at_claim_time: runtime.verified_at_claim_time,\n verified_at_link_creation: runtime.verified_at_link_creation,\n deploy_evidence_status: deployStatus,\n integration_evidence_status: integrationStatus,\n approval_artifact_status: approvalStatus,\n delta_computed: deltaComputed,\n policy_drift_clean: policyDriftClean,\n schema_drift_clean: schemaDriftClean,\n all_pass: allPass,\n last_verified_at: lastVerifiedAt,\n computed_at: now,\n };\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Assemble a {@link ClaimEvidenceLink} from already-fetched SDK artifacts.\n *\n * - Generates a client-side `link_id` (`cel_` + UUID v4).\n * - Computes schema drift from the SDK version; policy drift is set to\n * `delta.status: \"pending\"` (server-side, async).\n * - Signs the link with HMAC-SHA256 when `signingSecret` is provided.\n * - `verified_at_link_creation` is set to `true` when the receipt carries a\n * `decision === \"allow\"` (the permit was valid at the moment we're building\n * the link, since it was just produced by `protectWithEvidence()`).\n *\n * The returned link has `revision: 1`. Subsequent calls to\n * {@link verifyClaimEvidenceLink} increment `revision` and recompute\n * `link_hash` / `link_signature`.\n */\nexport function buildClaimEvidenceLink(opts: BuildClaimEvidenceLinkOpts): ClaimEvidenceLink {\n const now = new Date().toISOString();\n const linkId = `cel_${randomUUID().replace(/-/g, \"\")}`;\n const orgId = opts.orgId ?? opts.runtimeEvidence.org_id;\n const schemaVersion = opts.schemaVersion ?? SDK_VERSION;\n\n const deploySlot = toDeploySlot(opts.deployEvidence);\n const integrationSlot = toIntegrationSlot(opts.integrationEvidence);\n const approvalSlot = toApprovalSlot(opts.approvalArtifact);\n\n const deployStatus = slotStatus(opts.deployEvidence, deploySlot);\n const integrationStatus = slotStatus(opts.integrationEvidence, integrationSlot);\n const approvalStatus = slotStatus(opts.approvalArtifact, approvalSlot);\n\n // verified_at_link_creation: true only if the decision was allow (permit is fresh)\n const verifiedAtCreation = opts.runtimeEvidence.decision === \"allow\";\n const runtime = toRuntimeSlot(opts.runtimeEvidence, verifiedAtCreation);\n\n const delta: DeltaSlot = {\n status: \"pending\",\n computed_at: null,\n policy_version_at_claim: null,\n policy_version_current: null,\n policy_drift_detected: null,\n schema_version_at_claim: schemaVersion,\n schema_version_current: schemaVersion,\n schema_drift_detected: false,\n drift_details: [],\n };\n\n const lastVerifiedAt = verifiedAtCreation ? now : null;\n const checklist = buildChecklist(\n runtime, deployStatus, integrationStatus, approvalStatus, delta, lastVerifiedAt, now,\n );\n\n const linkAlgorithm: ClaimEvidenceLink[\"link_algorithm\"] =\n opts.signingSecret ? \"hmac-sha256\" : \"none\";\n\n // Build the signable body (everything except link_hash + link_signature)\n const body = {\n version: \"claim_evidence_link.v1\" as const,\n link_id: linkId,\n claim_id: opts.claimId,\n org_id: orgId,\n linked_at: now,\n updated_at: now,\n revision: 1,\n link_algorithm: linkAlgorithm,\n runtime_evidence: runtime,\n deploy_evidence: deploySlot,\n integration_evidence: integrationSlot,\n approval_artifact: approvalSlot,\n delta,\n verification_checklist: checklist,\n };\n\n const linkHash = computeLinkHash(body);\n const linkSignature = opts.signingSecret\n ? hmacSha256Base64url(linkHash, opts.signingSecret)\n : null;\n\n return { ...body, link_hash: linkHash, link_signature: linkSignature };\n}\n\n/**\n * Verify the structural integrity and checklist freshness of a\n * {@link ClaimEvidenceLink}.\n *\n * Checks:\n * 1. `link_hash` matches a canonical re-serialisation of the link content.\n * 2. `link_signature` verifies under `link_algorithm` (when not `\"none\"`).\n * 3. Recomputes the `verification_checklist` from the current slot state.\n *\n * Returns a new `ClaimEvidenceLink` with:\n * - Updated `verified_at_link_creation` / `last_verified_at` (permit may have\n * expired since the link was built — reflected in the updated checklist).\n * - Incremented `revision`.\n * - Recomputed `link_hash` / `link_signature` over the mutated content.\n *\n * Does **not** mutate the input. Does **not** make network calls (permit\n * re-verification via `/v1-verify-permit` is scoped for v2 once the server\n * endpoint ships).\n *\n * @throws {@link AtlaSentError} with `code: \"claim_evidence_incomplete\"` when\n * `all_pass` is false on the refreshed checklist.\n */\nexport function verifyClaimEvidenceLink(\n link: ClaimEvidenceLink,\n opts: VerifyClaimEvidenceLinkOpts = {},\n): VerifyClaimEvidenceLinkResult {\n const now = new Date().toISOString();\n\n // 1. Verify link_hash\n const { link_hash: _lh, link_signature: _ls, ...body } = link as unknown as Record<string, unknown>;\n const expectedHash = computeLinkHash(\n body as Omit<ClaimEvidenceLink, \"link_hash\" | \"link_signature\">,\n );\n const hashValid = expectedHash === link.link_hash;\n\n // 2. Verify signature\n let sigValid = true;\n if (link.link_algorithm === \"hmac-sha256\") {\n if (!opts.signingSecret) {\n sigValid = false;\n } else {\n const expected = hmacSha256Base64url(link.link_hash, opts.signingSecret);\n sigValid = expected === link.link_signature;\n }\n }\n\n // 3. Recompute checklist (permit re-verification deferred to v2)\n const runtime: RuntimeEvidenceSlot = {\n ...link.runtime_evidence,\n // If the link hash or signature is invalid, mark creation-time verification as failed\n verified_at_link_creation: hashValid && sigValid\n ? link.runtime_evidence.verified_at_link_creation\n : false,\n };\n\n const checklist = buildChecklist(\n runtime,\n link.verification_checklist.deploy_evidence_status,\n link.verification_checklist.integration_evidence_status,\n link.verification_checklist.approval_artifact_status,\n link.delta,\n runtime.verified_at_link_creation ? (link.verification_checklist.last_verified_at ?? now) : null,\n now,\n );\n\n // 4. Build updated link\n const updatedBody = {\n version: link.version,\n link_id: link.link_id,\n claim_id: link.claim_id,\n org_id: link.org_id,\n linked_at: link.linked_at,\n updated_at: now,\n revision: link.revision + 1,\n link_algorithm: link.link_algorithm,\n runtime_evidence: runtime,\n deploy_evidence: link.deploy_evidence,\n integration_evidence: link.integration_evidence,\n approval_artifact: link.approval_artifact,\n delta: link.delta,\n verification_checklist: checklist,\n };\n\n const newHash = computeLinkHash(updatedBody);\n const newSignature = opts.signingSecret\n ? hmacSha256Base64url(newHash, opts.signingSecret)\n : link.link_algorithm === \"none\" ? null : link.link_signature;\n\n const updatedLink: ClaimEvidenceLink = {\n ...updatedBody,\n link_hash: newHash,\n link_signature: newSignature,\n };\n\n // 5. Collect failed slots\n const failedSlots: string[] = [];\n if (!hashValid) failedSlots.push(\"link_hash\");\n if (!sigValid) failedSlots.push(\"link_signature\");\n if (!checklist.verified_at_claim_time) failedSlots.push(\"verified_at_claim_time\");\n if (!checklist.verified_at_link_creation) failedSlots.push(\"verified_at_link_creation\");\n if (!checklist.delta_computed) failedSlots.push(\"delta_computed\");\n if (checklist.policy_drift_clean === false) failedSlots.push(\"policy_drift_clean\");\n if (!checklist.schema_drift_clean) failedSlots.push(\"schema_drift_clean\");\n if (checklist.deploy_evidence_status === \"missing\") failedSlots.push(\"deploy_evidence_status\");\n if (checklist.integration_evidence_status === \"missing\") failedSlots.push(\"integration_evidence_status\");\n if (checklist.approval_artifact_status === \"missing\") failedSlots.push(\"approval_artifact_status\");\n\n const valid = failedSlots.length === 0;\n\n if (!valid) {\n throw new AtlaSentError(\n `ClaimEvidenceLink verification failed: ${failedSlots.join(\", \")}`,\n { code: \"claim_evidence_incomplete\" as never },\n );\n }\n\n return { link: updatedLink, valid, failedSlots };\n}\n\n/**\n * Build a {@link ClaimEvidenceLink} directly from the `evidence-bundle`\n * JSON emitted by the AtlaSent GitHub Action.\n *\n * ```ts\n * import { buildClaimEvidenceLinkFromActionBundle } from \"@atlasent/sdk\";\n *\n * const bundle = JSON.parse(process.env.ATLASENT_EVIDENCE_BUNDLE!);\n * const link = buildClaimEvidenceLinkFromActionBundle(bundle, {\n * claimId: myClaimId,\n * signingSecret: process.env.ATLASENT_SIGNING_SECRET,\n * });\n * ```\n *\n * The `receipt` fields map directly to the `runtime_evidence` slot. The\n * `bundle.sha` / `bundle.environment` / `bundle.actor` are used to\n * auto-populate the `deploy_evidence` slot — pass `deployNotApplicable: true`\n * to suppress this for non-deploy actions.\n */\nexport function buildClaimEvidenceLinkFromActionBundle(\n bundle: ActionBundleInput,\n opts: BuildFromActionBundleOpts,\n): ClaimEvidenceLink {\n const runtimeEvidence: DecisionReceipt = {\n receipt_id: bundle.receipt.receipt_id,\n evaluation_id: bundle.receipt.evaluation_id,\n org_id: opts.orgId ?? \"\",\n decision: bundle.receipt.decision as \"allow\",\n action: bundle.action,\n actor: bundle.actor,\n resource_type: null,\n resource_id: null,\n reasons: [],\n why_trace: null,\n permit_id: bundle.receipt.permit_id,\n permit_hash: null,\n audit_hash: bundle.receipt.audit_hash ?? \"\",\n context_hash: \"\",\n issued_at: bundle.receipt.issued_at,\n expires_at: null,\n algorithm: bundle.receipt.algorithm as DecisionReceiptAlgorithm,\n signature: bundle.receipt.signature,\n signing_key_id: null,\n payload: {\n receipt_id: bundle.receipt.receipt_id,\n evaluation_id: bundle.receipt.evaluation_id,\n org_id: opts.orgId ?? \"\",\n decision: bundle.receipt.decision as \"allow\",\n action: bundle.action,\n actor: bundle.actor,\n resource_type: null,\n resource_id: null,\n reasons: [],\n why_summary: \"\",\n permit_id: bundle.receipt.permit_id,\n permit_hash: null,\n audit_hash: bundle.receipt.audit_hash ?? \"\",\n context_hash: \"\",\n issued_at: bundle.receipt.issued_at,\n expires_at: null,\n },\n };\n\n const deployEvidence: DeployEvidenceInput | NotApplicable = opts.deployNotApplicable\n ? NOT_APPLICABLE\n : {\n deploy_id: bundle.bundle_id,\n environment: bundle.environment,\n sha: bundle.sha,\n actor_id: bundle.actor,\n deployed_at: bundle.generated_at,\n gate_permit_token: bundle.receipt.permit_id ?? bundle.receipt.receipt_id,\n };\n\n return buildClaimEvidenceLink({\n claimId: opts.claimId,\n ...(opts.orgId !== undefined ? { orgId: opts.orgId } : {}),\n runtimeEvidence,\n deployEvidence,\n ...(opts.signingSecret !== undefined ? { signingSecret: opts.signingSecret } : {}),\n ...(opts.schemaVersion !== undefined ? { schemaVersion: opts.schemaVersion } : {}),\n });\n}\n","/**\n * BCCAE V1 — TypeScript client.\n *\n * BCCAEClient wraps the four BCCAE Phase 3 endpoints:\n * evaluate → POST /v1/bccae/evaluations (bccae:evaluate scope)\n * execute → POST /v1/bccae/execute (bccae:execute scope)\n * revoke → POST /v1/bccae/revocations (bccae:revoke scope)\n * getEvidence → GET /v1/bccae/evidence/:id (bccae:audit scope)\n *\n * Spec: atlasent-internal/architecture/BCCAE-architecture.md\n * Phase 3 — Execution Assurance. Not a Deploy Gate V1 customer API.\n */\n\nimport { AtlaSentError } from \"./errors.js\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type BccaeActorType = \"HUMAN\" | \"AGENT\" | \"SERVICE\" | \"EXTERNAL\";\nexport type BccaeTrustLevel = \"L0\" | \"L1\" | \"L2\" | \"L3\";\nexport type BccaeResourceClassification =\n | \"PUBLIC\"\n | \"INTERNAL\"\n | \"CONFIDENTIAL\"\n | \"RESTRICTED\";\nexport type BccaeDeploymentEnv = \"PROD\" | \"STAGING\" | \"DEV\" | \"TEST\";\nexport type BccaeSecurityPosture = \"STANDARD\" | \"ELEVATED\" | \"LOCKED\";\nexport type BccaeRequestSource =\n | \"AGENT\"\n | \"API\"\n | \"INTERNAL\"\n | \"SCHEDULED\"\n | \"TRIGGERED\";\nexport type BccaeRevocationTargetType =\n | \"PERMIT\"\n | \"EVALUATION\"\n | \"ACTOR\"\n | \"RESOURCE\";\n\nexport interface BccaeEvaluateInput {\n actor_id: string;\n actor_type: BccaeActorType;\n actor_trust_level: BccaeTrustLevel;\n actor_claims?: Record<string, unknown>;\n action_id: string;\n execution_intent: string;\n /** 64 lowercase hex characters (32 random bytes). */\n caller_nonce: string;\n resource_ref: string;\n resource_type: string;\n resource_classification: BccaeResourceClassification;\n organization_version?: number;\n deployment_env: BccaeDeploymentEnv;\n deployment_region: string;\n security_posture: BccaeSecurityPosture;\n external_signals?: unknown[];\n dependencies?: unknown[];\n policy_version_set?: unknown[];\n request_source?: BccaeRequestSource;\n request_chain_id?: string;\n parent_eval_id?: string;\n}\n\nexport interface BccaeEvaluateResponse {\n evaluation_id: string;\n envelope_hash: string;\n permit_token: string;\n permit_id: string;\n expires_at: string;\n outcome: \"PERMIT\" | \"PERMIT_WITH_CONDITIONS\";\n}\n\nexport interface BccaeExecuteInput {\n permit_token: string;\n action_id: string;\n resource_ref: string;\n}\n\nexport interface BccaeExecuteResponse {\n authorized: boolean;\n outcome: \"EXECUTION_AUTHORIZED\" | \"EXECUTION_DENIED\";\n permit_id?: string;\n evaluation_id?: string;\n envelope_hash?: string;\n evidence_id?: string | null;\n /** Populated on denial — identifies which gate check failed. */\n check?: string;\n reason?: string;\n}\n\nexport interface BccaeRevokeInput {\n target_type: BccaeRevocationTargetType;\n target_id: string;\n reason: string;\n}\n\nexport interface BccaeRevokeResponse {\n revocation_id: string;\n target_type: BccaeRevocationTargetType;\n target_id: string;\n effective_at: string;\n}\n\nexport interface BccaeEvidenceResponse {\n evidence_id: string;\n org_id: string;\n event_type: string;\n evaluation_id: string | null;\n permit_id: string | null;\n envelope_hash: string | null;\n actor_id: string;\n action_id: string | null;\n resource_ref: string | null;\n outcome: string;\n detail: Record<string, unknown>;\n previous_evidence_id: string | null;\n previous_hash: string | null;\n record_hash: string;\n sequence: number;\n recorded_at: string;\n chain_integrity: {\n hash_intact: boolean;\n expected_hash?: string;\n };\n}\n\nexport interface BccaeClientOptions {\n /** API key with appropriate bccae:* scopes. */\n apiKey: string;\n /** Override base URL. Defaults to https://api.atlasent.io */\n baseUrl?: string;\n /** Request timeout in ms. Defaults to 10000. */\n timeoutMs?: number;\n /** Inject a custom fetch implementation (testing / edge runtimes). */\n fetch?: typeof globalThis.fetch;\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nconst DEFAULT_BASE_URL = \"https://api.atlasent.io\";\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\n/**\n * Validates the caller-supplied base URL and returns its normalized origin\n * (scheme://host[:port]). Using parsed.origin rather than the raw string\n * breaks the taint path from caller input to the outbound fetch call.\n */\nfunction enforceTls(raw: string): string {\n let parsed: URL;\n try {\n parsed = new URL(raw);\n } catch {\n throw new AtlaSentError(\n \"BCCAEClient baseUrl is not a valid URL\",\n { code: \"network\" },\n );\n }\n if (parsed.protocol === \"http:\") {\n // Exact hostname comparison via parsed.hostname avoids\n // false positives from query strings containing 'localhost'.\n const h = parsed.hostname;\n if (h !== \"localhost\" && h !== \"127.0.0.1\" && h !== \"[::1]\") {\n throw new AtlaSentError(\n \"BCCAEClient baseUrl must use https:// for non-local endpoints\",\n { code: \"network\" },\n );\n }\n }\n // Return the URL's origin (scheme + host + port) — any path/query\n // component in the raw input is intentionally dropped here.\n return parsed.origin;\n}\n\n/** Generate a cryptographically random 64-char hex nonce (32 bytes). */\nexport function generateBccaeNonce(): string {\n const bytes = new Uint8Array(32);\n globalThis.crypto.getRandomValues(bytes);\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n// ─── BCCAEClient ──────────────────────────────────────────────────────────────\n\n/**\n * Thin HTTP client for the BCCAE V1 Phase 3 endpoints.\n *\n * Each method maps 1:1 to an edge function:\n * - {@link BCCAEClient.evaluate} → v1-bccae-evaluate\n * - {@link BCCAEClient.execute} → v1-bccae-execute\n * - {@link BCCAEClient.revoke} → v1-bccae-revoke\n * - {@link BCCAEClient.getEvidence} → v1-bccae-evidence\n *\n * Authorization denials are returned (not thrown). Network errors,\n * invalid API keys, and 5xx responses throw {@link AtlaSentError}.\n *\n * Use {@link generateBccaeNonce} to produce a valid `caller_nonce`.\n */\nexport class BCCAEClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly timeoutMs: number;\n private readonly fetchImpl: typeof fetch;\n\n constructor(options: BccaeClientOptions) {\n if (!options.apiKey || typeof options.apiKey !== \"string\") {\n throw new AtlaSentError(\"BCCAEClient: apiKey is required\", {\n code: \"invalid_api_key\",\n });\n }\n this.apiKey = options.apiKey;\n // enforceTls validates scheme/host and returns parsed.origin,\n // severing any taint from the raw options.baseUrl string.\n this.baseUrl = enforceTls(options.baseUrl ?? DEFAULT_BASE_URL);\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n async evaluate(input: BccaeEvaluateInput): Promise<BccaeEvaluateResponse> {\n const { body } = await this.post<BccaeEvaluateResponse>(\n \"/v1/bccae/evaluations\",\n input,\n );\n return body;\n }\n\n async execute(input: BccaeExecuteInput): Promise<BccaeExecuteResponse> {\n const { body } = await this.post<BccaeExecuteResponse>(\n \"/v1/bccae/execute\",\n input,\n );\n return body;\n }\n\n async revoke(input: BccaeRevokeInput): Promise<BccaeRevokeResponse> {\n const { body } = await this.post<BccaeRevokeResponse>(\n \"/v1/bccae/revocations\",\n input,\n );\n return body;\n }\n\n async getEvidence(evidenceId: string): Promise<BccaeEvidenceResponse> {\n if (!evidenceId || typeof evidenceId !== \"string\") {\n throw new AtlaSentError(\"BCCAEClient: evidenceId is required\", {\n code: \"bad_request\",\n });\n }\n const { body } = await this.get<BccaeEvidenceResponse>(\n `/v1/bccae/evidence/${encodeURIComponent(evidenceId)}`,\n );\n return body;\n }\n\n // ── HTTP primitives ─────────────────────────────────────────────────────────\n\n private async post<T>(\n path: string,\n body: unknown,\n ): Promise<{ body: T }> {\n return this.request<T>(path, \"POST\", body);\n }\n\n private async get<T>(path: string): Promise<{ body: T }> {\n return this.request<T>(path, \"GET\", undefined);\n }\n\n private async request<T>(\n path: string,\n method: \"GET\" | \"POST\",\n body: unknown,\n ): Promise<{ body: T }> {\n const url = `${this.baseUrl}${path}`;\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n \"User-Agent\": \"atlasent-bccae-client/1.0\",\n };\n if (method === \"POST\") headers[\"Content-Type\"] = \"application/json\";\n\n let response: Response;\n try {\n response = await this.fetchImpl(url, {\n method,\n headers,\n signal: AbortSignal.timeout(this.timeoutMs),\n ...(method === \"POST\" ? { body: JSON.stringify(body) } : {}),\n });\n } catch (err) {\n throw new AtlaSentError(\n `BCCAEClient: network error on ${method} ${path}: ${err instanceof Error ? err.message : String(err)}`,\n { code: \"network\" },\n );\n }\n\n let responseBody: unknown;\n try {\n responseBody = await response.json();\n } catch {\n throw new AtlaSentError(\n `BCCAEClient: non-JSON response (status ${response.status}) from ${method} ${path}`,\n { code: \"network\" },\n );\n }\n\n if (!response.ok) {\n const err = responseBody as Record<string, unknown>;\n const message =\n typeof err?.message === \"string\"\n ? err.message\n : `BCCAE request failed with status ${response.status}`;\n const code =\n response.status === 401\n ? \"invalid_api_key\"\n : response.status === 403\n ? \"forbidden\"\n : response.status === 429\n ? \"rate_limited\"\n : response.status >= 500\n ? \"server_error\"\n : \"network\";\n throw new AtlaSentError(message, { code });\n }\n\n return { body: responseBody as T };\n }\n}\n","/**\n * Constrained governance agents — read-side SDK surface.\n *\n * Three endpoints, all GET, all org-scoped server-side:\n *\n * GET /v1/governance/agents — registry of advisory agents\n * GET /v1/governance/findings?change_id=… — findings against one change\n * GET /v1/governance/evaluations?change_id=… — agent run records\n *\n * **Doctrine — evaluation ≠ authorization ≠ execution.**\n * Every type in this module is read-only signal. `can_authorize` is\n * pinned `false` on the wire (DB-generated column on the registry,\n * CHECK on findings). The SDK does not expose an invocation method:\n * agent invocation is a CI concern (atlasent-action `governance-agents`\n * mode), not an application concern. This module is for surfaces that\n * want to render findings alongside the authority workflow.\n *\n * Wire schema source of truth lives in\n * atlasent-api/packages/types/src/governance-agents.ts\n * which is intentionally standalone (not re-exported from @atlasent/types).\n * The shapes mirrored below are the read-side subset.\n *\n * @module\n */\n\n// ─── enums (mirror SQL CHECK domains) ────────────────────────────────────────\n\nexport type AgentFindingSeverity =\n | \"info\"\n | \"low\"\n | \"medium\"\n | \"high\"\n | \"blocker\";\n\nexport type AgentEvaluationStatus =\n | \"running\"\n | \"completed\"\n | \"failed\"\n | \"timeout\";\n\nexport type AgentAuthorityDomain =\n | \"engineering\"\n | \"runtime_platform\"\n | \"security\"\n | \"compliance\"\n | \"release_management\"\n | \"operations\"\n | \"customer_impact\"\n | \"governance_office\";\n\nexport type AgentInvokerKind =\n | \"human\"\n | \"service_account\"\n | \"autonomous_agent\"\n | \"system\";\n\nexport type AgentSubjectKind =\n | \"pull_request\"\n | \"schema_migration\"\n | \"runtime_flag\"\n | \"deployment\"\n | \"operational_rollout\"\n | \"regulated_execution_change\"\n | \"policy_bundle\";\n\n// ─── records ─────────────────────────────────────────────────────────────────\n\n/**\n * A versioned advisory agent definition. `authority_class` is fixed to\n * `advisory` and `can_authorize` to `false` at the schema level — these\n * cannot be relaxed without a structural change to the runtime DB.\n */\nexport interface GovernanceAgent {\n readonly slug: string;\n readonly version: string;\n readonly name: string;\n readonly description: string;\n readonly applicable_subject_kinds: readonly AgentSubjectKind[];\n readonly authority_class: \"advisory\";\n /** Structurally false. Generated column on the runtime DB. */\n readonly can_authorize: false;\n readonly capabilities: readonly string[];\n readonly is_active: boolean;\n readonly created_at: string;\n readonly retired_at: string | null;\n}\n\n/** A typed evidence pointer attached to a finding. Free-form by design. */\nexport interface AgentEvidenceRef {\n readonly kind: string;\n readonly ref: string;\n readonly note?: string;\n}\n\n/**\n * One advisory finding produced by an agent run. `can_authorize` is\n * pinned `false` by a CHECK constraint on the underlying table — no\n * finding row in any environment can ever satisfy a gate.\n */\nexport interface GovernanceAgentFinding {\n readonly id: string;\n readonly org_id: string;\n readonly evaluation_id: string;\n readonly change_id: string;\n readonly agent_slug: string;\n readonly agent_version: string;\n readonly finding_type: string;\n readonly severity: AgentFindingSeverity;\n readonly confidence: number | null;\n readonly summary: string;\n readonly evidence_refs: readonly AgentEvidenceRef[];\n readonly required_authority: AgentAuthorityDomain | null;\n readonly recommended_action: string | null;\n /** Structurally false. CHECK constraint on the runtime DB. */\n readonly can_authorize: false;\n readonly supersedes_finding_id: string | null;\n readonly payload: Readonly<Record<string, unknown>>;\n readonly created_at: string;\n /**\n * Populated by the finding→gate routing trigger (atlasent-api #842).\n * Null when no matching gate exists at insertion time; can be\n * back-resolved by `governance_resolve_findings_for_gate(gate_id)`.\n */\n readonly routed_gate_id?: string | null;\n}\n\n/**\n * An append-only record of one agent run against one governed change.\n * The same (agent_slug, agent_version, input_hash) combination may\n * produce multiple rows across time — the runtime DB does not dedupe.\n */\nexport interface GovernanceAgentEvaluation {\n readonly id: string;\n readonly org_id: string;\n readonly change_id: string;\n readonly agent_slug: string;\n readonly agent_version: string;\n readonly input_hash: string;\n readonly status: AgentEvaluationStatus;\n readonly highest_severity: AgentFindingSeverity | null;\n readonly findings_count: number;\n readonly summary: string | null;\n readonly runtime_ms: number | null;\n readonly failure_reason: string | null;\n readonly invoked_by_kind: AgentInvokerKind;\n readonly invoked_by: string | null;\n readonly started_at: string;\n readonly completed_at: string | null;\n}\n\n// ─── response envelopes ──────────────────────────────────────────────────────\n\nexport interface ListGovernanceAgentsResponse {\n readonly agents: readonly GovernanceAgent[];\n}\n\nexport interface ListGovernanceFindingsResponse {\n readonly findings: readonly GovernanceAgentFinding[];\n}\n\nexport interface ListGovernanceEvaluationsResponse {\n readonly evaluations: readonly GovernanceAgentEvaluation[];\n}\n\n// ─── query shapes ────────────────────────────────────────────────────────────\n\nexport interface ListGovernanceFindingsQuery {\n readonly change_id: string;\n /** Optional: filter to one agent's findings. */\n readonly agent_slug?: string;\n}\n\nexport interface ListGovernanceEvaluationsQuery {\n readonly change_id: string;\n /** Optional: filter to one agent's runs. */\n readonly agent_slug?: string;\n}\n\n// ─── helpers ─────────────────────────────────────────────────────────────────\n\nconst SEVERITY_RANK: Record<AgentFindingSeverity, number> = {\n info: 1,\n low: 2,\n medium: 3,\n high: 4,\n blocker: 5,\n};\n\n/**\n * Return the worst severity across a set of findings, or `null` when\n * the input is empty. Pure function, exported because every consumer\n * needs the same rollup logic (Console finds panel, CI summary, etc.).\n */\nexport function highestAgentFindingSeverity(\n findings: readonly Pick<GovernanceAgentFinding, \"severity\">[],\n): AgentFindingSeverity | null {\n let best: AgentFindingSeverity | null = null;\n let rank = 0;\n for (const f of findings) {\n const r = SEVERITY_RANK[f.severity];\n if (r > rank) {\n rank = r;\n best = f.severity;\n }\n }\n return best;\n}\n","/**\n * Delta VQP — TypeScript client for the VQP re-derivation audit endpoints.\n *\n * VQPClient wraps two service-role-only edge functions:\n * generate → POST /functions/v1/v1-generate-vqp (creates snapshot + prompt_hash)\n * verify → POST /functions/v1/v1-verify-vqp (re-derives prompt, hashes, audits)\n *\n * These endpoints require a Supabase service_role key — not a user API key.\n * This client is for server-side admin tooling only.\n *\n * Spec: atlasent-api/supabase/functions/v1-generate-vqp, v1-verify-vqp\n * Phase 3 — Deterministic re-derivation audit.\n */\n\nimport { AtlaSentError } from \"./errors.js\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type VqpVerdict = \"qualified\" | \"conditionally_qualified\" | \"not_qualified\";\n\nexport interface VQPGenerateInput {\n bundle_id: string;\n org_id: string;\n /** Additional context embedded in the VQP prompt for this snapshot. */\n vqp_context?: Record<string, unknown>;\n}\n\nexport interface VQPGenerateResponse {\n snapshot_id: string;\n bundle_id: string;\n bundle_version: string;\n overall_verdict: VqpVerdict;\n quality_score: number;\n /** SHA-256 hex of the deterministic VQP prompt used to produce this snapshot. */\n prompt_hash: string;\n generation_model: string;\n generated_at: string;\n}\n\nexport interface VQPVerifyInput {\n snapshot_id: string;\n /**\n * Re-call the AI model with the re-derived prompt to detect score drift.\n * When false (default), only prompt hash integrity is checked.\n */\n rerun?: boolean;\n}\n\nexport interface VQPVerifyResponse {\n snapshot_id: string;\n /** True when the re-derived prompt hash matches the stored snapshot.prompt_hash. */\n hash_match: boolean;\n original_prompt_hash: string;\n rerun_prompt_hash: string;\n /** Score from the re-run AI call. Null when rerun was not requested. */\n rerun_score: number | null;\n /** Verdict from the re-run AI call. Null when rerun was not requested. */\n rerun_verdict: VqpVerdict | null;\n /** rerun_score - original quality_score. Null when rerun was not requested. */\n score_delta: number | null;\n /** True when rerun_verdict differs from the stored overall_verdict. */\n verdict_changed: boolean;\n /** UUID of the written vqp_audit_log row. */\n audit_log_id: string;\n}\n\nexport interface VQPClientOptions {\n /** Supabase service_role key. These endpoints are not accessible with user API keys. */\n serviceRoleKey: string;\n /** Supabase project URL, e.g. https://<ref>.supabase.co */\n supabaseUrl: string;\n /** Request timeout in ms. Defaults to 30000 (AI re-run calls can be slow). */\n timeoutMs?: number;\n /** Inject a custom fetch implementation (testing / edge runtimes). */\n fetch?: typeof globalThis.fetch;\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\nfunction enforceHttps(raw: string): string {\n let parsed: URL;\n try {\n parsed = new URL(raw);\n } catch {\n throw new AtlaSentError(\"VQPClient supabaseUrl is not a valid URL\", {\n code: \"network\",\n });\n }\n if (parsed.protocol === \"http:\") {\n const h = parsed.hostname;\n if (h !== \"localhost\" && h !== \"127.0.0.1\" && h !== \"[::1]\") {\n throw new AtlaSentError(\n \"VQPClient supabaseUrl must use https:// for non-local endpoints\",\n { code: \"network\" },\n );\n }\n }\n return parsed.origin;\n}\n\n// ─── VQPClient ────────────────────────────────────────────────────────────────\n\n/**\n * Thin HTTP client for the Delta VQP Phase 3 service-role endpoints.\n *\n * Each method maps 1:1 to an edge function:\n * - {@link VQPClient.generate} → v1-generate-vqp\n * - {@link VQPClient.verify} → v1-verify-vqp\n *\n * **Server-side only.** These endpoints require `SUPABASE_SERVICE_ROLE_KEY`.\n * Never expose a service_role key in browser or agent code.\n *\n * Network errors and 5xx responses throw {@link AtlaSentError}.\n */\nexport class VQPClient {\n private readonly serviceRoleKey: string;\n private readonly baseUrl: string;\n private readonly timeoutMs: number;\n private readonly fetchImpl: typeof fetch;\n\n constructor(options: VQPClientOptions) {\n if (!options.serviceRoleKey || typeof options.serviceRoleKey !== \"string\") {\n throw new AtlaSentError(\"VQPClient: serviceRoleKey is required\", {\n code: \"invalid_api_key\",\n });\n }\n this.serviceRoleKey = options.serviceRoleKey;\n this.baseUrl = enforceHttps(options.supabaseUrl);\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n async generate(input: VQPGenerateInput): Promise<VQPGenerateResponse> {\n const { body } = await this.post<VQPGenerateResponse>(\n \"/functions/v1/v1-generate-vqp\",\n input,\n );\n return body;\n }\n\n async verify(input: VQPVerifyInput): Promise<VQPVerifyResponse> {\n const { body } = await this.post<VQPVerifyResponse>(\n \"/functions/v1/v1-verify-vqp\",\n input,\n );\n return body;\n }\n\n // ── HTTP primitives ─────────────────────────────────────────────────────────\n\n private async post<T>(path: string, body: unknown): Promise<{ body: T }> {\n return this.request<T>(path, \"POST\", body);\n }\n\n private async request<T>(\n path: string,\n method: \"GET\" | \"POST\",\n body: unknown,\n ): Promise<{ body: T }> {\n const url = `${this.baseUrl}${path}`;\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n Authorization: `Bearer ${this.serviceRoleKey}`,\n \"User-Agent\": \"atlasent-vqp-client/1.0\",\n };\n if (method === \"POST\") headers[\"Content-Type\"] = \"application/json\";\n\n let response: Response;\n try {\n response = await this.fetchImpl(url, {\n method,\n headers,\n signal: AbortSignal.timeout(this.timeoutMs),\n ...(method === \"POST\" ? { body: JSON.stringify(body) } : {}),\n });\n } catch (err) {\n throw new AtlaSentError(\n `VQPClient: network error on ${method} ${path}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n { code: \"network\" },\n );\n }\n\n let responseBody: unknown;\n try {\n responseBody = await response.json();\n } catch {\n throw new AtlaSentError(\n `VQPClient: non-JSON response (status ${response.status}) from ${method} ${path}`,\n { code: \"network\" },\n );\n }\n\n if (!response.ok) {\n const err = responseBody as Record<string, unknown>;\n const message =\n typeof err?.message === \"string\"\n ? err.message\n : `VQP request failed with status ${response.status}`;\n const code =\n response.status === 401\n ? \"invalid_api_key\"\n : response.status === 403\n ? \"forbidden\"\n : response.status === 429\n ? \"rate_limited\"\n : response.status >= 500\n ? \"server_error\"\n : \"network\";\n throw new AtlaSentError(message, { code });\n }\n\n return { body: responseBody as T };\n }\n}\n"],"mappings":"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","names":["isNode","headers","varianceKind","resolve","sha256Hex","createHash","createHmac","createHash","overrides","sleep","resolve","escalation","outcome","start","MACHINE_EXECUTABLE_ACTIONS","pct","import_node_crypto","timingSafeEqual","createHmac","pickFetch","resolveConfig","apiGet","apiPost","import_node_crypto","SDK_VERSION","sha256Hex","createHash","DEFAULT_BASE_URL","DEFAULT_TIMEOUT_MS","headers","DEFAULT_TIMEOUT_MS","headers"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/trustRoot.ts","../src/types.ts","../src/compat.ts","../src/retry.ts","../src/scim.ts","../src/evidence-bundle.ts","../src/auth.ts","../src/sso.ts","../src/access-governance-log.ts","../src/client.ts","../src/auditBundle.ts","../src/evidenceEngine.ts","../src/protect.ts","../src/requirePermit.ts","../src/withPermit.ts","../src/approvalRuntime.ts","../src/actionContext.ts","../src/verticals/deployGate.ts","../src/verticals/closeGovernance.ts","../src/verticals/paymentRelease.ts","../src/verticals/dataExport.ts","../src/shadow.ts","../src/verticals/agentTools.ts","../src/verticals/gxpActions.ts","../src/verticals/paymentOperations.ts","../src/verticals/deploymentActions.ts","../src/verticals/behaviorEvents.ts","../src/verticals/infraActions.ts","../src/verticals/hrActions.ts","../src/verticals/modelGovernance.ts","../src/verticals/dataDelete.ts","../src/verticals/contractActions.ts","../src/verticals/pricingActions.ts","../src/verticals/securityActions.ts","../src/verticals/accessCert.ts","../src/verticals/financialClose.ts","../src/verticals/databaseActions.ts","../src/replay.ts","../src/hitl.ts","../src/sandboxDiff.ts","../src/delegationPropagation.ts","../src/contextEnvelope.ts","../src/trust.ts","../src/financialAction.ts","../src/liabilityAttribution.ts","../src/economicRisk.ts","../src/financialQuorum.ts","../src/budgetaryGovernance.ts","../src/autonomousFinancial.ts","../src/incentiveAlignment.ts","../src/economicEvidence.ts","../src/disputeReversal.ts","../src/financialDashboard.ts","../src/governanceEnforcement.ts","../src/governanceWebhooks.ts","../src/complianceEvidence.ts","../src/policySync.ts","../src/webhook.ts","../src/crossOrgPermission.ts","../src/anomalyResponse.ts","../src/budgetExceptions.ts","../src/regulatoryEscalation.ts","../src/incentiveSignalFeedback.ts","../src/crossOrgImpersonation.ts","../src/v2.ts","../src/runtime_v2.ts","../src/controlSurface.ts","../src/claimLineage.ts","../src/bccae.ts","../src/governanceAgents.ts","../src/vqp.ts"],"sourcesContent":["/**\n * @atlasent/sdk — execution-time authorization for AI agents.\n *\n * The canonical execution-boundary surface is two forms of the same\n * contract. Both mint and verify a Permit end-to-end; both fail closed.\n * Pick the form that fits the call site.\n *\n * `protect` — the primitive. Returns the verified {@link Permit} so\n * the caller can pass it across a boundary, persist it alongside\n * their own record, or interleave it with non-trivial control flow:\n *\n * ```ts\n * import atlasent from \"@atlasent/sdk\";\n *\n * const permit = await atlasent.protect({\n * agent: \"deploy-bot\",\n * action: \"production.deploy\",\n * context: { commit, approver },\n * });\n * // permit is verified end-to-end. Execute the action.\n * ```\n *\n * `withPermit` — the lexically-scoped form. Binds the action body to\n * the permit's lifetime via a callback so the call site reads as\n * \"execute this body under a permit\":\n *\n * ```ts\n * const result = await atlasent.withPermit(\n * { agent: \"deploy-bot\", action: \"production.deploy\",\n * context: { commit, approver } },\n * async (permit) => runDeploy(commit, { permitId: permit.permitId }),\n * );\n * ```\n *\n * `requirePermit` — descriptor form for dangerous operations carrying\n * `resource_id` + `environment`. The executor only runs when AtlaSent\n * authorizes it end-to-end:\n *\n * ```ts\n * await atlasent.requirePermit(\n * { action_type: \"database.table.drop\", actor_id: \"agent:code-agent\",\n * resource_id: \"prod-db.users\", environment: \"production\",\n * context: { reversibility: \"irreversible\" } },\n * async () => { await db.raw(\"DROP TABLE users\"); },\n * );\n * ```\n *\n * Named exports remain available for the lower-level\n * {@link AtlaSentClient} and the error taxonomy.\n */\n\nimport { AtlaSentClient } from \"./client.js\";\nimport { verifyBundle } from \"./auditBundle.js\";\nimport { AtlaSentDeniedError, AtlaSentError } from \"./errors.js\";\nimport { configure, deployGate, protect } from \"./protect.js\";\nimport { requirePermit, classifyCommand } from \"./requirePermit.js\";\nimport { withPermit } from \"./withPermit.js\";\nimport {\n DEPLOYMENT_PRODUCTION_ACTION,\n PRODUCTION_DEPLOY_ACTION,\n} from \"./types.js\";\nimport {\n protectPaymentRelease,\n protectDataExport,\n protectReconciliationCertify,\n protectToolCall,\n protectGxpAction,\n protectBatchRecordRelease,\n protectPaymentOperation,\n protectDeploymentV2,\n protectBehaviorEvent,\n protectInfraAction,\n protectHrOffboard,\n protectModelPromotion,\n protectCustomerDataDelete,\n protectContractExecution,\n protectPricingRule,\n protectSecurityIncidentEscalate,\n protectSecurityAccessQuarantine,\n protectAccessCertRevoke,\n protectPeriodCloseCertify,\n protectDatabaseMigration,\n protectDatabaseSchemaDrop,\n protectDatabaseTableDelete,\n} from \"./verticals/index.js\";\n\nexport { AtlaSentClient } from \"./client.js\";\nexport {\n DEPLOY_GATE_CODES,\n DEPLOYMENT_PRODUCTION_ACTION,\n PRODUCTION_DEPLOY_ACTION,\n} from \"./types.js\";\nexport {\n AtlaSentDeniedError,\n AtlaSentEscalateError,\n AtlaSentError,\n BundleVerificationError,\n PermitRevoked,\n StreamParseError,\n StreamTimeoutError,\n normalizePermitOutcome,\n type AtlaSentDecision,\n type AtlaSentDeniedErrorInit,\n type AtlaSentEscalateErrorInit,\n type AtlaSentErrorCode,\n type AtlaSentErrorInit,\n type PermitOutcome,\n} from \"./errors.js\";\nexport {\n configure,\n deployGate,\n protect,\n type ConfigureOptions,\n type Permit,\n type PermitWithEvidence,\n type ProtectRequest,\n type ProtectWithEvidenceOptions,\n protectWithEvidence,\n} from \"./protect.js\";\nexport {\n requirePermit,\n classifyCommand,\n CanonicalProtectedActionType,\n type ProtectedAction,\n} from \"./requirePermit.js\";\nexport { withPermit } from \"./withPermit.js\";\nexport type {\n ApiKeySelfResponse,\n AtlaSentClientOptions,\n BvsSnapshot,\n ConsentClassProjection,\n AuditEventsResult,\n AuditExportRequest,\n AuditExportResult,\n ConstraintTrace,\n ConstraintTracePolicy,\n ConstraintTraceStage,\n Decision,\n DecisionCanonical,\n DeployGateContext,\n DeployGateDenyCode,\n DeployGateEvidence,\n DeployGateRequest,\n DeployGateResponse,\n DeployOverrideClaim,\n DeployPermitClaim,\n BatchEvalItem,\n BatchEvalResponse,\n DecisionStreamEvent,\n EvaluateBatchResultItem,\n EvaluatePreflightResponse,\n SubscribeDecisionsOptions,\n CompletionProof,\n EvaluateRequest,\n EvaluateResponse,\n EvaluateResponsePermit,\n EvaluateRiskEnvelope,\n EvaluateRiskEnvelopeFactor,\n GetPermitResponse,\n LicenseStatus,\n LicenseVerifyResult,\n ListPermitsRequest,\n ListPermitsResponse,\n PermitRecord,\n PermitStatus,\n PermitValidResponse,\n RateLimitState,\n RevokePermitByIdInput,\n RevokePermitByIdResponse,\n RevokePermitRequest,\n RevokePermitResponse,\n VerifyPermitByIdResponse,\n StreamDecisionEvent,\n StreamEvent,\n StreamOptions,\n StreamProgressEvent,\n VerifyPermitRequest,\n VerifyPermitResponse,\n} from \"./types.js\";\nexport {\n canonicalJSON,\n signedBytesFor,\n verifyAuditBundle,\n verifyBundle,\n type AuditBundle,\n type BundleVerificationResult,\n type VerifyBundleOptions,\n type VerifyKey,\n} from \"./auditBundle.js\";\nexport type {\n AuditDecision,\n AuditEvent,\n AuditEventsPage,\n AuditEventsQuery,\n AuditExport,\n AuditExportSignatureStatus,\n} from \"./audit.js\";\nexport type {\n EngineVersionKind,\n EnvelopeDriftDetail,\n EnvelopeVerification,\n ReplayDecisionResponse,\n ReplayDecisionValue,\n ReplayRequest,\n ReplayResponse,\n ReplayVarianceKind,\n EvidenceBundleVerifyResult,\n OfflineEvidenceBundleData,\n} from \"./replay.js\";\nexport {\n verifyEvidenceBundle,\n _computeEvidenceRootHash,\n} from \"./replay.js\";\nexport {\n DEFAULT_RETRY_POLICY,\n computeBackoffMs,\n hasAttemptsLeft,\n isRetryable,\n mergePolicy,\n type RetryPolicy,\n} from \"./retry.js\";\nexport {\n normalizeEvaluateRequest,\n normalizeEvaluateResponse,\n type LegacyEvaluateRequest,\n type LegacyEvaluateResponse,\n type V2EvaluateRequest,\n type V2EvaluateResponse,\n} from \"./compat.js\";\nexport {\n hitlRequiredApproverCount,\n type HitlAiUnavailableFallback,\n type HitlApprovalRecord,\n type HitlApproveRequest,\n type HitlApproverPoolEntry,\n type HitlApproverType,\n type HitlChainHop,\n type HitlCreateRequest,\n type HitlDetailResponse,\n type HitlEscalation,\n type HitlFallbackDecision,\n type HitlHeterogeneousQuorumExtension,\n type HitlHeterogeneousQuorumTally,\n type HitlListResponse,\n type HitlQuorumProgress,\n type HitlQuorumTier,\n type HitlRejectRequest,\n type HitlRespondRequest,\n type HitlStatus,\n type ListHitlEscalationsRequest,\n type ListHitlEscalationsResponse,\n} from \"./hitl.js\";\nexport {\n isSandboxDiffPopulated,\n type SandboxDiff,\n type SandboxDiffEmpty,\n type SandboxDiffPerTable,\n type SandboxDiffResponse,\n type SandboxRunMode,\n type SandboxRunStatus,\n type SandboxRunWrite,\n type SandboxWriteOp,\n} from \"./sandboxDiff.js\";\nexport {\n delegationPropagationHadEffect,\n type DelegationPropagationSummary,\n} from \"./delegationPropagation.js\";\nexport type {\n ApprovalArtifactV1,\n ApprovalIssuer,\n ApprovalReference,\n ApprovalReviewer,\n PrincipalKind,\n} from \"./approvalArtifact.js\";\nexport type {\n IdentityAssertionBinding,\n IdentityAssertionV1,\n IdentityIssuer,\n IdentityIssuerKey,\n IdentitySubject,\n IdentityTrustedIssuersConfig,\n} from \"./identityAssertion.js\";\nexport type {\n ApprovalQuorumV1,\n QuorumIndependence,\n QuorumPolicy,\n QuorumProof,\n QuorumRoleRequirement,\n} from \"./approvalQuorum.js\";\n\n// ── Evidence engine ──────────────────────────────────────────────────────────────────────────────────────\nexport type {\n WhyStage,\n WhyPolicyEvaluation,\n WhyTrace,\n DecisionReceiptAlgorithm,\n DecisionReceiptPayload,\n DecisionReceipt,\n ComplianceControlCoverage,\n ActionEvidenceBundle,\n} from \"./evidenceEngine.js\";\nexport {\n buildWhyTrace,\n computeContextHash,\n buildDecisionReceiptPayload,\n signDecisionReceiptHmac,\n verifyDecisionReceiptHmac,\n computeBundleHash,\n soc2ControlCoverageForDecision,\n} from \"./evidenceEngine.js\";\n\n// ── Context Envelope ──────────────────────────────────────────────────────────────────────────────────────\nexport {\n CONTEXT_NAMESPACES,\n} from \"./contextEnvelope.js\";\nexport type {\n ContextEnvelope,\n ContextNamespaceEntry,\n ContextNamespaceKey,\n ContextSignal,\n RecordContextEnvelopeInput,\n} from \"./contextEnvelope.js\";\n\n// ── V1 Proof bundle ──────────────────────────────────────────────────────────────────────────────────────\nexport type {\n GovernanceEvent,\n PermitV1,\n} from \"./v1Types.js\";\nexport type {\n ProofEvaluationSummary,\n ProofPayload,\n ProofResponse,\n} from \"./proof.js\";\n\n// ── V1 Override types ────────────────────────────────────────────────────────────────────────────────────\nexport type {\n CreateOverrideRequest,\n OverrideEvent,\n OverrideEventsResponse,\n OverrideListResponse,\n OverrideStatus,\n OverrideEventType,\n OverrideV1,\n} from \"./overrides.js\";\nexport type {\n TrustRootSnapshot,\n TrustRootKey,\n TrustRootRevocationEntry,\n TrustRootManagerOptions,\n} from \"./trustRoot.js\";\nexport {\n TrustRootManager,\n getGlobalTrustRootManager,\n __setGlobalTrustRootManagerForTests,\n} from \"./trustRoot.js\";\nexport {\n bootstrapTrust,\n isKidRevoked,\n isTrustSnapshotExpired,\n DEFAULT_TRUST_TTL_MS,\n type JWK,\n type TrustSnapshot,\n} from \"./trust.js\";\n\n// ── Economic Governance & Liability Attribution ─────────────────────────────────────────────────────────────\nexport {\n DEFAULT_RISK_TIER_THRESHOLDS,\n classifyRiskTier,\n withinAutonomousCeiling,\n type CurrencyCode,\n type FinancialActionClass,\n type FinancialActionType,\n type FinancialExecutionRecord,\n type FinancialExecutionStatus,\n type FinancialRiskTier,\n type LiabilityClassification,\n type RiskTierThreshold,\n} from \"./financialAction.js\";\n\nexport {\n buildLiabilityChain,\n computeLiabilityWeights,\n findPrimaryLiabilityParties,\n validateLiabilityChain,\n type LiabilityAttributionInput,\n type LiabilityAttributionRecord,\n type LiabilityChainValidation,\n type LiabilityParty,\n type LiabilityPartyRole,\n type WeightDistribution,\n} from \"./liabilityAttribution.js\";\n\nexport {\n computeApprovalRiskScore,\n computeExposureScore,\n computeHHI,\n computeOverallRiskScore,\n computeOverrideScore,\n detectSelfApproval,\n hhiToConcentrationScore,\n scoreToRiskTier,\n type AnomalyType,\n type ApprovalConcentrationAnalysis,\n type ApproverBreakdown,\n type BudgetaryDriftAnalysis,\n type ConcentrationAlert,\n type ExecutionAnomaly,\n type FinancialRiskScore,\n type RiskFactor,\n} from \"./economicRisk.js\";\n\nexport {\n computeEscalatedApprovalCount,\n evaluateFinancialQuorum,\n type AmountThreshold,\n type EmergencyFreeze,\n type FinancialQuorumInput,\n type FinancialQuorumPolicy,\n type FinancialQuorumResult,\n type FinancialRoleRequirement,\n} from \"./financialQuorum.js\";\n\nexport {\n budgetUtilizationSeverity,\n checkBudgetConstraints,\n type BudgetConstraintCheckResult,\n type BudgetLimit,\n type BudgetPolicy,\n type BudgetScope,\n type BudgetSpendingState,\n type BudgetViolation,\n type SpendingConstraint,\n} from \"./budgetaryGovernance.js\";\n\nexport {\n checkAutonomousBounds,\n detectAutonomousAnomaly,\n type AutonomousExecutionBounds,\n type AutonomousExecutionCheckResult,\n type AutonomousExecutionRecord,\n type ExecutionCeiling,\n} from \"./autonomousFinancial.js\";\n\nexport {\n DEFAULT_INCENTIVE_CONFIG,\n computeGovernanceHealthScore,\n detectMisalignedIncentives,\n type GovernanceBehaviorPattern,\n type IncentiveAlignmentConfig,\n type IncentiveSignal,\n type IncentiveSignalType,\n type MisalignmentAlert,\n} from \"./incentiveAlignment.js\";\n\nexport {\n buildSignableContent,\n canonicalizeForEvidence,\n serializeSignableContent,\n verifyEvidenceBundleStructure,\n type ApprovalProvenance,\n type EconomicEvidenceBundle,\n type EvidenceBundleSignableContent,\n type EvidenceBundleVerificationResult,\n type EvidencePurpose,\n} from \"./economicEvidence.js\";\n\nexport {\n computeRemediationUrgency,\n isFreezeActive,\n transitionDispute,\n transitionReversal,\n type ActionFreeze,\n type DisputeOrigin,\n type DisputeRecord,\n type DisputeStatus,\n type ReversalStage,\n type ReversalWorkflow,\n} from \"./disputeReversal.js\";\n\nexport {\n buildLiabilityVisualization,\n buildRiskTimeline,\n type ActionTypeOverrideStat,\n type ActorOverrideStat,\n type DisputeReversalSummary,\n type FinancialGovernanceSummary,\n type LiabilityEdge,\n type LiabilityNode,\n type LiabilityVisualization,\n type OverrideAnalytics,\n type RiskTimelinePoint,\n} from \"./financialDashboard.js\";\n\n// ── Governance enforcement layer ────────────────────────────────────────────────────────────────────────────────────────\nexport {\n GovernanceEnforcementError,\n enforceAutonomousBounds,\n enforceBudgetConstraint,\n enforceEconomicGovernance,\n enforceFinancialQuorum,\n type AutonomousBoundsDenyCode,\n type BudgetDenyCode,\n type FinancialQuorumDenyCode,\n type GovernanceEnforcementErrorInit,\n type GovernanceGate,\n} from \"./governanceEnforcement.js\";\n\n// ── Governance Webhooks, Compliance Evidence & Policy Sync ────────────────────────────────────────────\nexport {\n verifyWebhookSignature,\n type CreateWebhookSubscriptionRequest,\n type EnforcementWebhookEvent,\n type GovernanceWebhookEvent,\n type ListWebhookDeliveriesResponse,\n type ListWebhookSubscriptionsResponse,\n type WebhookDelivery,\n type WebhookDeliveryStatus,\n type WebhookPayload,\n type WebhookSubscription,\n} from \"./governanceWebhooks.js\";\n\nexport {\n evidenceRunPasses,\n nonPassingControls,\n type ComplianceEvidenceRun,\n type ComplianceEvidenceSummary,\n type ComplianceFramework,\n type ComplianceRunStatus,\n type EvidenceControl,\n type EvidenceControlStatus,\n type ListEvidenceRunsResponse,\n type SOC2ControlId,\n type TriggerEvidenceRunRequest,\n type TriggerEvidenceRunResponse,\n} from \"./complianceEvidence.js\";\n\nexport {\n formatPolicySyncDiff,\n isPolicySyncTerminal,\n type ApplyPolicySyncResponse,\n type ListPolicySyncRunsResponse,\n type PolicyBundleEntry,\n type PolicyRef,\n type PolicySyncDiff,\n type PolicySyncRun,\n type PolicySyncStatus,\n type SubmitPolicySyncRequest,\n type SubmitPolicySyncResponse,\n} from \"./policySync.js\";\n\nexport {\n assertWebhook,\n verifyWebhook,\n WebhookVerificationError,\n} from \"./webhook.js\";\n\n// ── Governance Graph & Incident Reconstruction ────────────────────────────────────────────────\nexport type {\n GovernanceGraphQueryType,\n GovernanceGraphQueryParams,\n GovernanceGraphQueryResponse,\n GovernanceGraphResultRow,\n GraphNodeType,\n GraphEdgeType,\n GraphNode,\n GraphEdge,\n ProductionDeployerRow,\n ExecutionApproverRow,\n QuorumBypassConnectorRow,\n EmergencyOverrideActionRow,\n ConnectedSystemRow,\n UserApprovalRow,\n ListGraphNodesResponse,\n ListGraphEdgesResponse,\n CreateGraphNodeInput,\n CreateGraphEdgeInput,\n} from \"./governanceGraph.js\";\n\nexport type {\n IncidentChainExecutionRow,\n IncidentChainActorEntry,\n IncidentChainEvidenceRow,\n IncidentTimelineResponse,\n} from \"./incidentReconstruction.js\";\n\n// ── Connector Management & Organizational Risk Graph ──────────────────────────────────────────────────────\nexport type {\n ConnectorType,\n ConnectorStatus,\n ConnectorRow,\n ConnectorCredentialType,\n ConnectorCredentialRow,\n EnforcementAction,\n EnforcementQuorumConfig,\n ConnectorEnforcementPolicy,\n ConnectorAuditLogEntry,\n ConnectorSyncState,\n ConnectorEnforcementEventInput,\n ConnectorEnforcementResult,\n InstallConnectorInput,\n AuthenticateConnectorInput,\n UpsertEnforcementPolicyInput,\n ListConnectorsResponse,\n InstallConnectorResponse,\n AuthenticateConnectorResponse,\n SyncConnectorResponse,\n RevokeConnectorResponse,\n RotateCredentialsResponse,\n ListEnforcementPoliciesResponse,\n UpsertEnforcementPolicyResponse,\n} from \"./connectorManagement.js\";\n\nexport type {\n OrgRiskLevel,\n OrgRiskScore,\n ComputeOrgRiskOptions,\n ComputeOrgRiskResponse,\n GetLatestOrgRiskResponse,\n ListOrgRiskHistoryResponse,\n} from \"./orgRiskGraph.js\";\n\n// ── Cross-Org Permission Negotiation ────────────────────────────────────────────────────────────────────────────\nexport {\n summarizeCrossOrgPermission,\n type CrossOrgPermissionCheckListParams,\n type CrossOrgPermissionCheckRequest,\n type CrossOrgPermissionCheckResult,\n type CrossOrgTrustHop,\n} from \"./crossOrgPermission.js\";\n\n// ── Anomaly Response Automation ─────────────────────────────────────────────────────────────────────────────────────\nexport {\n highestSeverityAction,\n matchAnomalyRules,\n type AnomalyActionType,\n type AnomalyResponseEvent,\n type AnomalyResponseRule,\n type CreateAnomalyResponseRuleRequest,\n type TriggerAnomalyResponseRequest,\n} from \"./anomalyResponse.js\";\n\n// ── Budget Exception Workflows ──────────────────────────────────────────────────────────────────────────────────────────\nexport {\n isBudgetExceptionActive,\n isBudgetExceptionTerminal,\n type ApproveBudgetExceptionRequest,\n type BudgetExceptionRequest,\n type BudgetExceptionStatus,\n type CreateBudgetExceptionRequest,\n} from \"./budgetExceptions.js\";\n\n// ── Regulatory Escalation Chain ────────────────────────────────────────────────────────────────────────────────────\nexport {\n isEscalationSlaBreached,\n isRegulatoryEscalationTerminal,\n type CreateRegulatoryEscalationRequest,\n type RegulatoryAuthorityLevel,\n type RegulatoryEscalation,\n type RegulatoryEscalationStatus,\n} from \"./regulatoryEscalation.js\";\n\n// ── Incentive Signal Feedback Loop ───────────────────────────────────────────────────────────────────────────────────────\nexport {\n computeSignalEngagementRate,\n isSubstantiveSignalResponse,\n type GovernanceSignalAction,\n type RecordSignalActionRequest,\n type RecordSignalOutcomeRequest,\n type SignalActionSummary,\n type SignalActionType,\n} from \"./incentiveSignalFeedback.js\";\n\n// ── Cross-Org Impersonation ──────────────────────────────────────────────────────────────────────────────────────────\nexport {\n clampTokenDuration,\n isImpersonationGrantUsable,\n type CreateImpersonationGrantRequest,\n type CrossOrgImpersonationGrant,\n type ImpersonationToken,\n type ImpersonationValidationResult,\n} from \"./crossOrgImpersonation.js\";\n\n// ── V2 Wave-A endpoints ──────────────────────────────────────────────────────────────────────────────────────────────────\nexport {\n FeatureNotEnabledError,\n V2_BATCH_PATH,\n V2_GRAPHQL_MAX_DEPTH,\n V2_GRAPHQL_PATH,\n V2_MAX_BATCH_ITEMS,\n V2_MAX_BODY_BYTES,\n V2_STREAM_PATH,\n authorizeStream,\n evaluateMany,\n graphql,\n type AuthorizeStreamHandlers,\n type EvaluateBatchItem,\n type EvaluateBatchResponse,\n type EvaluateManyRequest,\n type FeatureNotEnabledErrorInit,\n type GraphQLRequest,\n type GraphQLResponse,\n type StreamComplete,\n type StreamDecisionFrame,\n type StreamErrorFrame,\n type V2Feature,\n type V2Transport,\n} from \"./v2.js\";\n\n// ── Runtime v2 — four-plane lifecycle ─────────────────────────────────────────\nexport {\n RuntimeV2Client,\n type AuditChainFilters,\n type AuditChainPage,\n type AuthorizationDecision,\n type AuthorityRecord,\n type ChainIntegrityReport,\n type ComplianceExport,\n type ExecutionReceipt,\n type PostExecutionResult,\n type RuntimeAuditEntry,\n type VerificationFailure,\n type VerificationResult,\n} from \"./runtime_v2.js\";\n\n// ── Approval / Override Runtime ────────────────────────────────────────────────────────────────────────────────────\nexport {\n configureApprovalRuntime,\n createEscalation,\n EscalationDeniedError,\n EscalationTimeoutError,\n protectOrEscalate,\n requestOverride,\n waitForEscalationApproval,\n type ApprovalPermit,\n type ApprovalRuntimeConfig,\n type ApprovalStatus,\n type CreateEscalationOptions,\n type EscalationHandle,\n type EscalationOutcome,\n type ProtectOrEscalateOptions,\n type RequestOverrideOptions,\n type WaitForApprovalOptions,\n} from \"./approvalRuntime.js\";\n\n// ── Context Layer ───────────────────────────────────────────────────────────────────────────────────────────────────────\nexport {\n DEFAULT_REDACTION_RULES,\n buildActionContext,\n flattenActionContext,\n redactContext,\n validateActionContext,\n type ActionContext,\n type ActionMetaContext,\n type ActorContext,\n type BuildActionContextInput,\n type ContextValidationError,\n type ContextValidationResult,\n type ContextValidationWarning,\n type EnvironmentContext,\n type HistoricalContext,\n type RedactionMode,\n type RedactionRule,\n type ResourceContext,\n type ValidateContextOptions,\n} from \"./actionContext.js\";\n\n// ── Shadow Mode ──────────────────────────────────────────────────────────────────────────────────────────────────────────\nexport {\n configureShadow,\n protectShadow,\n reportShadowEvent,\n type ShadowConfig,\n type ShadowEventPayload,\n type ShadowMode,\n type ShadowOptions,\n type ShadowOutcome,\n} from \"./shadow.js\";\n\n// ── Enterprise Control Surface ────────────────────────────────────────────────────────────────────────────────────\nexport {\n checkIntegrationHealth,\n configureControlSurface,\n getEnforcementStatus,\n getOrgSummary,\n reportProtectedAction,\n type ControlSurfaceConfig,\n type EnforcementMode,\n type EnforcementStatus,\n type HealthReport,\n type GetEnforcementStatusOptions,\n type OrgSummary,\n type ProtectedActionEntry,\n type ReportProtectedActionOptions,\n} from \"./controlSurface.js\";\n\n// ── Pilot Verticals ────────────────────────────────────────────────────────────────────────────────────────────────────────\nexport {\n protectDeploy,\n type DeployGateOptions,\n type DeployEnvironment,\n protectCloseAction,\n protectReconciliationCertify,\n type CloseGovernanceOptions,\n type CloseActionType,\n type ReconciliationCertifyOptions,\n protectPaymentRelease,\n type PaymentReleaseOptions,\n VENDOR_PAYMENT_ACTION,\n protectDataExport,\n type DataExportOptions,\n CUSTOMER_DATA_EXPORT_ACTION,\n protectToolCall,\n classifyToolRisk,\n type AgentToolOptions,\n type AgentToolMode,\n protectGxpAction,\n protectBatchRecordRelease,\n type GxpActionType,\n type GxpActionOptions,\n type BatchRecordReleaseOptions,\n type ClinicalDataAccessOptions,\n type CAPAOptions,\n protectPaymentOperation,\n type PaymentOperationActionType,\n type PaymentOperationOptions,\n protectDeploymentV2,\n type DeploymentActionType,\n type DeploymentV2Options,\n DEPLOY_V1_ACTION,\n protectBehaviorEvent,\n type BehaviorEventCategory,\n type BehaviorEventOptions,\n BEHAVIOR_SENSITIVE_CATEGORIES,\n protectInfraAction,\n type InfraActionType,\n type InfraActionOptions,\n protectHrAction,\n protectHrOffboard,\n protectHrRoleEscalate,\n type HrActionType,\n type HrActionOptions,\n protectModelGovernance,\n protectModelPromotion,\n type ModelGovernanceActionType,\n type ModelGovernanceOptions,\n protectCustomerDataDelete,\n type DataDeleteActionType,\n type DataDeleteOptions,\n type GdprLegalBasis,\n protectContractAction,\n protectContractExecution,\n type ContractActionType,\n type ContractActionOptions,\n protectPricingAction,\n protectPricingRule,\n type PricingActionType,\n type PricingActionOptions,\n protectSecurityAction,\n protectSecurityIncidentEscalate,\n protectSecurityAccessQuarantine,\n type SecurityActionType,\n type SecurityActionOptions,\n protectAccessCertAction,\n protectAccessCertRevoke,\n type AccessCertActionType,\n type AccessCertOptions,\n protectFinancialCloseAction,\n protectPeriodCloseCertify,\n type FinancialCloseActionType,\n type FinancialCloseOptions,\n protectDatabaseAction,\n protectDatabaseMigration,\n protectDatabaseSchemaDrop,\n protectDatabaseTableDelete,\n type DatabaseMigrationActionType,\n type DatabaseDestructiveActionType,\n type DatabaseActionType,\n type PermitEvidence,\n type DenialEvidence,\n type DatabaseActionOptions,\n} from \"./verticals/index.js\";\n\n/**\n * Default export. The opinionated, category-defining entry point:\n *\n * ```ts\n * import atlasent from \"@atlasent/sdk\";\n * const permit = await atlasent.protect({ ... }); // primitive\n * await atlasent.withPermit({ ... }, async (permit) => …); // scoped form\n * await atlasent.requirePermit({ ... }, executor); // descriptor form\n * ```\n */\nconst atlasent = {\n protect,\n withPermit,\n deployGate,\n configure,\n requirePermit,\n classifyCommand,\n verifyBundle,\n PRODUCTION_DEPLOY_ACTION,\n DEPLOYMENT_PRODUCTION_ACTION,\n AtlaSentClient,\n AtlaSentError,\n AtlaSentDeniedError,\n paymentGate: protectPaymentRelease,\n dataExportGate: protectDataExport,\n reconciliationGate: protectReconciliationCertify,\n agentGuard: protectToolCall,\n gxpGate: protectGxpAction,\n batchRecordGate: protectBatchRecordRelease,\n paymentOpsGate: protectPaymentOperation,\n deployV2Gate: protectDeploymentV2,\n behaviorEventGate: protectBehaviorEvent,\n infraGate: protectInfraAction,\n hrGate: protectHrOffboard,\n modelGovernanceGate: protectModelPromotion,\n dataDeleteGate: protectCustomerDataDelete,\n contractGate: protectContractExecution,\n pricingGate: protectPricingRule,\n securityGate: protectSecurityIncidentEscalate,\n accessCertGate: protectAccessCertRevoke,\n financialCloseGate: protectPeriodCloseCertify,\n databaseMigrationGate: protectDatabaseMigration,\n databaseSchemaDropGate: protectDatabaseSchemaDrop,\n databaseTableDeleteGate: protectDatabaseTableDelete,\n} as const;\n\nexport default atlasent;\n\nexport {\n buildClaimEvidenceLink,\n verifyClaimEvidenceLink,\n NOT_APPLICABLE,\n type BuildClaimEvidenceLinkOpts,\n type VerifyClaimEvidenceLinkOpts,\n type VerifyClaimEvidenceLinkResult,\n type ClaimEvidenceLink,\n type RuntimeEvidenceSlot,\n type DeployEvidenceSlot,\n type IntegrationEvidenceSlot,\n type ApprovalArtifactSlot,\n type DeltaSlot,\n type DriftDetail,\n type DriftChangeType,\n type DriftSeverity,\n type DeltaStatus,\n type EvidenceSlotStatus,\n type VerificationChecklist,\n type NotApplicable,\n type DeployEvidenceInput,\n type HitlChainSummary,\n type SignedApprovalArtifact,\n buildClaimEvidenceLinkFromActionBundle,\n type ActionBundleInput,\n type ActionBundleReceipt,\n type BuildFromActionBundleOpts,\n} from \"./claimLineage.js\";\n\n// ── BCCAE V1 — Phase 3 Execution Assurance substrate ───────────────────────────────────────────────\nexport {\n BCCAEClient,\n generateBccaeNonce,\n type BccaeActorType,\n type BccaeTrustLevel,\n type BccaeResourceClassification,\n type BccaeDeploymentEnv,\n type BccaeSecurityPosture,\n type BccaeRequestSource,\n type BccaeRevocationTargetType,\n type BccaeClientOptions,\n type BccaeEvaluateInput,\n type BccaeEvaluateResponse,\n type BccaeExecuteInput,\n type BccaeExecuteResponse,\n type BccaeRevokeInput,\n type BccaeRevokeResponse,\n type BccaeEvidenceResponse,\n} from \"./bccae.js\";\n\n// ── Constrained governance agents (advisory read surface) ───────────────────────────────────────────────\nexport {\n highestAgentFindingSeverity,\n type AgentAuthorityDomain,\n type AgentEvaluationStatus,\n type AgentEvidenceRef,\n type AgentFindingSeverity,\n type AgentInvokerKind,\n type AgentSubjectKind,\n type GovernanceAgent,\n type GovernanceAgentEvaluation,\n type GovernanceAgentFinding,\n type ListGovernanceAgentsResponse,\n type ListGovernanceEvaluationsQuery,\n type ListGovernanceEvaluationsResponse,\n type ListGovernanceFindingsQuery,\n type ListGovernanceFindingsResponse,\n} from \"./governanceAgents.js\";\n\n// ── SCIM 2.0 Provisioning ─────────────────────────────────────────────────────────────────────────────────────────\nexport {\n makeScimClient,\n SCIM_GROUP_SCHEMA,\n SCIM_PATCH_OP_SCHEMA,\n SCIM_USER_SCHEMA,\n type ScimEmail,\n type ScimGroupRef,\n type ScimGroupsSubClient,\n type ScimListParams,\n type ScimListResponse,\n type ScimMeta,\n type ScimName,\n type ScimPatchOp,\n type ScimSubClient,\n type ScimUser,\n type ScimUserCreate,\n type ScimUsersSubClient,\n type ScimUserUpdate,\n} from \"./scim.js\";\n\n// ── Evidence Bundles ──────────────────────────────────────────────────────────────────────────────────────────────\nexport {\n makeEvidenceBundleClient,\n type EvidenceBundle,\n type EvidenceBundleCreateParams,\n type EvidenceBundleListPage,\n type EvidenceBundleListParams,\n type EvidenceBundleStatus,\n type EvidenceBundleSubClient,\n} from \"./evidence-bundle.js\";\n\n// ── Auth Token Management ─────────────────────────────────────────────────────────────────────────────────────────────\nexport {\n makeAuthClient,\n type AuthSubClient,\n type IdpConnection,\n type TokenResponse,\n} from \"./auth.js\";\n\n// ── SSO Administration ────────────────────────────────────────────────────────────────────────────────────────────────\nexport {\n wireToSsoConnection,\n wireToSsoJitRule,\n wireToSsoEvent,\n wireToSsoReadiness,\n makeSsoClient,\n type SsoConnection,\n type SsoConnectionWire,\n type SsoConnectionInput,\n type SsoJitRule,\n type SsoJitRuleWire,\n type SsoJitRuleInput,\n type SsoJitRulePatch,\n type SsoEvent,\n type SsoEventWire,\n type SsoEnforceAction,\n type SsoEnforceResult,\n type SsoReadiness,\n type SsoReadinessWire,\n type SsoRole,\n type SsoSubClient,\n} from \"./sso.js\";\n\n// ── Access Governance Log ─────────────────────────────────────────────────────\nexport {\n makeAccessGovernanceLogClient,\n type AccessGovernanceEvent,\n type AccessGovernanceLogPage,\n type AccessGovernanceLogQuery,\n type AccessGovernanceLogSubClient,\n} from \"./access-governance-log.js\";\n\n// ── Delta VQP — AI re-derivation audit (service-role server-side client) ────────────────────────────────\nexport {\n VQPClient,\n type VqpVerdict,\n type VQPClientOptions,\n type VQPGenerateInput,\n type VQPGenerateResponse,\n type VQPVerifyInput,\n type VQPVerifyResponse,\n} from \"./vqp.js\";\n\n// ── Action Dependencies ───────────────────────────────────────────────────────\nexport type {\n ActionDependency,\n ActionDependencyResponse,\n CreateActionDependencyRequest,\n DependencyLink,\n DependencyRequirement,\n DependencyStatus,\n ListActionDependenciesResponse,\n} from \"./actionDependencies.js\";\n\n// ── Engine Versions ───────────────────────────────────────────────────────────\nexport type {\n EngineVersionRecord,\n EngineVersionResponse,\n EngineVersionStatus,\n ListEngineVersionsResponse,\n RegisterEngineVersionRequest,\n} from \"./engineVersions.js\";\n\n// ── State Snapshots ───────────────────────────────────────────────────────────\nexport type {\n SnapshotSourceKind,\n StateSnapshot,\n StateSnapshotInput,\n StateSnapshotRef,\n} from \"./snapshots.js\";\n","/**\n * Error types for the AtlaSent TypeScript SDK.\n *\n * The SDK follows a fail-closed design: a clean policy DENY is\n * returned as `EvaluateResponse.decision === \"deny\"` (not thrown),\n * but any failure to confirm authorization — network, timeout,\n * bad response, invalid key, rate limit — throws an\n * {@link AtlaSentError}.\n */\n\n// ── Streaming-specific errors ─────────────────────────────────────────────────\n\n/**\n * Thrown when no SSE event arrives within the configured timeout window.\n *\n * Callers can catch this specifically to distinguish a stalled stream\n * from other network or parse failures:\n *\n * ```ts\n * catch (e) {\n * if (e instanceof StreamTimeoutError) { // reconnect or alert }\n * }\n * ```\n */\nexport class StreamTimeoutError extends Error {\n override name: string = \"StreamTimeoutError\";\n /** Timeout that was exceeded, in milliseconds. */\n readonly timeoutMs: number;\n\n constructor(timeoutMs: number) {\n super(`AtlaSent stream timed out after ${timeoutMs}ms with no event`);\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Thrown when the SSE stream closes with a partial / malformed JSON payload.\n *\n * This is a recoverable condition — the stream closed mid-JSON. The\n * caller can reconnect using the last received `Last-Event-ID` and\n * resume from where the server left off.\n *\n * ```ts\n * catch (e) {\n * if (e instanceof StreamParseError) { // log raw data, maybe reconnect }\n * }\n * ```\n */\nexport class StreamParseError extends Error {\n override name: string = \"StreamParseError\";\n /** The raw data string that failed to parse. */\n readonly rawData: string;\n\n constructor(rawData: string, cause?: unknown) {\n super(`AtlaSent stream received malformed JSON: ${rawData.slice(0, 200)}`);\n this.rawData = rawData;\n if (cause !== undefined) {\n // ES2022 cause\n (this as { cause?: unknown }).cause = cause;\n }\n }\n}\n\n/** Discriminator for {@link AtlaSentError.code}. */\nexport type AtlaSentErrorCode =\n | \"invalid_api_key\"\n | \"forbidden\"\n | \"rate_limited\"\n | \"timeout\"\n | \"network\"\n | \"bad_response\"\n | \"bad_request\"\n | \"server_error\"\n // Tenant lacks a v2_<feature> flag — server returned 404. Distinct\n // from \"forbidden\" (403 authorization denial) so callers can branch\n // on the failure mode.\n | \"feature_disabled\"\n | \"claim_evidence_incomplete\";\n\n/** Initialization options for {@link AtlaSentError}. */\nexport interface AtlaSentErrorInit {\n status?: number;\n code?: AtlaSentErrorCode;\n requestId?: string;\n retryAfterMs?: number;\n cause?: unknown;\n}\n\n/**\n * The only error type this SDK throws.\n *\n * Flat top-level properties mirror the convention used by Stripe,\n * Octokit, and Supabase. `cause` is forwarded to the standard\n * ES2022 `Error` constructor.\n */\nexport class AtlaSentError extends Error {\n // Subclasses override to their own literal (e.g. \"AtlaSentDeniedError\");\n // keep this assignable rather than pinned to a single literal.\n override name: string = \"AtlaSentError\";\n\n /** HTTP status code, when the error originated from an API response. */\n readonly status: number | undefined;\n /** Coarse category — useful for `switch` statements at call sites. */\n readonly code: AtlaSentErrorCode | undefined;\n /** Correlation ID echoed from the `X-Request-ID` header the SDK sent. */\n readonly requestId: string | undefined;\n /** Parsed `Retry-After` header value, in milliseconds. Only set for 429. */\n readonly retryAfterMs: number | undefined;\n\n constructor(message: string, init: AtlaSentErrorInit = {}) {\n super(\n message,\n init.cause !== undefined ? { cause: init.cause } : undefined,\n );\n this.status = init.status;\n this.code = init.code;\n this.requestId = init.requestId;\n this.retryAfterMs = init.retryAfterMs;\n }\n}\n\n/**\n * Outcome of a denied decision.\n *\n * `\"deny\"` is what the current `/v1-evaluate` API returns. `\"hold\"`\n * and `\"escalate\"` are reserved for forthcoming API decisions that\n * put a permit into a pending state requiring human review; the\n * union is declared now so call sites can `switch` exhaustively\n * from the start and adopt new decisions without a breaking change.\n */\nexport type AtlaSentDecision = \"deny\" | \"hold\" | \"escalate\";\n\n/**\n * Reason an already-issued permit failed verification.\n *\n * Surfaced on {@link AtlaSentDeniedError.outcome} so callers can\n * distinguish replay (`permit_consumed`) from revocation\n * (`permit_revoked`) from natural expiry (`permit_expired`) without\n * parsing {@link AtlaSentDeniedError.reason}. The set is defined by\n * `contract/vectors/permit_outcomes.json`; any new outcome MUST be\n * added there first.\n *\n * Mirrors the Python SDK's `PermitOutcome`. See\n * `atlasent/docs/REVOCATION_RUNBOOK.md` for the operator-facing\n * matrix this discriminator drives.\n */\nexport type PermitOutcome =\n | \"permit_consumed\"\n | \"permit_expired\"\n | \"permit_revoked\"\n | \"permit_not_found\"\n | \"permit_signing_key_revoked\";\n\nconst KNOWN_PERMIT_OUTCOMES: ReadonlySet<string> = new Set([\n \"permit_consumed\",\n \"permit_expired\",\n \"permit_revoked\",\n \"permit_not_found\",\n \"permit_signing_key_revoked\",\n]);\n\n/**\n * Map a server-supplied `outcome` string to {@link PermitOutcome}.\n *\n * Returns `undefined` for `undefined`, `\"\"`, `\"verified\"`, or any\n * unrecognized value. Used at the SDK's deny boundary so we don't\n * surface mis-typed outcomes — when the server adds a new outcome\n * string, callers branching on {@link AtlaSentDeniedError.outcome}\n * see `undefined` and fall through to their generic deny path\n * rather than match an unknown literal.\n */\nexport function normalizePermitOutcome(\n raw: string | undefined,\n): PermitOutcome | undefined {\n if (raw !== undefined && KNOWN_PERMIT_OUTCOMES.has(raw)) {\n return raw as PermitOutcome;\n }\n return undefined;\n}\n\n/** Initialization options for {@link AtlaSentDeniedError}. */\nexport interface AtlaSentDeniedErrorInit {\n decision: AtlaSentDecision;\n evaluationId: string;\n reason?: string;\n requestId?: string;\n auditHash?: string;\n /**\n * When the denial came from permit verification (not policy\n * evaluation), the discriminator that distinguishes replay,\n * expiry, revocation, and missing-record failures. `undefined`\n * for evaluate-time denials.\n */\n outcome?: PermitOutcome;\n}\n\n/**\n * Thrown by {@link atlasent.protect} when the policy engine refuses\n * the action, or when a permit fails end-to-end verification.\n *\n * This is the **fail-closed boundary** of the SDK: every code path\n * that short-circuits an action because authorization was not\n * confirmed raises an `AtlaSentDeniedError`. Callers cannot silently\n * proceed on a denial by forgetting to branch on a return value.\n *\n * Extends {@link AtlaSentError} so `instanceof AtlaSentError`\n * catches denials as part of the SDK's single exception family;\n * use `instanceof AtlaSentDeniedError` to distinguish a policy\n * denial from a transport/auth error.\n */\nexport class AtlaSentDeniedError extends AtlaSentError {\n override name: string = \"AtlaSentDeniedError\";\n\n /** Policy decision — `\"deny\"` today; `\"hold\"` / `\"escalate\"` reserved. */\n readonly decision: AtlaSentDecision;\n /** Opaque permit/decision id from `/v1-evaluate`. */\n readonly evaluationId: string;\n /** Human-readable explanation from the policy engine, if provided. */\n readonly reason: string | undefined;\n /** Hash-chained audit-trail entry associated with the decision. */\n readonly auditHash: string | undefined;\n /**\n * Discriminator for permit-side denial reasons. Populated only\n * when the server reported `verified=false` from `/v1-verify-permit`;\n * `undefined` for evaluate-time denials. See {@link PermitOutcome}.\n */\n readonly outcome: PermitOutcome | undefined;\n\n constructor(init: AtlaSentDeniedErrorInit) {\n const msg = init.reason\n ? `AtlaSent ${init.decision}: ${init.reason}`\n : `AtlaSent ${init.decision}`;\n const errInit: AtlaSentErrorInit = { status: 200 };\n if (init.requestId !== undefined) errInit.requestId = init.requestId;\n super(msg, errInit);\n this.decision = init.decision;\n this.evaluationId = init.evaluationId;\n this.reason = init.reason;\n this.auditHash = init.auditHash;\n this.outcome = init.outcome;\n }\n\n // ── Outcome discriminators ───────────────────────────────────────\n // Convenience predicates that mirror the operator runbook's matrix.\n // Callers can compare `outcome` directly; these are sugar so the\n // common cases are explicit at the call site.\n\n /** `true` when the permit was explicitly revoked (D3 endpoint). */\n get isRevoked(): boolean {\n return this.outcome === \"permit_revoked\";\n }\n\n /** `true` when the permit's TTL passed before verification. */\n get isExpired(): boolean {\n return this.outcome === \"permit_expired\";\n }\n\n /**\n * `true` when the permit was already consumed by a prior verify\n * (v1 single-use replay protection).\n */\n get isConsumed(): boolean {\n return this.outcome === \"permit_consumed\";\n }\n\n /**\n * `true` when the permit id wasn't recognized server-side\n * (typo, cross-tenant lookup, or pre-issuance race).\n */\n get isNotFound(): boolean {\n return this.outcome === \"permit_not_found\";\n }\n\n /**\n * `true` when the permit's signing key KID appears in the\n * trust-root revocation list (ADR-005 D3 R2/R3 key rotation).\n */\n get isSigningKeyRevoked(): boolean {\n return this.outcome === \"permit_signing_key_revoked\";\n }\n}\n\n/** Initialization options for {@link AtlaSentEscalateError}. */\nexport interface AtlaSentEscalateErrorInit {\n requestId?: string;\n userId?: string;\n cause?: unknown;\n}\n\n/**\n * Thrown when an evaluate response carries `decision: \"escalate\"`.\n *\n * Distinct from {@link AtlaSentDeniedError} — an escalation does not\n * constitute a hard denial. It signals that the policy engine has\n * deferred the authorization decision to a human review queue.\n * Middleware and agent orchestrators should catch this specifically\n * and route the pending action to the appropriate HITL channel.\n *\n * ```ts\n * catch (e) {\n * if (e instanceof AtlaSentEscalateError) {\n * await humanReviewQueue.submit({ userId: e.userId, requestId: e.requestId });\n * }\n * }\n * ```\n *\n * Extends {@link AtlaSentError} so `instanceof AtlaSentError` catches\n * escalations alongside other SDK errors; use\n * `instanceof AtlaSentEscalateError` to branch specifically.\n */\nexport class AtlaSentEscalateError extends AtlaSentError {\n override name: string = \"AtlaSentEscalateError\";\n\n /** Always `\"escalate\"` — discriminates this error from other AtlaSent errors. */\n readonly decision = \"escalate\" as const;\n\n /** The user whose action triggered the escalation, if available. */\n readonly userId: string | undefined;\n\n constructor(message: string, opts?: AtlaSentEscalateErrorInit) {\n super(message, {\n ...(opts?.requestId !== undefined ? { requestId: opts.requestId } : {}),\n cause: opts?.cause,\n });\n this.userId = opts?.userId;\n }\n}\n\n// ── Permit revocation error (PROD-D9 continuous-authorization) ────────────────\n\n/**\n * Thrown by an SDK guard heartbeat when `GET /v1/permits/:id/valid`\n * returns `status: 'revoked'` during tool execution (PROD-D9\n * continuous-authorization lease model).\n *\n * This error is **always re-thrown** — it is never serialized as a\n * `tool-result` denial because it represents a live enforcement action,\n * not a policy evaluation at request time. Callers should treat it as\n * an immediate halt signal.\n *\n * ```ts\n * catch (e) {\n * if (e instanceof PermitRevoked) {\n * // log e.permitId and e.revocationId for incident correlation\n * await incidentLog.record({ permitId: e.permitId, revocationId: e.revocationId });\n * }\n * }\n * ```\n *\n * Guard heartbeat is configured via `permitRevalidationIntervalMs` in\n * the guard options (minimum 1000 ms). The heartbeat activates only\n * when the {@link AtlaSentClient} exposes `checkPermitValid` — i.e.\n * when `atlasent-api` has deployed `GET /v1/permits/:id/valid`.\n */\nexport class PermitRevoked extends AtlaSentError {\n override name: string = 'PermitRevoked';\n /** The id of the permit that was revoked mid-execution. */\n readonly permitId: string;\n /** The `scope_revocations.id` that triggered the revocation, when available. */\n readonly revocationId: string | undefined;\n\n constructor(permitId: string, revocationId?: string) {\n super(\n revocationId\n ? `AtlaSent: permit ${permitId} revoked (revocation: ${revocationId}) — guard heartbeat halted execution`\n : `AtlaSent: permit ${permitId} revoked — guard heartbeat halted execution`,\n );\n this.permitId = permitId;\n this.revocationId = revocationId;\n }\n}\n\n// ── Bundle verification error (ADR-005 D3 fail-closed expiry / revocation) ────\n\n/**\n * Initialization options for {@link BundleVerificationError}.\n */\nexport interface BundleVerificationErrorInit {\n /**\n * Machine-readable reason code:\n * - `trust_snapshot_expired`: the snapshot's `valid_until` has passed\n * and `allowExpiredSnapshot` was not set.\n * - `key_revoked`: the bundle's `signing_key_id` appears in\n * `revoked_keys` of the active trust snapshot.\n * - `key_role_mismatch`: the signing key's `role` is not `\"R3_audit\"`.\n */\n reason: \"trust_snapshot_expired\" | \"key_revoked\" | \"key_role_mismatch\";\n /** ISO-8601 `valid_until` of the snapshot that caused the failure. */\n snapshotValidUntil?: string;\n /** ISO-8601 `issued_at` of the snapshot (its fetch/pin time). */\n snapshotFetchedAt?: string;\n /** Whether the snapshot came from the bundled vendor files or a live refresh. */\n snapshotSource?: \"pinned\" | \"live\";\n /** Which key id was revoked or role-mismatched, when applicable. */\n kid?: string;\n}\n\n/**\n * Thrown by {@link verifyAuditBundle} / {@link verifyBundle} when the\n * active trust-root snapshot is expired (ADR-005 D3) or the bundle's\n * signing key is revoked / has the wrong role.\n *\n * This error is **always thrown** — it is never returned as a\n * {@link BundleVerificationResult} because ADR-005 D3 requires that\n * an expired snapshot or revoked key constitutes a hard enforcement\n * action, not a soft verification failure.\n *\n * To opt out of fail-closed expiry (air-gap / offline use), pass\n * `allowExpiredSnapshot: true` to `verifyBundle`.\n */\nexport class BundleVerificationError extends AtlaSentError {\n override name = \"BundleVerificationError\";\n\n readonly reason: BundleVerificationErrorInit[\"reason\"];\n readonly snapshotValidUntil: string | undefined;\n readonly snapshotFetchedAt: string | undefined;\n readonly snapshotSource: \"pinned\" | \"live\" | undefined;\n readonly kid: string | undefined;\n\n constructor(init: BundleVerificationErrorInit) {\n super(`AtlaSent audit bundle verification failed: ${init.reason}`);\n this.reason = init.reason;\n this.snapshotValidUntil = init.snapshotValidUntil;\n this.snapshotFetchedAt = init.snapshotFetchedAt;\n this.snapshotSource = init.snapshotSource;\n this.kid = init.kid;\n }\n}\n\n","/**\n * Hybrid trust-root bootstrap and snapshot management.\n *\n * At module load, seeds from the vendor snapshot in vendor/trust-root/.\n * Optionally refreshes from https://keys.atlasent.io/.well-known/ on\n * a configurable interval (default 4h, floor 5 min per ADR-005 D2).\n * Refresh failure is silent — falls back to the in-memory snapshot.\n *\n * Snapshot expiry (valid_until) is fail-closed per ADR-005 D3:\n * checkExpiry() emits a one-time console.warn at half-life, and again\n * on expiry. verifyAuditBundle throws BundleVerificationError when\n * expired (unless allowExpiredSnapshot=true is passed).\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { resolve, dirname } from \"node:path\";\n\n// Types for the trust-root document shapes\nexport interface TrustRootKey {\n kid: string;\n role: \"R1_release\" | \"R2_permit\" | \"R3_audit\" | \"R4_pack\";\n kty: string;\n crv?: string;\n alg: string;\n x?: string;\n valid_from?: string | null;\n valid_until?: string | null;\n replaced_by?: string | null;\n revoked?: boolean;\n tenant?: string | null;\n}\n\nexport interface TrustRootRevocationEntry {\n kid: string;\n role?: string;\n revoked_at: string;\n reason?: string;\n}\n\nexport interface TrustRootSnapshot {\n /** ISO-8601 expiry of this snapshot; fail-closed when exceeded */\n valid_until: string;\n issued_at: string;\n keys: TrustRootKey[];\n revoked_keys: TrustRootRevocationEntry[];\n revoked_identities: Array<{ identity: string; revoked_at: string; reason?: string }>;\n}\n\nexport interface TrustRootManagerOptions {\n /** Override the refresh URL (default: https://keys.atlasent.io/.well-known/) */\n refreshBaseUrl?: string;\n /** Refresh interval in ms. Default: 4h. Floor: 5 min. */\n refreshIntervalMs?: number;\n /** Disable automatic background refresh. */\n disableRefresh?: boolean;\n /** Custom fetch implementation (for tests). */\n fetch?: typeof fetch;\n}\n\nconst REFRESH_INTERVAL_MS_DEFAULT = 4 * 60 * 60 * 1000; // 4 hours\nconst REFRESH_INTERVAL_MS_FLOOR = 5 * 60 * 1000; // 5 minutes\nconst KEYS_BASE_URL = \"https://keys.atlasent.io/.well-known\";\n\n// Half-life and expiry warnings: emitted once per process (ADR-005 D3).\nlet _halfLifeWarningEmitted = false;\nlet _expiredWarningEmitted = false;\n\nfunction _resetWarningFlags(): void {\n _halfLifeWarningEmitted = false;\n _expiredWarningEmitted = false;\n}\n\nexport class TrustRootManager {\n private _snapshot: TrustRootSnapshot;\n private _refreshTimer: ReturnType<typeof setInterval> | null = null;\n private readonly _opts: Required<TrustRootManagerOptions>;\n\n constructor(\n initialSnapshot: TrustRootSnapshot,\n opts: TrustRootManagerOptions = {},\n ) {\n this._snapshot = initialSnapshot;\n const intervalMs = Math.max(\n opts.refreshIntervalMs ?? REFRESH_INTERVAL_MS_DEFAULT,\n REFRESH_INTERVAL_MS_FLOOR,\n );\n this._opts = {\n refreshBaseUrl: opts.refreshBaseUrl ?? KEYS_BASE_URL,\n refreshIntervalMs: intervalMs,\n disableRefresh: opts.disableRefresh ?? false,\n fetch:\n opts.fetch ??\n (typeof globalThis !== \"undefined\" && globalThis.fetch\n ? globalThis.fetch.bind(globalThis)\n : ((_url: string) =>\n Promise.reject(new Error(\"fetch not available\"))) as typeof fetch),\n };\n if (!this._opts.disableRefresh) {\n this._scheduleRefresh();\n }\n }\n\n getSnapshot(): TrustRootSnapshot {\n return this._snapshot;\n }\n\n /**\n * Check whether the snapshot is expired, emit one-time warnings at\n * half-life and expiry. Returns \"ok\" | \"half_life\" | \"expired\".\n *\n * Emits console.warn once per process at half-life (ADR-005 D3).\n * Emits console.warn once per process on expiry.\n */\n checkExpiry(): \"ok\" | \"half_life\" | \"expired\" {\n const snap = this._snapshot;\n const now = Date.now();\n const issuedAt = new Date(snap.issued_at).getTime();\n const validUntil = new Date(snap.valid_until).getTime();\n\n if (now > validUntil) {\n if (!_expiredWarningEmitted) {\n _expiredWarningEmitted = true;\n const daysAgo = Math.floor((now - validUntil) / (24 * 60 * 60 * 1000));\n // eslint-disable-next-line no-console\n console.warn(\n `[atlasent] Trust snapshot expired ${daysAgo} day(s) ago (valid_until: ${snap.valid_until}). ` +\n \"Update to a newer SDK build or enable allowExpiredSnapshot.\",\n );\n }\n return \"expired\";\n }\n const window = validUntil - issuedAt;\n const halfLife = issuedAt + window / 2;\n if (now > halfLife) {\n if (!_halfLifeWarningEmitted) {\n _halfLifeWarningEmitted = true;\n const daysLeft = Math.floor((validUntil - now) / (24 * 60 * 60 * 1000));\n // eslint-disable-next-line no-console\n console.warn(\n `[atlasent] Trust snapshot at half-life: expires in ${daysLeft} day(s) (valid_until: ${snap.valid_until}). ` +\n \"Plan an SDK update.\",\n );\n }\n return \"half_life\";\n }\n return \"ok\";\n }\n\n /** Look up a key entry by kid. Returns undefined if not found. */\n lookupKey(kid: string): TrustRootKey | undefined {\n return this._snapshot.keys.find((k) => k.kid === kid);\n }\n\n /** Returns true if the kid appears in revoked_keys. */\n isRevoked(kid: string): boolean {\n return this._snapshot.revoked_keys.some((r) => r.kid === kid);\n }\n\n /** Replace the snapshot (e.g. after a successful refresh). */\n replaceSnapshot(next: TrustRootSnapshot): void {\n this._snapshot = next;\n }\n\n stopRefresh(): void {\n if (this._refreshTimer !== null) {\n clearInterval(this._refreshTimer);\n this._refreshTimer = null;\n }\n }\n\n private _scheduleRefresh(): void {\n this._refreshTimer = setInterval(() => {\n void this._doRefresh();\n }, this._opts.refreshIntervalMs);\n // Don't hold the process open.\n if (\n this._refreshTimer &&\n typeof this._refreshTimer === \"object\" &&\n \"unref\" in this._refreshTimer\n ) {\n (this._refreshTimer as { unref(): void }).unref();\n }\n }\n\n private async _doRefresh(): Promise<void> {\n try {\n const base = this._opts.refreshBaseUrl.replace(/\\/$/, \"\");\n const [keysRes, revocRes] = await Promise.all([\n this._opts.fetch(`${base}/atlasent-verifier-keys.json`),\n this._opts.fetch(`${base}/atlasent-revocations.json`),\n ]);\n const indexRes = await this._opts.fetch(`${base}/atlasent-trust-root.json`);\n\n if (!keysRes.ok || !revocRes.ok || !indexRes.ok) return;\n\n const [keys, revoc, index] = await Promise.all([\n keysRes.json() as Promise<{ keys: TrustRootKey[] }>,\n revocRes.json() as Promise<{\n revoked_keys: TrustRootRevocationEntry[];\n revoked_identities: unknown[];\n }>,\n indexRes.json() as Promise<{ valid_until: string; issued_at: string }>,\n ]);\n\n if (!index.valid_until || !Array.isArray(keys.keys)) return;\n\n this._snapshot = {\n valid_until: index.valid_until,\n issued_at: index.issued_at ?? this._snapshot.issued_at,\n keys: keys.keys,\n revoked_keys: revoc.revoked_keys ?? [],\n revoked_identities:\n (revoc.revoked_identities as Array<{\n identity: string;\n revoked_at: string;\n }>) ?? [],\n };\n } catch {\n // Refresh failure is silent — keep using the current snapshot.\n }\n }\n}\n\n// ─── Load the embedded (vendor) snapshot ─────────────────────────────────────\n\nfunction _loadVendorSnapshot(): TrustRootSnapshot {\n try {\n // Resolve relative to the package root. Works both when running from\n // typescript/ (dev) and from dist/ (published).\n let packageRoot: string;\n try {\n // ESM: use import.meta.url\n const thisFile = fileURLToPath(import.meta.url);\n // src/trustRoot.ts → ../../vendor/trust-root OR\n // dist/trustRoot.js → ../../vendor/trust-root\n packageRoot = resolve(dirname(thisFile), \"..\", \"..\");\n } catch {\n // CJS or bundler: fall back to __dirname if available\n packageRoot = resolve(__dirname, \"..\", \"..\");\n }\n\n const vendorDir = resolve(packageRoot, \"vendor\", \"trust-root\");\n\n const index = JSON.parse(\n readFileSync(resolve(vendorDir, \"atlasent-trust-root.json\"), \"utf8\"),\n ) as { valid_until: string; issued_at: string };\n\n const verifierKeys = JSON.parse(\n readFileSync(resolve(vendorDir, \"atlasent-verifier-keys.json\"), \"utf8\"),\n ) as { keys: TrustRootKey[] };\n\n const revocations = JSON.parse(\n readFileSync(resolve(vendorDir, \"atlasent-revocations.json\"), \"utf8\"),\n ) as {\n revoked_keys: TrustRootRevocationEntry[];\n revoked_identities: Array<{ identity: string; revoked_at: string }>;\n };\n\n return {\n valid_until: index.valid_until,\n issued_at: index.issued_at,\n keys: verifierKeys.keys ?? [],\n revoked_keys: revocations.revoked_keys ?? [],\n revoked_identities: revocations.revoked_identities ?? [],\n };\n } catch {\n // Fallback: a minimal never-expiring snapshot so the SDK degrades\n // gracefully in build environments where vendor/ is not present.\n return {\n valid_until: \"2099-01-01T00:00:00Z\",\n issued_at: \"2026-05-26T00:00:00Z\",\n keys: [],\n revoked_keys: [],\n revoked_identities: [],\n };\n }\n}\n\n// Process-global manager — created lazily.\nlet _globalManager: TrustRootManager | null = null;\n\nexport function getGlobalTrustRootManager(\n opts?: TrustRootManagerOptions,\n): TrustRootManager {\n if (!_globalManager) {\n _globalManager = new TrustRootManager(\n _loadVendorSnapshot(),\n opts ?? { disableRefresh: false },\n );\n }\n return _globalManager;\n}\n\n/** Replace the global manager (primarily for tests). */\nexport function __setGlobalTrustRootManagerForTests(\n mgr: TrustRootManager | null,\n): void {\n _globalManager = mgr;\n _resetWarningFlags();\n}\n\nexport { _resetWarningFlags as __resetWarningFlagsForTests };\n","/**\n * Public types for the AtlaSent TypeScript SDK.\n *\n * These shapes are deliberately minimal and 1:1 with the AtlaSent\n * authorization API. Request / response fields are camelCase on the\n * SDK side; the client handles snake_case translation on the wire.\n */\n\nimport type { AuditEventsPage, AuditExport } from \"./audit.js\";\n\n/**\n * Canonical 4-value policy decision, byte-identical to the wire.\n *\n * - `allow` — action is authorized; a Permit is issued.\n * - `deny` — action is blocked.\n * - `hold` — decision deferred (e.g. waiting on an approval signal).\n * - `escalate` — routed to a human reviewer queue.\n *\n * Pin to this type on new code.\n */\nexport type DecisionCanonical = \"allow\" | \"deny\" | \"hold\" | \"escalate\";\n\n/**\n * Decision type — unified with the canonical 4-value vocabulary.\n *\n * This type previously emitted `\"ALLOW\"` / `\"DENY\"` (uppercase, 2-value).\n * It now reflects the canonical wire values (`\"allow\" | \"deny\" | \"hold\" |\n * \"escalate\"`) so the `decision` and `decision_canonical` fields on\n * {@link EvaluateResponse} carry identical values and types.\n *\n * Backward compatibility: the SDK normalises API response values to\n * lowercase (`.toLowerCase()`) before returning them, so callers that\n * previously checked `=== \"ALLOW\"` must update to `=== \"allow\"`. The\n * canonical field `decision_canonical` is also available and was always\n * lowercase — prefer it on new code.\n *\n * Legacy uppercase input accepted by the SDK is normalised to lowercase\n * output; `\"ALLOW\"` in → `\"allow\"` out, `\"DENY\"` in → `\"deny\"` out.\n */\nexport type Decision = DecisionCanonical;\n\n/**\n * Rate-limit state parsed from the server's `X-RateLimit-*` headers.\n *\n * Present on every authenticated response (success and 429) when the\n * server emits the headers. `null` when the server doesn't — older\n * deployments, or internal endpoints that skip per-key rate limiting.\n *\n * Clients should check `remaining` and sleep until `resetAt` to\n * preemptively back off before hitting a 429.\n */\nexport interface RateLimitState {\n /** Value of `X-RateLimit-Limit` — the per-minute budget. */\n limit: number;\n /** Value of `X-RateLimit-Remaining` — unused budget in the current window. */\n remaining: number;\n /**\n * Parsed `X-RateLimit-Reset` — the UTC instant when the current\n * window's counter zeroes. Accepts either a unix-seconds integer or\n * an ISO 8601 string on the wire.\n */\n resetAt: Date;\n}\n\n/**\n * Canonical Deploy Gate V1 protected action.\n *\n * Use this constant (or its string value `\"production.deploy\"`) on all\n * new code. Server-side `action_classes.slug` was canonicalised to\n * `production.deploy` in atlasent-api PR #662 / atlasent-console\n * PR #432; the SDK default now matches.\n */\nexport const PRODUCTION_DEPLOY_ACTION = \"production.deploy\" as const;\n\n/**\n * Legacy alias for {@link PRODUCTION_DEPLOY_ACTION}.\n *\n * @deprecated since 2.3.0 — use {@link PRODUCTION_DEPLOY_ACTION}. The\n * server alias-tolerates `deployment.production` during the V1 alias\n * window, so existing callers continue to work unchanged; please\n * migrate by the next minor release.\n */\nexport const DEPLOYMENT_PRODUCTION_ACTION = \"deployment.production\" as const;\n\n// ── Deploy Gate V1 context types ──────────────────────────────────────────────────────\n\n/**\n * Permit claim for `production.deploy` evaluations (Rule 3).\n *\n * Pass as `permit` inside {@link DeployGateContext}.\n * The `verified` flag is set by the verify-permit service after a\n * successful `/v1-verify-permit` call — do not self-assert it.\n */\nexport interface DeployPermitClaim {\n permit_id?: string;\n environment?: string;\n action_type?: string;\n /** ISO-8601 timestamp when the permit was issued. */\n issued_at?: string;\n /** Set server-side by the verify-permit service. Do not self-assert. */\n verified?: boolean;\n}\n\n/**\n * Override claim for `production.deploy` evaluations (Rule 8).\n *\n * Both `override_reason` and `authority_basis` must be non-empty to\n * receive `OVERRIDE_APPROVED`. Missing or blank fields return `DENY_POLICY`.\n */\nexport interface DeployOverrideClaim {\n /** Human-readable reason. Required and non-empty. */\n override_reason?: string;\n /** Authoritative basis — runbook section, incident ticket, etc. Required and non-empty. */\n authority_basis?: string;\n /** Approver actor ID (audit record; does not gate the decision). */\n approver_actor_id?: string;\n}\n\n/**\n * Typed context shape for `production.deploy` evaluations.\n *\n * Pass as `context` to `protect()`, `deployGate()`, or\n * {@link AtlaSentClient.evaluate} for the Deploy Gate V1 flow.\n *\n * @example\n * ```ts\n * const permit = await atlasent.protect({\n * agent: \"deploy-bot\",\n * action: PRODUCTION_DEPLOY_ACTION,\n * context: {\n * environment: \"production\",\n * evaluation_confirmed: true,\n * actorMetadata: { role: \"deploy_engineer\" },\n * permit: {\n * permit_id: permitToken,\n * environment: \"production\",\n * action_type: PRODUCTION_DEPLOY_ACTION,\n * issued_at: new Date().toISOString(),\n * verified: true,\n * },\n * } satisfies DeployGateContext,\n * });\n * ```\n */\nexport interface DeployGateContext {\n /** Must be `\"production\"` for the production gate to apply. */\n environment?: \"production\" | \"staging\" | \"development\";\n /**\n * When `true`, all rule failures are shadowed to `allow` (fail-open).\n * Malformed-timestamp inconsistencies still escalate.\n * Use for initial rollout before locking enforcement.\n */\n pilot_mode?: boolean;\n /** Must be `true` — confirms an evaluation record exists before proceeding. */\n evaluation_confirmed?: boolean;\n /** ISO-8601 timestamp of when evaluation was confirmed. */\n evaluation_confirmed_at?: string;\n /** Actor role metadata. `role` must be one of the approved deploy roles. */\n actorMetadata?: { role?: string };\n /** Signed permit claim — required for non-pilot production deployments. */\n permit?: DeployPermitClaim;\n /** Override claim — short-circuits all rules when both fields are non-empty. */\n override?: DeployOverrideClaim;\n [key: string]: unknown;\n}\n\n/**\n * Canonical deploy gate decision codes emitted for `production.deploy`.\n *\n * Appears as `deny_code` / `matchedRuleId` on evaluation responses.\n * Pin dashboards, alerting, and routing logic to these codes — not to\n * `deny_reason` strings, which may change.\n */\nexport type DeployGateDenyCode =\n | \"ALLOW\"\n | \"DENY_POLICY\"\n | \"DENY_AUTHORITY\"\n | \"DENY_ENVIRONMENT\"\n | \"PERMIT_EXPIRED\"\n | \"VERIFY_FAILED\"\n | \"ESCALATE_REQUIRED\"\n | \"OVERRIDE_APPROVED\";\n\n/** Typed constants for {@link DeployGateDenyCode}. */\nexport const DEPLOY_GATE_CODES = Object.freeze({\n ALLOW: \"ALLOW\",\n DENY_POLICY: \"DENY_POLICY\",\n DENY_AUTHORITY: \"DENY_AUTHORITY\",\n DENY_ENVIRONMENT: \"DENY_ENVIRONMENT\",\n PERMIT_EXPIRED: \"PERMIT_EXPIRED\",\n VERIFY_FAILED: \"VERIFY_FAILED\",\n ESCALATE_REQUIRED: \"ESCALATE_REQUIRED\",\n OVERRIDE_APPROVED: \"OVERRIDE_APPROVED\",\n} satisfies Record<DeployGateDenyCode, DeployGateDenyCode>);\n\n/** Input to {@link AtlaSentClient.deployGate}. */\nexport interface DeployGateRequest {\n /** CI/repo actor performing the deployment. Defaults to `ci-deploy-bot`. */\n agent?: string;\n /** Protected action. Defaults to `production.deploy`. */\n action?:\n | typeof PRODUCTION_DEPLOY_ACTION\n | typeof DEPLOYMENT_PRODUCTION_ACTION\n | string;\n /** Typed deploy gate context for `production.deploy`. */\n context?: DeployGateContext | Record<string, unknown>;\n}\n\n/** Evidence metadata returned by {@link AtlaSentClient.deployGate}. */\nexport interface DeployGateEvidence {\n permitId?: string;\n permitHash?: string;\n auditHash?: string;\n verifiedAt?: string;\n}\n\n/** Result of the canonical Deploy Gate V1 flow. */\nexport interface DeployGateResponse {\n /** True only after evaluate allowed AND `/v1-verify-permit` verified server-side. */\n allowed: boolean;\n /** Evaluation response from `POST /v1-evaluate`, when available. */\n evaluation?: EvaluateResponse;\n /** Verification response from `POST /v1-verify-permit`, when evaluation allowed. */\n verification?: VerifyPermitResponse;\n /** Human-readable block/allow reason. */\n reason: string;\n /** Best-effort audit/evidence metadata available to the SDK. */\n evidence: DeployGateEvidence;\n}\n\n/**\n * Frozen BVS snapshot wire shape (BI4).\n * Carried in {@link EvaluateRequest}.context.bvsSnapshot when\n * the `behavior_conditioning` flag is enabled for the tenant.\n * Produced by behavior-insights GET /api/patterns/snapshot/:userId\n * and attached via `@atlasent/behavior` attachToEvaluate().\n */\nexport interface BvsSnapshot {\n user_id: string;\n /** Factor model output — keyed by BVS factor slug, value is score 0-1. */\n factors: Record<string, number>;\n /** Aggregate confidence score (0-1). Decays on a 60-day half-life. */\n confidence: number;\n /** True when the aggregate is fresh-and-thin (too few events to trust). */\n confidence_low: boolean;\n /** ISO-8601 timestamp of the compute run that produced this snapshot. */\n computed_at: string;\n}\n\n/**\n * Consent-class projection (BI5) — the privacy-safe aggregate shape that\n * third-party apps (LedgersMe, hiCoach, echobloom) receive when reading a\n * user's behavioral summary. Counts and timestamps only; no raw free-text.\n * Produced by behavior-insights `/api/patterns/summary/:userId` and fetched\n * via `@atlasent/behavior` getStateSummary(). The SDK enforces\n * {@link https://github.com/AtlaSent-Systems-Inc/atlasent-sdk | assertNoRawText}\n * client-side before returning this shape to callers.\n */\nexport interface ConsentClassProjection {\n user_id: string;\n window_start: string;\n window_end: string;\n event_count: number;\n category_counts: Partial<Record<string, number>>;\n}\n\n/**\n * Proof that a specific actor consumed a specific permit for a specific\n * action_type. Pass an array of these as `completion_proofs` on an evaluate\n * request to satisfy multi-actor quorum dependencies.\n *\n * The runtime verifies each proof via two gates (both must pass):\n * 1. A `permit_uses` row exists for `permit_id` (permit was consumed).\n * 2. An `execution_evaluations` row is bound to `actor_id` + `action_type`\n * for the same permit (actor/action binding — Codex P1 #1148 FIX #3).\n * Proofs that fail either gate are silently dropped (fail-closed).\n */\nexport interface CompletionProof {\n /** The action_type (slug) that was completed by the prior actor. */\n action_type: string;\n /** The actor who completed the action. */\n actor_id: string;\n /** The permit token (or its hash) issued when the action was permitted. */\n permit_id: string;\n}\n\n/** Input to {@link AtlaSentClient.evaluate}. */\nexport interface EvaluateRequest {\n /** Identifier of the calling agent (e.g. \"clinical-data-agent\"). */\n agent: string;\n /** The action being authorized (e.g. \"modify_patient_record\"). */\n action: string;\n /** Arbitrary policy context (user, environment, resource IDs). */\n context?: Record<string, unknown>;\n /**\n * When `true`, the server populates `riskEnvelope.factors` with a\n * per-factor breakdown of the weighted risk score. Omit (or `false`)\n * to keep response payloads small.\n */\n explain?: boolean;\n /** Deployment environment where the action executes (e.g. `\"production\"`). */\n environment?: string;\n /** Structured resource descriptor. Prefer over embedding resource info in `context`. */\n resource?: { type: string; id?: string; attributes?: Record<string, unknown> };\n /** Snapshot of the resource state before the proposed action. Enables state-transition-aware policy evaluation. */\n current_state?: { description: string; attributes?: Record<string, unknown> };\n /** Desired resource state after the action executes. */\n proposed_state?: { description: string; attributes?: Record<string, unknown> };\n /** Execution surface binding — identifies the CI/CD adapter, DB driver, or enforcement point. */\n execution_binding?: { kind: string; adapter_version?: string; resource_id?: string; enforcement_point?: string };\n /** The desired end-state the actor wants the resource to reach. Enables trajectory-aware authorization. */\n desired_state?: { description: string; attributes?: Record<string, unknown>; fingerprint?: string };\n /** Actor-proposed execution path from current_state to desired_state. The engine returns an authorized_trajectory that may differ. */\n proposed_trajectory?: {\n steps: Array<{\n step: string;\n description?: string;\n required: boolean;\n time_limit_seconds?: number;\n authorized_by?: string;\n constraints?: Record<string, unknown>;\n }>;\n description?: string;\n };\n /**\n * Multi-actor quorum completion proofs. Supply one entry per prior actor\n * whose completed action this evaluation depends on. The runtime verifies\n * each proof (consumed-permit gate + actor/action binding gate) and counts\n * only valid proofs toward quorum. Absent or empty → no quorum proofs\n * submitted (no behavioral change for non-quorum dependencies).\n */\n completion_proofs?: CompletionProof[];\n}\n\n/**\n * Slim permit object embedded in {@link EvaluateResponse} when the decision\n * is `\"allow\"`. Contains the essential fields needed to act on the permit\n * immediately without a separate `GET /v1/permits/:id` round-trip.\n *\n * Mirrors the `Permit` schema in atlasent-control-plane\n * `api/src/schemas/permits.ts`.\n */\nexport interface EvaluateResponsePermit {\n id: string;\n orgId: string;\n subject: string;\n scope: string;\n status: \"active\" | \"revoked\" | \"expired\";\n /** The evaluation that produced this permit. */\n evaluationId: string | null;\n issuedBy: string;\n revokedBy: string | null;\n /** ISO-8601 issuance timestamp. */\n issuedAt: string;\n revokedAt: string | null;\n expiresAt: string | null;\n metadata: Record<string, unknown> | null;\n}\n\n/** Result of {@link AtlaSentClient.evaluate}. */\nexport interface EvaluateResponse {\n /**\n * Policy decision — canonical 4-value lowercase vocabulary:\n * `\"allow\"`, `\"deny\"`, `\"hold\"`, or `\"escalate\"`.\n *\n * Previously emitted `\"ALLOW\"` / `\"DENY\"` (uppercase, 2-value);\n * the SDK now normalises all values to lowercase and passes `hold`\n * and `escalate` through rather than collapsing them to `\"DENY\"`.\n *\n * The `decision_canonical` field carries the same value and is the\n * recommended field for new code.\n */\n decision: Decision;\n /**\n * Canonical 4-value decision, byte-identical to the wire.\n *\n * One of `\"allow\"`, `\"deny\"`, `\"hold\"`, `\"escalate\"`. Branch on\n * this field on new code. `hold` and `escalate` are non-terminal\n * states that route to a human reviewer / approval signal — they\n * are not equivalent to a `deny`.\n */\n decision_canonical: DecisionCanonical;\n /**\n * Server-assigned identifier for this evaluation decision.\n *\n * Stable across retries and used as the key for proof retrieval\n * (`GET /v1/proof/:evaluationId`) and override requests. Also\n * available as the legacy `permitId` field for backward compatibility.\n */\n evaluationId: string;\n /** Opaque permit identifier, passed to {@link AtlaSentClient.verifyPermit}.\n *\n * @deprecated Prefer `evaluationId`. This field is kept for backward\n * compatibility and points to the same server-assigned ID.\n */\n permitId: string;\n /**\n * Slim permit object issued when `decision === \"allow\"`.\n * `null` on deny, hold, or escalate decisions.\n *\n * Mirrors the `Permit` schema from the control-plane.\n */\n permit: EvaluateResponsePermit | null;\n /**\n * Opaque HMAC-signed permit token issued when `decision === \"allow\"`.\n * Pass to `POST /v1/verify-permit` to verify the permit server-side.\n * `null` on deny, hold, or escalate decisions.\n */\n permitToken: string | null;\n /**\n * Machine-readable reasons emitted by the policy engine.\n *\n * The array may be empty. For deny/hold/escalate decisions the array\n * typically contains a single human-readable explanation; for allow\n * decisions it is often empty. Do not parse these strings — use\n * `decision` for branching.\n */\n reasons: string[];\n /** Human-readable explanation from the policy engine.\n *\n * @deprecated Prefer `reasons[0]` or `reasons`. This field is the\n * first element of `reasons` (or an empty string) for backward compat.\n */\n reason: string;\n /** Hash-chained audit-trail entry (21 CFR Part 11 / GxP-ready). */\n auditHash: string;\n /** ISO 8601 timestamp of the decision. */\n timestamp: string;\n /**\n * Per-key rate-limit state for this request's response, parsed from\n * `X-RateLimit-*` headers. `null` when the server didn't emit them.\n */\n rateLimit: RateLimitState | null;\n /**\n * Risk envelope summary from the policy engine. Present on all responses\n * from engine version wire-v1@1.0.0+. Provides the weighted risk score,\n * the pre/post-promotion decisions, and (when evaluate was called with\n * `explain: true`) a per-factor breakdown.\n *\n * The envelope can only raise severity — it structurally cannot soften\n * a deny to allow. When `promoted` is true the live `decision` was\n * upgraded from `engineDecision` to `envelopeDecision`.\n */\n riskEnvelope?: EvaluateRiskEnvelope;\n /**\n * Resolved risk class from the evaluation engine.\n * One of `\"critical\"`, `\"high\"`, `\"medium\"`, `\"low\"`.\n * Present when the risk envelope assigns a class.\n */\n riskClass?: string;\n /**\n * WHY this permit was issued — the authority kind and a reference to the\n * authorizing entity. Present on `allow` decisions when the control plane\n * attaches explicit authority provenance.\n */\n authorityBasis?: {\n kind: \"policy\" | \"approval\" | \"emergency\" | \"maintenance_window\" | \"delegation\" | \"quorum\";\n reference?: string;\n grantedBy?: string;\n rationale?: string;\n expiresAt?: string;\n };\n /**\n * ID of the HITL escalation auto-created by the control plane.\n * Present iff `decision === \"hold\"`. Poll `GET /v1/escalations/{id}`\n * for resolution status.\n */\n escalationId?: string;\n /**\n * Authorized execution trajectory returned when the engine approved a\n * `proposed_trajectory`. Present only on `allow` decisions.\n * May differ from what was proposed — the engine may add checkpoints,\n * restrict steps, or tighten time limits. Follow this trajectory exactly;\n * call `POST /v1/trajectory-verify` at each step to confirm on_trajectory.\n */\n authorized_trajectory?: {\n trajectory_id: string;\n steps: Array<{\n step: string;\n description?: string;\n required: boolean;\n time_limit_seconds?: number;\n authorized_by?: string;\n constraints?: Record<string, unknown>;\n expected_intermediate_state?: { description: string; attributes?: Record<string, unknown>; fingerprint?: string };\n }>;\n description?: string;\n forbidden_states?: Array<{ description: string; attributes?: Record<string, unknown>; fingerprint?: string }>;\n expires_at: string;\n };\n}\n\n/** Per-factor contribution in a {@link EvaluateRiskEnvelope}. */\nexport interface EvaluateRiskEnvelopeFactor {\n /** Factor identifier, e.g. `\"ACTION_SENSITIVITY\"`. */\n factor: string;\n /** Factor score in [0, 1]. Higher = more risk. */\n value: number;\n /** Configured weight for this factor. */\n weight: number;\n /** Human-readable explanation for the score. */\n reason: string;\n}\n\n/** Risk envelope summary returned in a top-level {@link EvaluateResponse}. */\nexport interface EvaluateRiskEnvelope {\n /** Weighted risk score in [0, 1]. Score ≥ 0.70 triggers a hold. */\n weightedScore: number;\n /** Policy engine decision before envelope promotion. */\n engineDecision: Decision;\n /** Decision resolved by the risk envelope. */\n envelopeDecision: Decision;\n /** `true` when the envelope raised the decision's severity (most-restrictive-wins). */\n promoted: boolean;\n /** Deny codes that unconditionally block regardless of score. */\n hardBlocks: string[];\n /** Per-factor breakdown. Present only when `explain: true` was passed. */\n factors?: EvaluateRiskEnvelopeFactor[];\n}\n\n/** Input to {@link AtlaSentClient.verifyPermit}. */\nexport interface VerifyPermitRequest {\n /** The permit ID returned by a prior evaluate() call. */\n permitId: string;\n /** Optional: re-state the action for cross-check with the server. */\n action?: string;\n /** Optional: re-state the agent for cross-check with the server. */\n agent?: string;\n /** Optional: re-state the context for cross-check with the server. */\n context?: Record<string, unknown>;\n /**\n * Environment of the permit being verified. Sourced from the evaluate\n * payload (context.environment → top-level environment → \"production\").\n * Required by the server for production permits as of 2026-05-14.\n * P1-1 fix: withPermit/protect now always populates this field.\n */\n environment?: string;\n /**\n * SHA-256 hex digest of the recursively key-sorted canonical JSON of the\n * original evaluate payload. Required by the server for production permits\n * as of 2026-05-14.\n * P1-5 fix: withPermit/protect now always computes and sends this field.\n */\n execution_hash?: string;\n}\n\n/**\n * Result of {@link AtlaSentClient.verifyPermit}.\n *\n * @deprecated Use {@link VerifyPermitByIdResponse} via\n * {@link AtlaSentClient.verifyPermitById} — the canonical REST surface\n * (`POST /v1/permits/{id}/verify`) returns the unified verification\n * envelope (`valid`, `verification_type`, `reason`, `verified_at`,\n * `evidence`) plus the full {@link PermitRecord} fields. Will be\n * removed in `@atlasent/sdk@3`.\n */\nexport interface VerifyPermitResponse {\n /** `true` when the permit is valid and un-revoked. */\n verified: boolean;\n /** Verification outcome string from the server. */\n outcome: string;\n /** Verification hash bound to the permit. */\n permitHash: string;\n /** ISO 8601 timestamp of the verification. */\n timestamp: string;\n /**\n * ISO-8601 expiration timestamp of the permit. `null` on pre-rollout\n * server versions that do not yet surface this field.\n */\n expiresAt: string | null;\n /**\n * Per-key rate-limit state for this request's response, parsed from\n * `X-RateLimit-*` headers. `null` when the server didn't emit them.\n */\n rateLimit: RateLimitState | null;\n}\n\n/**\n * Result of {@link AtlaSentClient.keySelf} — self-introspection of the API\n * key the client was constructed with. Returned by `GET /v1/api-key-self`.\n *\n * Never includes the raw key or its hash — introspection is intentionally\n * read-only and safe to surface in operator dashboards.\n */\nexport interface ApiKeySelfResponse {\n /** Server-side UUID of the api_keys row for this key. */\n keyId: string;\n /** Organization the key belongs to. */\n orgId: string;\n /** \"live\" or \"test\" (or any future environment label the server introduces). */\n environment: string;\n /** Granted scopes — e.g. [\"evaluate\", \"audit.read\"]. */\n scopes: string[];\n /**\n * Per-key IP allowlist as CIDR strings (e.g. [\"10.0.0.0/8\"]). `null`\n * when the key is unrestricted.\n */\n allowedCidrs: string[] | null;\n /** Server-enforced per-minute rate limit for this key. */\n rateLimitPerMinute: number;\n /** Client IP as the server observed it (first hop of X-Forwarded-For). */\n clientIp: string | null;\n /** Server-stored expiry; `null` means the key does not auto-expire. */\n expiresAt: string | null;\n /**\n * Per-key rate-limit state for this request's response, parsed from\n * `X-RateLimit-*` headers. `null` when the server didn't emit them.\n */\n rateLimit: RateLimitState | null;\n}\n\n/**\n * Result of {@link AtlaSentClient.listAuditEvents}. Extends the raw\n * wire page with a camelCase `rateLimit` alongside the snake_case\n * wire fields.\n */\nexport interface AuditEventsResult extends AuditEventsPage {\n rateLimit: RateLimitState | null;\n}\n\n/**\n * Filter accepted by {@link AtlaSentClient.createAuditExport}.\n */\nexport interface AuditExportRequest {\n /** Comma-joined list of event types to include. */\n types?: string;\n /** Filter to a single actor. */\n actor_id?: string;\n /** Inclusive lower bound on `occurred_at` (ISO 8601). */\n from?: string;\n /** Inclusive upper bound on `occurred_at` (ISO 8601). */\n to?: string;\n}\n\n/**\n * Result of {@link AtlaSentClient.createAuditExport}.\n */\nexport interface AuditExportResult extends AuditExport {\n rateLimit: RateLimitState | null;\n}\n\n/** Constructor options for {@link AtlaSentClient}. */\nexport interface AtlaSentClientOptions {\n /** Required. Your AtlaSent API key. */\n apiKey: string;\n /** API base URL. Defaults to \"https://api.atlasent.io\". */\n baseUrl?: string;\n /** Per-request timeout in milliseconds. Defaults to 10_000. */\n timeoutMs?: number;\n /**\n * Inject a fetch implementation (primarily for testing).\n * Defaults to `globalThis.fetch`.\n */\n fetch?: typeof fetch;\n /**\n * Retry policy for transient failures (network errors, timeouts,\n * 429 rate-limit, 5xx server errors, malformed responses).\n * Omit to use the default: 4 total attempts, 2 000 ms base, 16 000 ms cap,\n * full-jitter exponential backoff matching the Python SDK schedule\n * (2 s → 4 s → 8 s → 16 s).\n * Pass `{ maxAttempts: 1 }` to disable retries entirely.\n */\n retryPolicy?: import(\"./retry.js\").RetryPolicy;\n /**\n * Base URL for the trust-root host (default: https://keys.atlasent.io/.well-known).\n * Override for air-gapped / enterprise mirror deployments.\n * Per ADR-005 D2.\n */\n trustRootUrl?: string;\n /**\n * Trust-root snapshot refresh interval in milliseconds.\n * Default: 4 hours. Floor: 5 minutes (ADR-005 D2).\n * Set to 0 to inherit the default.\n */\n trustSnapshotRefreshMs?: number;\n}\n\n// ── Permit lifecycle (canonical REST shapes) ───────────────────────────────────────────\n\n/** Permit lifecycle status. */\nexport type PermitStatus =\n | \"issued\"\n | \"verified\"\n | \"consumed\"\n | \"expired\"\n | \"revoked\";\n\n/**\n * Wire shape of a Permit row, returned by {@link AtlaSentClient.getPermit}\n * and {@link AtlaSentClient.listPermits}.\n */\nexport interface PermitRecord {\n id: string;\n org_id: string;\n actor_id: string;\n action_id: string;\n target_id?: string;\n environment?: string;\n status: PermitStatus;\n issued_at: string;\n expires_at: string;\n consumed_at?: string | null;\n revoked_at?: string | null;\n revoked_by?: string | null;\n revoke_reason?: string | null;\n signature?: string;\n payload_hash?: string | null;\n decision_id?: string | null;\n /** SHA-256 hex of the CDO that produced this permit. P1 provisional. */\n cdo_hash?: string | null;\n}\n\n/** Optional filters for {@link AtlaSentClient.listPermits}. */\nexport interface ListPermitsRequest {\n status?: PermitStatus;\n actorId?: string;\n actionType?: string;\n from?: string;\n to?: string;\n limit?: number;\n cursor?: string;\n}\n\n/** Response from {@link AtlaSentClient.listPermits}. */\nexport interface ListPermitsResponse {\n permits: PermitRecord[];\n total: number;\n nextCursor?: string;\n rateLimit: RateLimitState | null;\n}\n\n/** Response from {@link AtlaSentClient.getPermit}. */\nexport interface GetPermitResponse {\n permit: PermitRecord;\n rateLimit: RateLimitState | null;\n}\n\n/**\n * Response from {@link AtlaSentClient.checkPermitValid}.\n */\nexport interface PermitValidResponse {\n valid: boolean;\n status: \"active\" | \"expired\" | \"revoked\" | \"consumed\";\n revoked_at?: string;\n revocation_id?: string;\n}\n\n// ── Canonical revoke / verify (REST) ──────────────────────────────────────────────────\n\n/** Input for {@link AtlaSentClient.revokePermitById}. */\nexport interface RevokePermitByIdInput {\n reason?: string;\n}\n\n/**\n * Response from {@link AtlaSentClient.revokePermitById}.\n */\nexport interface RevokePermitByIdResponse {\n permit: PermitRecord;\n rateLimit: RateLimitState | null;\n}\n\n/**\n * Response from {@link AtlaSentClient.verifyPermitById}.\n */\nexport interface VerifyPermitByIdResponse {\n valid: boolean;\n verification_type: \"permit\";\n reason: string | null;\n verified_at: string;\n evidence: {\n permit_id: string;\n status: PermitStatus;\n actor_id?: string;\n action_id?: string;\n expires_at?: string;\n payload_hash?: string | null;\n decision_id?: string | null;\n };\n permit: PermitRecord;\n rateLimit: RateLimitState | null;\n}\n\n// ── Revoke permit ─────────────────────────────────────────────────────────────────────────\n\n/** Input for {@link AtlaSentClient.revokePermit}. */\nexport interface RevokePermitRequest {\n permitId: string;\n reason?: string;\n}\n\n/**\n * Result of {@link AtlaSentClient.revokePermit}.\n *\n * @deprecated Use {@link RevokePermitByIdResponse} via\n * {@link AtlaSentClient.revokePermitById}.\n * Will be removed in `@atlasent/sdk@3`.\n */\nexport interface RevokePermitResponse {\n revoked: boolean;\n permitId: string;\n revokedAt?: string | undefined;\n auditHash?: string | undefined;\n rateLimit: RateLimitState | null;\n}\n\n// ── Constraint trace (preflight) ────────────────────────────────────────────────────────\n\nexport interface ConstraintTraceStage {\n readonly stage: string;\n readonly rule?: string;\n readonly matched: boolean;\n readonly detail?: string;\n readonly order: number;\n readonly [key: string]: unknown;\n}\n\nexport interface ConstraintTracePolicy {\n readonly policy_id: string;\n readonly decision: string;\n readonly fingerprint: string;\n readonly risk_score?: number;\n readonly stages: ReadonlyArray<ConstraintTraceStage>;\n readonly [key: string]: unknown;\n}\n\nexport interface ConstraintTrace {\n readonly rules_evaluated: ReadonlyArray<ConstraintTracePolicy>;\n readonly matching_policy_id?: string;\n readonly [key: string]: unknown;\n}\n\nexport interface EvaluatePreflightResponse {\n readonly evaluation: EvaluateResponse;\n readonly constraintTrace: ConstraintTrace | null;\n}\n\n// ── Streaming evaluate ─────────────────────────────────────────────────────────────────────\n\nexport interface StreamOptions {\n signal?: AbortSignal;\n timeoutMs?: number;\n maxRetries?: number;\n}\n\nexport interface StreamDecisionEvent {\n type: \"decision\";\n decision: Decision;\n decision_canonical: DecisionCanonical;\n permitId: string;\n reason: string;\n auditHash: string;\n timestamp: string;\n isFinal: boolean;\n}\n\nexport interface StreamProgressEvent {\n type: \"progress\";\n stage: string;\n [key: string]: unknown;\n}\n\nexport type StreamEvent = StreamDecisionEvent | StreamProgressEvent;\n\n// ── Batch evaluate ────────────────────────────────────────────────────────────────────────────\n\nexport interface BatchEvalItem {\n agent: string;\n action: string;\n context?: Record<string, unknown>;\n}\n\nexport interface EvaluateBatchResultItem {\n index: number;\n decision?: DecisionCanonical;\n decisionId?: string;\n permitToken?: string | null;\n reason?: string;\n auditHash?: string;\n timestamp?: string;\n error?: string;\n message?: string;\n}\n\nexport interface BatchEvalResponse {\n batchId: string;\n items: EvaluateBatchResultItem[];\n partial: boolean;\n replayed?: boolean;\n rateLimit: RateLimitState | null;\n}\n\n// ── Decisions stream ──────────────────────────────────────────────────────────────────────\n\nexport interface SubscribeDecisionsOptions {\n types?: string[];\n actorId?: string;\n lastEventId?: string;\n maxSeconds?: number;\n signal?: AbortSignal;\n}\n\nexport interface DecisionStreamEvent {\n id?: string;\n type: string;\n decision?: DecisionCanonical;\n actorId?: string;\n resourceType?: string;\n resourceId?: string;\n payload?: Record<string, unknown>;\n hash?: string;\n previousHash?: string;\n occurredAt?: string;\n}\n\n// ── Trajectory authorization ────────────────────────────────────────────────────────────\n\n/** Verified snapshot of resource state. */\nexport interface StateSnapshot {\n description: string;\n attributes?: Record<string, unknown>;\n /** Deterministic hash of the state (e.g. schema fingerprint, content hash). */\n fingerprint?: string;\n recorded_at?: string;\n}\n\n/** Step in an execution trajectory. */\nexport interface TrajectoryStep {\n step: string;\n description?: string;\n required: boolean;\n time_limit_seconds?: number;\n authorized_by?: string;\n constraints?: Record<string, unknown>;\n expected_intermediate_state?: StateSnapshot;\n}\n\n/** Actor-submitted trajectory proposal. */\nexport interface ProposedTrajectory {\n steps: TrajectoryStep[];\n description?: string;\n}\n\n/** Evaluation-engine-returned authorized trajectory. May differ from the proposed trajectory. */\nexport interface AuthorizedTrajectory extends ProposedTrajectory {\n trajectory_id: string;\n forbidden_states?: StateSnapshot[];\n expires_at: string;\n}\n\n/** Input to POST /v1/trajectory-verify. */\nexport interface TrajectoryVerifyRequest {\n permit_token: string;\n current_step: string;\n current_state?: StateSnapshot;\n completed_steps?: string[];\n execution_context?: Record<string, unknown>;\n}\n\n/** Response from POST /v1/trajectory-verify. */\nexport interface TrajectoryVerifyResponse {\n on_trajectory: boolean;\n trajectory_position?: number;\n trajectory_complete: boolean;\n deviation?: TrajectoryDeviationEvent;\n verified_at: string;\n}\n\n/** Deviation type for trajectory deviation events. */\nexport type TrajectoryDeviationType =\n | \"step_not_on_trajectory\"\n | \"step_out_of_sequence\"\n | \"forbidden_state_reached\"\n | \"required_step_skipped\"\n | \"time_limit_exceeded\"\n | \"constraint_violation\"\n | \"trajectory_expired\";\n\n/** Emitted when execution departs from the authorized trajectory. */\nexport interface TrajectoryDeviationEvent {\n deviation_type: TrajectoryDeviationType;\n trajectory_id: string;\n permit_id: string;\n step?: string;\n actual_state?: StateSnapshot;\n expected_state?: StateSnapshot;\n reason: string;\n detected_at: string;\n}\n\n/** Evidence artifact: authorized trajectory vs. actual execution trace. */\nexport interface ComplianceComparisonArtifact {\n version: \"compliance_comparison.v1\";\n artifact_id: string;\n authorized_transition: {\n permit_id: string;\n desired_state: StateSnapshot;\n trajectory: AuthorizedTrajectory;\n spec_signature?: string;\n };\n execution_trace: {\n executed_steps: Array<{\n step: string;\n started_at: string;\n completed_at?: string;\n outcome: \"success\" | \"failure\" | \"skipped\";\n state_after?: StateSnapshot;\n }>;\n final_state: StateSnapshot;\n trace_signature?: string;\n };\n fidelity: {\n compliant: boolean;\n /** Score in [0, 1] measuring closeness of actual to authorized trajectory. */\n fidelity_score: number;\n missing_required_steps: string[];\n unexpected_steps: string[];\n forbidden_states_reached: StateSnapshot[];\n deviation_events: TrajectoryDeviationEvent[];\n };\n artifact_hash: string;\n generated_at: string;\n}\n\n// ── License verification (self-hosted / air-gapped) ───────────────────────────\n\n/**\n * License status for a self-hosted or air-gapped AtlaSent deployment.\n *\n * Returned by `GET /v1/license`. Describes the current validity, posture,\n * features, and optional limits for the license key installed on this instance.\n *\n * Callers should check `status === \"active\"` before relying on `features`.\n * A `\"grace\"` status means the license has expired but a grace period\n * (`grace_until`) has not yet elapsed — enforcement is not yet suspended, but\n * the license should be renewed immediately.\n */\nexport interface LicenseStatus {\n /**\n * Current validity state of the license.\n *\n * - `\"active\"` — license is valid and within its expiry window.\n * - `\"grace\"` — license has expired; a grace period (`grace_until`) applies.\n * - `\"expired\"` — license has expired and the grace period has elapsed.\n * - `\"revoked\"` — license has been explicitly revoked by AtlaSent.\n */\n status: \"active\" | \"grace\" | \"expired\" | \"revoked\";\n /** Slug of the organization this license was issued to. */\n org_slug: string;\n /**\n * Deployment posture the license was issued for.\n *\n * - `\"self_hosted\"` — customer-managed deployment with network access to the\n * AtlaSent license endpoint for periodic renewal checks.\n * - `\"air_gapped\"` — fully offline deployment; license verification is\n * entirely local (signed blob checked against the embedded public key).\n */\n posture: \"self_hosted\" | \"air_gapped\";\n /** ISO 8601 timestamp when the license expires. */\n expires_at: string;\n /**\n * ISO 8601 timestamp when the grace period ends.\n * Present only when `status === \"grace\"`.\n */\n grace_until?: string;\n /**\n * Feature flags enabled by this license (e.g. `\"governance\"`, `\"bvs\"`,\n * `\"federation\"`). Check presence of a specific feature with\n * `status.features.includes(\"feature_name\")`.\n */\n features: string[];\n /**\n * Maximum evaluations per day allowed by this license.\n * `undefined` means unlimited.\n */\n eval_limit?: number;\n /**\n * Maximum active seats (API key holders) allowed by this license.\n * `undefined` means unlimited.\n */\n seat_limit?: number;\n}\n\n/**\n * Result of submitting a license blob to `POST /v1/license/verify`.\n *\n * `valid` is the contract field — pin to it. When `valid` is `false`, the\n * `error` field carries a machine-readable reason code such as\n * `\"SIGNATURE_INVALID\"`, `\"ORG_MISMATCH\"`, `\"LICENSE_EXPIRED\"`, or\n * `\"LICENSE_REVOKED\"`.\n */\nexport interface LicenseVerifyResult {\n /** `true` when the submitted blob passes all verification checks. */\n valid: boolean;\n /** Slug of the organization the submitted license was issued to. Present when `valid` is `true`. */\n org_slug?: string;\n /** ISO 8601 expiry of the submitted license. Present when `valid` is `true`. */\n expires_at?: string;\n /** Machine-readable error code when `valid` is `false`. */\n error?: string;\n}\n","/**\n * Dual-shape input bridge for the v2.0.0 wire format change.\n *\n * The v2.0.0 wire format renamed the evaluate request fields:\n * OLD: { action, agent, context, api_key }\n * NEW: { action_type, actor_id, context }\n *\n * And the response fields:\n * OLD: { permitted, decision_id }\n * NEW: { decision, permit_token }\n *\n * TypeScript callers on the old v1.x request shape receive a\n * deprecation warning and are transparently upgraded to the new\n * shape. The response compat bridge normalises the legacy\n * `permitted` boolean to `decision === \"allow\"`.\n *\n * Both shims will be removed in v3.0.0.\n */\n\n/** Legacy v1.x evaluate request shape. */\nexport interface LegacyEvaluateRequest {\n action?: string;\n agent?: string;\n context?: Record<string, unknown>;\n}\n\n/** v2.0 evaluate request shape (canonical wire format). */\nexport interface V2EvaluateRequest {\n action_type: string;\n actor_id: string;\n context?: Record<string, unknown>;\n /** Populate `risk_envelope.factors` in the response (Phase C). */\n explain?: boolean;\n /** Deployment environment where the action executes (e.g. `\"production\"`). */\n environment?: string;\n /** Structured resource descriptor. Prefer over `resource_id` for new callers. */\n resource?: { type: string; id?: string; attributes?: Record<string, unknown> };\n /** Snapshot of the resource before the proposed action. Enables state-transition-aware policy evaluation. */\n current_state?: { description: string; attributes?: Record<string, unknown> };\n /** Desired resource state after the action. */\n proposed_state?: { description: string; attributes?: Record<string, unknown> };\n /** Execution surface binding (CI/CD adapter, DB driver, etc.). */\n execution_binding?: { kind: string; adapter_version?: string; resource_id?: string; enforcement_point?: string };\n}\n\n/**\n * Normalise an evaluate request from either the legacy v1.x shape\n * (`action` / `agent`) or the current v2.0 shape (`action_type` /\n * `actor_id`) into the canonical v2.0 wire format.\n *\n * When the legacy shape is detected a `console.warn` deprecation\n * notice is emitted once per call-site process lifetime. The shim\n * will be removed in v3.0.0.\n */\nexport function normalizeEvaluateRequest(\n input: LegacyEvaluateRequest | V2EvaluateRequest,\n): V2EvaluateRequest {\n // Detect legacy shape: has `action` or `agent` but NOT `action_type` /\n // `actor_id`. Both old fields are optional in the legacy interface so\n // we key on the absence of the new fields.\n if ('action' in input && !('action_type' in input)) {\n // eslint-disable-next-line no-console\n console.warn(\n '[atlasent] Deprecation: action/agent request shape is deprecated. ' +\n 'Use action_type/actor_id instead. This compatibility shim will be removed in v3.0.0.',\n );\n const legacy = input as LegacyEvaluateRequest;\n const normalized: V2EvaluateRequest = {\n action_type: legacy.action!,\n actor_id: legacy.agent!,\n };\n if (legacy.context !== undefined) normalized.context = legacy.context;\n const l = legacy as any;\n if (l.explain !== undefined) normalized.explain = l.explain;\n if (l.environment !== undefined) normalized.environment = l.environment;\n if (l.resource !== undefined) normalized.resource = l.resource;\n if (l.current_state !== undefined) normalized.current_state = l.current_state;\n if (l.proposed_state !== undefined) normalized.proposed_state = l.proposed_state;\n if (l.execution_binding !== undefined) normalized.execution_binding = l.execution_binding;\n return normalized;\n }\n return input as V2EvaluateRequest;\n}\n\n/**\n * Legacy v1.x evaluate response shape returned by older server\n * deployments.\n */\nexport interface LegacyEvaluateResponse {\n permitted?: boolean;\n decision_id?: string;\n reason?: string;\n audit_hash?: string;\n timestamp?: string;\n}\n\n/** v2.0 evaluate response shape (canonical wire format). */\nexport interface V2EvaluateResponse {\n decision: 'allow' | 'deny' | 'hold' | 'escalate';\n permit_token?: string;\n request_id?: string;\n expires_at?: string;\n denial?: { reason?: string; code?: string };\n}\n\n/**\n * Normalise an evaluate response from either the legacy v1.x shape\n * (`permitted` / `decision_id`) or the current v2.0 shape\n * (`decision` / `permit_token`) into the canonical v2.0 wire format.\n *\n * Used internally by the client to tolerate older atlasent-api\n * deployments without surfacing the impedance mismatch to callers.\n */\nexport function normalizeEvaluateResponse(\n wire: LegacyEvaluateResponse | V2EvaluateResponse,\n): V2EvaluateResponse {\n if (!('decision' in wire) && 'permitted' in wire) {\n // Legacy server — map `permitted` boolean → canonical `decision`.\n const legacy = wire as LegacyEvaluateResponse;\n const normalized: V2EvaluateResponse = {\n decision: legacy.permitted ? 'allow' : 'deny',\n };\n if (legacy.decision_id !== undefined) {\n normalized.permit_token = legacy.decision_id;\n }\n if (!legacy.permitted && legacy.reason) {\n normalized.denial = { reason: legacy.reason };\n }\n return normalized;\n }\n return wire as V2EvaluateResponse;\n}\n","/**\n * Retry-policy helpers for the AtlaSent TypeScript SDK.\n *\n * This module is **pure**: no I/O, no network, no globals beyond\n * `Math.random`. The intent is that {@link AtlaSentClient} (and any\n * caller wrapping `protect()` / `evaluate()`) can ask\n * {@link isRetryable} whether to retry a given {@link AtlaSentError},\n * then ask {@link computeBackoffMs} how long to sleep before the next\n * attempt.\n *\n * Wire-up into the client itself is intentionally deferred — see\n * ROADMAP item #7 (Post-GA). Sentry breadcrumb emission is also\n * deferred; both will land together once a transport-level retry\n * loop is wired into `client.ts`.\n *\n * Retry classification (matches the server's documented contract):\n * - `network` / `timeout` → retry (transient transport)\n * - `server_error` (HTTP 5xx) → retry\n * - `rate_limited` (HTTP 429) → retry, honour `retryAfterMs`\n * - `bad_response` → retry (likely truncated body)\n * - `invalid_api_key`/`forbidden`/`bad_request` → never retry\n *\n * Backoff: capped exponential with full jitter.\n * delay = min(maxDelayMs, baseDelayMs * 2^attempt) * random[0, 1)\n *\n * \"Full jitter\" is the AWS-recommended scheme — see\n * https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/.\n * It avoids thundering-herd retries from many SDK instances that hit\n * a 429 in the same window.\n *\n * Default schedule:\n * attempt 0 (1st retry): base 250 ms, jittered in [0, 250)\n * attempt 1 (2nd retry): base 500 ms, jittered in [0, 500)\n * Total attempts (including initial): 3\n */\n\nimport { AtlaSentError, type AtlaSentErrorCode } from \"./errors.js\";\n\n/**\n * Defaults for {@link RetryPolicy}.\n *\n * Exponential backoff with full jitter, base 250 ms, capped at 10 s:\n * attempt 0 (1st retry): base 250 ms, jittered in [0, 250)\n * attempt 1 (2nd retry): base 500 ms, jittered in [0, 500)\n * Total attempts (including initial): 3\n */\nexport const DEFAULT_RETRY_POLICY: Required<RetryPolicy> = {\n maxAttempts: 3,\n baseDelayMs: 250,\n maxDelayMs: 10_000,\n};\n\n/**\n * Caller-tunable retry policy. All fields optional; missing fields\n * fall back to {@link DEFAULT_RETRY_POLICY}.\n */\nexport interface RetryPolicy {\n /**\n * Total attempts including the first try. `1` disables retries\n * entirely. Must be `>= 1`; values below are clamped to `1`.\n */\n maxAttempts?: number;\n /**\n * Initial backoff for `attempt = 0`. Doubles per attempt up to\n * `maxDelayMs`. Must be `>= 0`.\n */\n baseDelayMs?: number;\n /**\n * Hard ceiling on the per-attempt sleep, applied **before** jitter.\n * The actual sleep is uniformly distributed in `[0, ceiling]`.\n */\n maxDelayMs?: number;\n}\n\n/**\n * Error codes the SDK considers transient. A `Set` (rather than a\n * `switch`) keeps callers free to extend the policy in the future\n * without forking this module.\n */\nconst RETRYABLE_CODES: ReadonlySet<AtlaSentErrorCode> = new Set([\n \"network\",\n \"timeout\",\n \"rate_limited\",\n \"server_error\",\n \"bad_response\",\n]);\n\n/**\n * Decide whether `err` is worth a retry. Anything that isn't an\n * {@link AtlaSentError} is treated as non-retryable — the SDK's\n * transport layer always wraps fetch failures in `AtlaSentError`,\n * so a non-AtlaSent throwable is by definition a programmer bug\n * (a bad input, an assertion in user code) and should propagate.\n */\nexport function isRetryable(err: unknown): boolean {\n if (!(err instanceof AtlaSentError)) return false;\n if (err.code === undefined) return false;\n return RETRYABLE_CODES.has(err.code);\n}\n\n/**\n * Compute how long to sleep before retry attempt `attempt`\n * (zero-indexed: `attempt = 0` is the first retry, i.e. the second\n * total request). Uses capped exponential backoff with full jitter.\n *\n * When `err` carries a `retryAfterMs` (server-provided `Retry-After`\n * header), the result is `max(retryAfterMs, jitteredDelay)` — the\n * server's hint is treated as a floor so we never retry sooner than\n * the server asked.\n *\n * @param attempt Zero-indexed retry attempt (0, 1, 2, ...). For\n * the default policy this produces delays drawn from\n * [0, 2 000), [0, 4 000), [0, 8 000), [0, 16 000).\n * @param policy Optional override of {@link DEFAULT_RETRY_POLICY}.\n * @param err Optional error whose `retryAfterMs` is honoured.\n * @param random Injectable RNG, defaults to `Math.random`. Must\n * return values in `[0, 1)` to preserve the\n * distribution.\n */\nexport function computeBackoffMs(\n attempt: number,\n policy: RetryPolicy = {},\n err?: unknown,\n random: () => number = Math.random,\n): number {\n const merged = mergePolicy(policy);\n const safeAttempt = Math.max(0, Math.floor(attempt));\n // 2^attempt grows exponentially; cap before multiplying to keep the\n // intermediate value bounded for very large `attempt`.\n const exp = Math.min(safeAttempt, 30);\n const ceiling = Math.min(merged.maxDelayMs, merged.baseDelayMs * 2 ** exp);\n const jittered = Math.floor(ceiling * clampUnit(random()));\n\n const retryAfterMs =\n err instanceof AtlaSentError && typeof err.retryAfterMs === \"number\"\n ? Math.max(0, err.retryAfterMs)\n : 0;\n\n return Math.max(retryAfterMs, jittered);\n}\n\n/**\n * Returns `true` when `attempt` (zero-indexed) is below the policy's\n * `maxAttempts - 1` ceiling — i.e. when there is still budget for at\n * least one more try after this one. Convenience wrapper so retry\n * loops read top-to-bottom:\n *\n * ```ts\n * for (let attempt = 0; ; attempt++) {\n * try { return await op(); }\n * catch (err) {\n * if (!isRetryable(err) || !hasAttemptsLeft(attempt, policy)) throw err;\n * await sleep(computeBackoffMs(attempt, policy, err));\n * }\n * }\n * ```\n */\nexport function hasAttemptsLeft(\n attempt: number,\n policy: RetryPolicy = {},\n): boolean {\n const merged = mergePolicy(policy);\n return attempt + 1 < merged.maxAttempts;\n}\n\n/**\n * Merge a partial policy with {@link DEFAULT_RETRY_POLICY} and clamp\n * each field into a sensible range. Exported for tests and for\n * callers that want to log the resolved policy.\n */\nexport function mergePolicy(policy: RetryPolicy): Required<RetryPolicy> {\n const maxAttempts = Math.max(\n 1,\n Math.floor(policy.maxAttempts ?? DEFAULT_RETRY_POLICY.maxAttempts),\n );\n const baseDelayMs = Math.max(\n 0,\n policy.baseDelayMs ?? DEFAULT_RETRY_POLICY.baseDelayMs,\n );\n const maxDelayMs = Math.max(\n baseDelayMs,\n policy.maxDelayMs ?? DEFAULT_RETRY_POLICY.maxDelayMs,\n );\n return { maxAttempts, baseDelayMs, maxDelayMs };\n}\n\n/**\n * Clamp `n` into `[0, 1)`. Defends against a misbehaving injected\n * RNG returning `NaN`, `Infinity`, or a negative number.\n */\nfunction clampUnit(n: number): number {\n if (!Number.isFinite(n)) return 0;\n if (n < 0) return 0;\n if (n >= 1) return 0.999_999_999;\n return n;\n}\n","/**\n * SCIM 2.0 provisioning client — user and group lifecycle management.\n *\n * Wire surface: /scim/v2/* endpoints in atlasent-api (RFC 7643/7644).\n *\n * Usage:\n *\n * ```ts\n * import { AtlaSentClient } from \"@atlasent/sdk\";\n *\n * const client = new AtlaSentClient({ apiKey: \"...\" });\n *\n * const page = await client.scim.users.list({ orgId: \"org_abc\" });\n * for (const user of page.Resources) {\n * console.log(user.userName);\n * }\n *\n * const newUser = await client.scim.users.create(\"org_abc\", {\n * userName: \"alice@example.com\",\n * displayName: \"Alice Example\",\n * active: true,\n * emails: [{ value: \"alice@example.com\", primary: true }],\n * });\n * ```\n */\n\n// ─── SCIM schema URNs ─────────────────────────────────────────────────────────\n\nexport const SCIM_USER_SCHEMA =\n \"urn:ietf:params:scim:schemas:core:2.0:User\" as const;\nexport const SCIM_GROUP_SCHEMA =\n \"urn:ietf:params:scim:schemas:core:2.0:Group\" as const;\nexport const SCIM_PATCH_OP_SCHEMA =\n \"urn:ietf:params:scim:api:messages:2.0:PatchOp\" as const;\n\n// ─── SCIM resource types ──────────────────────────────────────────────────────\n\n/** SCIM email value. */\nexport interface ScimEmail {\n value: string;\n type?: string;\n primary?: boolean;\n}\n\n/** SCIM name component. */\nexport interface ScimName {\n formatted?: string;\n givenName?: string;\n familyName?: string;\n}\n\n/** Group reference embedded on a user. */\nexport interface ScimGroupRef {\n value: string;\n display?: string;\n}\n\n/** SCIM metadata block. */\nexport interface ScimMeta {\n resourceType?: string;\n created?: string;\n lastModified?: string;\n location?: string;\n version?: string;\n}\n\n/** SCIM 2.0 User resource. */\nexport interface ScimUser {\n schemas?: string[];\n id?: string;\n userName: string;\n displayName?: string;\n active?: boolean;\n emails?: ScimEmail[];\n name?: ScimName;\n groups?: ScimGroupRef[];\n meta?: ScimMeta;\n [k: string]: unknown;\n}\n\n/** Create payload for a new SCIM user. `schemas` is injected automatically. */\nexport type ScimUserCreate = Omit<ScimUser, \"id\" | \"meta\">;\n\n/** Update payload for an existing SCIM user. */\nexport type ScimUserUpdate = ScimUser;\n\n/** RFC 7644 PatchOp operation. */\nexport interface ScimPatchOp {\n op: \"add\" | \"remove\" | \"replace\";\n path?: string;\n value?: unknown;\n}\n\n/** SCIM 2.0 ListResponse envelope (generic). */\nexport interface ScimListResponse<T = unknown> {\n schemas: string[];\n totalResults: number;\n startIndex: number;\n itemsPerPage: number;\n Resources: T[];\n}\n\n/** Query parameters for SCIM list operations. */\nexport interface ScimListParams {\n /** Organisation ID (required). */\n orgId: string;\n /** SCIM filter expression, e.g. `userName eq \"alice@example.com\"`. */\n filter?: string;\n /** 1-based pagination offset. Defaults to 1 on the server. */\n startIndex?: number;\n /** Maximum results per page. Defaults to 100 on the server. */\n count?: number;\n}\n\n// ─── Sub-client interfaces ───────────────────────────────────────────────────\n\n/** Sub-client for /scim/v2/{orgId}/Users operations. */\nexport interface ScimUsersSubClient {\n /**\n * `GET /scim/v2/{orgId}/Users` — list provisioned users.\n *\n * ```ts\n * const page = await client.scim.users.list({ orgId: \"org_abc\" });\n * ```\n */\n list(params: ScimListParams): Promise<ScimListResponse<ScimUser>>;\n\n /**\n * `POST /scim/v2/{orgId}/Users` — provision a new user.\n *\n * ```ts\n * const user = await client.scim.users.create(\"org_abc\", {\n * userName: \"alice@example.com\",\n * active: true,\n * emails: [{ value: \"alice@example.com\", primary: true }],\n * });\n * ```\n */\n create(orgId: string, user: ScimUserCreate): Promise<ScimUser>;\n\n /**\n * `PUT /scim/v2/{orgId}/Users/{id}` — full replacement.\n *\n * ```ts\n * const updated = await client.scim.users.update(\"org_abc\", \"usr_123\", user);\n * ```\n */\n update(\n orgId: string,\n id: string,\n user: ScimUserUpdate,\n ): Promise<ScimUser>;\n\n /**\n * `DELETE /scim/v2/{orgId}/Users/{id}` — deprovision a user.\n *\n * ```ts\n * await client.scim.users.delete(\"org_abc\", \"usr_123\");\n * ```\n */\n delete(orgId: string, id: string): Promise<void>;\n}\n\n/** Sub-client for /scim/v2/{orgId}/Groups operations. */\nexport interface ScimGroupsSubClient {\n /** `GET /scim/v2/{orgId}/Groups` — list groups. */\n list(params: ScimListParams): Promise<ScimListResponse<Record<string, unknown>>>;\n /** `POST /scim/v2/{orgId}/Groups` — create a group. */\n create(orgId: string, group: Record<string, unknown>): Promise<Record<string, unknown>>;\n /** `DELETE /scim/v2/{orgId}/Groups/{id}` — delete a group. */\n delete(orgId: string, id: string): Promise<void>;\n}\n\n/** Top-level SCIM sub-client exposed as `client.scim`. */\nexport interface ScimSubClient {\n users: ScimUsersSubClient;\n groups: ScimGroupsSubClient;\n}\n\n// ─── Factory ─────────────────────────────────────────────────────────────────\n\ntype PostFn = <T>(\n path: string,\n body: unknown,\n query?: URLSearchParams,\n) => Promise<{ body: T }>;\n\ntype GetFn = <T>(\n path: string,\n query?: URLSearchParams,\n) => Promise<{ body: T }>;\n\ntype PutFn = <T>(\n path: string,\n body: unknown,\n) => Promise<{ body: T }>;\n\ntype DeleteFn = (path: string) => Promise<void>;\n\nfunction scimUsersPath(orgId: string): string {\n return `/scim/v2/${encodeURIComponent(orgId)}/Users`;\n}\n\nfunction scimGroupsPath(orgId: string): string {\n return `/scim/v2/${encodeURIComponent(orgId)}/Groups`;\n}\n\nfunction buildScimQuery(\n filter?: string,\n startIndex?: number,\n count?: number,\n): URLSearchParams | undefined {\n const params = new URLSearchParams();\n if (filter !== undefined) params.set(\"filter\", filter);\n if (startIndex !== undefined) params.set(\"startIndex\", String(startIndex));\n if (count !== undefined) params.set(\"count\", String(count));\n return params.size > 0 ? params : undefined;\n}\n\n/**\n * Factory that returns the SCIM sub-client bound to a host client.\n * Called internally by AtlaSentClient; not part of the public constructor API.\n */\nexport function makeScimClient(\n postFn: PostFn,\n getFn: GetFn,\n putFn: PutFn,\n deleteFn: DeleteFn,\n): ScimSubClient {\n const users: ScimUsersSubClient = {\n async list(params: ScimListParams): Promise<ScimListResponse<ScimUser>> {\n const qs = buildScimQuery(\n params.filter,\n params.startIndex,\n params.count,\n );\n const { body } = await getFn<ScimListResponse<ScimUser>>(\n scimUsersPath(params.orgId),\n qs,\n );\n return body;\n },\n\n async create(orgId: string, user: ScimUserCreate): Promise<ScimUser> {\n const payload = user.schemas\n ? user\n : { ...user, schemas: [SCIM_USER_SCHEMA] };\n const { body } = await postFn<ScimUser>(scimUsersPath(orgId), payload);\n return body;\n },\n\n async update(\n orgId: string,\n id: string,\n user: ScimUserUpdate,\n ): Promise<ScimUser> {\n const payload = user.schemas\n ? user\n : { ...user, schemas: [SCIM_USER_SCHEMA] };\n const { body } = await putFn<ScimUser>(\n `${scimUsersPath(orgId)}/${encodeURIComponent(id)}`,\n payload,\n );\n return body;\n },\n\n async delete(orgId: string, id: string): Promise<void> {\n return deleteFn(\n `${scimUsersPath(orgId)}/${encodeURIComponent(id)}`,\n );\n },\n };\n\n const groups: ScimGroupsSubClient = {\n async list(\n params: ScimListParams,\n ): Promise<ScimListResponse<Record<string, unknown>>> {\n const qs = buildScimQuery(\n params.filter,\n params.startIndex,\n params.count,\n );\n const { body } = await getFn<ScimListResponse<Record<string, unknown>>>(\n scimGroupsPath(params.orgId),\n qs,\n );\n return body;\n },\n\n async create(\n orgId: string,\n group: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n const payload =\n group[\"schemas\"] ? group : { ...group, schemas: [SCIM_GROUP_SCHEMA] };\n const { body } = await postFn<Record<string, unknown>>(\n scimGroupsPath(orgId),\n payload,\n );\n return body;\n },\n\n async delete(orgId: string, id: string): Promise<void> {\n return deleteFn(\n `${scimGroupsPath(orgId)}/${encodeURIComponent(id)}`,\n );\n },\n };\n\n return { users, groups };\n}\n","/**\n * Evidence Bundle helpers — create, retrieve, and download compliance\n * evidence bundles for incident investigations and audit export.\n *\n * Wire surface: POST/GET /v1/evidence-bundles\n *\n * Usage:\n *\n * ```ts\n * import { AtlaSentClient } from \"@atlasent/sdk\";\n *\n * const client = new AtlaSentClient({ apiKey: \"...\" });\n *\n * // Create\n * const bundle = await client.evidenceBundles.create({\n * incidentId: \"inc_abc123\",\n * includeOverrides: true,\n * });\n *\n * // Get\n * const bundle2 = await client.evidenceBundles.get(bundle.bundleId);\n *\n * // Download as JSON or PDF\n * const pdf = await client.evidenceBundles.download(bundle.bundleId, \"pdf\");\n * ```\n */\n\n/** Status of an evidence bundle. */\nexport type EvidenceBundleStatus =\n | \"pending\"\n | \"building\"\n | \"ready\"\n | \"failed\"\n | \"expired\";\n\n/** An evidence bundle record returned by the API. */\nexport interface EvidenceBundle {\n /** Server-assigned bundle identifier. */\n bundleId: string;\n /** Organisation the bundle belongs to. */\n orgId: string;\n /** Incident or investigation ID this bundle was created for. */\n incidentId: string;\n /** Current bundle status. */\n status: EvidenceBundleStatus;\n /** Permit IDs included in the bundle (empty = all permits for the incident). */\n includedPermits: string[];\n /** Whether override events are included. */\n includeOverrides: boolean;\n /** Format used when the bundle was created. */\n format: \"json\" | \"pdf\";\n /** ISO 8601 creation time. */\n createdAt: string;\n /** ISO 8601 expiration time. */\n expiresAt: string;\n /** Pre-signed download URL (populated when status is `ready`). */\n downloadUrl?: string;\n /** Free-form metadata supplied at creation. */\n metadata?: Record<string, unknown>;\n}\n\n/** Input to {@link EvidenceBundlesMixin.create}. */\nexport interface EvidenceBundleCreateParams {\n /** Incident or investigation ID for this bundle. */\n incidentId: string;\n /**\n * Optional list of specific permit IDs to include.\n * When omitted, all permits associated with the incident are included.\n */\n includedPermits?: string[];\n /**\n * When `true`, override events are embedded in the bundle.\n * Defaults to `false`.\n */\n includeOverrides?: boolean;\n}\n\n/** Query parameters for {@link EvidenceBundleSubClient.list}. */\nexport interface EvidenceBundleListParams {\n /** Filter bundles to a specific execution ID. */\n executionId?: string;\n /** Maximum number of bundles to return. */\n limit?: number;\n /** Opaque cursor from a previous list response for pagination. */\n cursor?: string;\n}\n\n/** Paginated response from {@link EvidenceBundleSubClient.list}. */\nexport interface EvidenceBundleListPage {\n /** Evidence bundles for this page. */\n bundles: EvidenceBundle[];\n /** Pass as `cursor` to `list()` to fetch the next page. `null` means no more pages. */\n nextCursor: string | null;\n}\n\n/** Wire shape for the list response. */\ninterface EvidenceBundleListWire {\n bundles: EvidenceBundleWire[];\n next_cursor?: string | null;\n}\n\n/** Wire shape returned by POST /v1/evidence-bundles. */\ninterface EvidenceBundleWire {\n bundle_id: string;\n org_id: string;\n incident_id: string;\n status: EvidenceBundleStatus;\n included_permits: string[];\n include_overrides: boolean;\n format: \"json\" | \"pdf\";\n created_at: string;\n expires_at: string;\n download_url?: string;\n metadata?: Record<string, unknown>;\n}\n\nfunction wireToBundle(w: EvidenceBundleWire): EvidenceBundle {\n return {\n bundleId: w.bundle_id,\n orgId: w.org_id,\n incidentId: w.incident_id,\n status: w.status,\n includedPermits: w.included_permits ?? [],\n includeOverrides: w.include_overrides ?? false,\n format: w.format,\n createdAt: w.created_at,\n expiresAt: w.expires_at,\n ...(w.download_url !== undefined ? { downloadUrl: w.download_url } : {}),\n ...(w.metadata !== undefined ? { metadata: w.metadata } : {}),\n };\n}\n\n/**\n * Sub-client for evidence bundle operations.\n * Accessed as `client.evidenceBundles` on {@link AtlaSentClient}.\n */\nexport interface EvidenceBundleSubClient {\n /**\n * List evidence bundles for the org, with optional filters and pagination.\n *\n * ```ts\n * const page = await client.evidenceBundles.list({ limit: 20 });\n * for (const bundle of page.bundles) { ... }\n * if (page.nextCursor) {\n * const next = await client.evidenceBundles.list({ cursor: page.nextCursor });\n * }\n * ```\n */\n list(params?: EvidenceBundleListParams): Promise<EvidenceBundleListPage>;\n\n /**\n * Create a new evidence bundle.\n *\n * ```ts\n * const bundle = await client.evidenceBundles.create({\n * incidentId: \"inc_abc123\",\n * includeOverrides: true,\n * });\n * ```\n */\n create(params: EvidenceBundleCreateParams): Promise<EvidenceBundle>;\n\n /**\n * Retrieve an evidence bundle by ID.\n *\n * ```ts\n * const bundle = await client.evidenceBundles.get(\"bnd_xyz\");\n * ```\n */\n get(bundleId: string): Promise<EvidenceBundle>;\n\n /**\n * Download the evidence bundle contents.\n *\n * @param bundleId - The bundle to download.\n * @param format - `\"json\"` (default) or `\"pdf\"`.\n * @returns Raw bytes of the downloaded file.\n *\n * ```ts\n * const pdf = await client.evidenceBundles.download(\"bnd_xyz\", \"pdf\");\n * await fs.writeFile(\"bundle.pdf\", pdf);\n * ```\n */\n download(bundleId: string, format?: \"json\" | \"pdf\"): Promise<Buffer>;\n}\n\n/**\n * Factory that returns the evidence-bundles sub-client bound to a host\n * client. Called internally by AtlaSentClient; not part of the public\n * constructor API.\n */\nexport function makeEvidenceBundleClient(\n postFn: <T>(path: string, body: unknown) => Promise<{ body: T }>,\n getFn: <T>(path: string, query?: URLSearchParams) => Promise<{ body: T }>,\n getRawFn: (path: string) => Promise<ArrayBuffer>,\n): EvidenceBundleSubClient {\n return {\n async list(params: EvidenceBundleListParams = {}): Promise<EvidenceBundleListPage> {\n const qs = new URLSearchParams();\n if (params.executionId !== undefined) qs.set(\"execution_id\", params.executionId);\n if (params.limit !== undefined) qs.set(\"limit\", String(params.limit));\n if (params.cursor !== undefined) qs.set(\"cursor\", params.cursor);\n const { body } = await getFn<EvidenceBundleListWire>(\"/v1/evidence-bundles\", qs.size > 0 ? qs : undefined);\n return {\n bundles: (body.bundles ?? []).map(wireToBundle),\n nextCursor: body.next_cursor ?? null,\n };\n },\n\n async create(params: EvidenceBundleCreateParams): Promise<EvidenceBundle> {\n const payload: Record<string, unknown> = {\n incident_id: params.incidentId,\n };\n if (params.includedPermits !== undefined) {\n payload[\"included_permits\"] = params.includedPermits;\n }\n if (params.includeOverrides !== undefined) {\n payload[\"include_overrides\"] = params.includeOverrides;\n }\n const { body } = await postFn<EvidenceBundleWire>(\n \"/v1/evidence-bundles\",\n payload,\n );\n return wireToBundle(body);\n },\n\n async get(bundleId: string): Promise<EvidenceBundle> {\n const { body } = await getFn<EvidenceBundleWire>(\n `/v1/evidence-bundles/${encodeURIComponent(bundleId)}`,\n );\n return wireToBundle(body);\n },\n\n async download(\n bundleId: string,\n format: \"json\" | \"pdf\" = \"json\",\n ): Promise<Buffer> {\n const qs = new URLSearchParams({ format });\n const raw = await getRawFn(\n `/v1/evidence-bundles/${encodeURIComponent(bundleId)}/download?${qs}`,\n );\n return Buffer.from(raw);\n },\n };\n}\n","/**\n * Auth helpers — token management and multi-IdP token refresh.\n *\n * Wire surface: /v1/auth/* endpoints in atlasent-api.\n *\n * Usage:\n *\n * ```ts\n * import { AtlaSentClient } from \"@atlasent/sdk\";\n *\n * const client = new AtlaSentClient({ apiKey: \"...\" });\n *\n * // Refresh using the default IdP\n * const tokens = await client.auth.refresh(currentRefreshToken);\n *\n * // Refresh using a specific IdP (multi-IdP orgs)\n * const tokens = await client.auth.refreshWithIdp(\"idp_okta_prod\", currentRefreshToken);\n *\n * // List IdP connections\n * const connections = await client.auth.listIdpConnections();\n * ```\n */\n\n/** A token response from the auth endpoints. */\nexport interface TokenResponse {\n accessToken: string;\n refreshToken: string;\n tokenType: string;\n expiresIn: number;\n scope?: string;\n /** IdP that issued the token (populated on multi-IdP responses). */\n idpId?: string;\n}\n\n/** Wire shape for token responses. */\ninterface TokenResponseWire {\n access_token: string;\n refresh_token: string;\n token_type: string;\n expires_in: number;\n scope?: string;\n idp_id?: string;\n}\n\nfunction wireToTokenResponse(w: TokenResponseWire): TokenResponse {\n return {\n accessToken: w.access_token,\n refreshToken: w.refresh_token,\n tokenType: w.token_type,\n expiresIn: w.expires_in,\n ...(w.scope !== undefined ? { scope: w.scope } : {}),\n ...(w.idp_id !== undefined ? { idpId: w.idp_id } : {}),\n };\n}\n\n/** An IdP connection record. */\nexport interface IdpConnection {\n id: string;\n name: string;\n provider: string;\n enabled: boolean;\n isDefault: boolean;\n domains?: string[];\n createdAt: string;\n}\n\n/** Wire shape for an IdP connection. */\ninterface IdpConnectionWire {\n id: string;\n name: string;\n provider: string;\n enabled: boolean;\n default: boolean;\n domains?: string[];\n created_at: string;\n}\n\nfunction wireToIdpConnection(w: IdpConnectionWire): IdpConnection {\n return {\n id: w.id,\n name: w.name,\n provider: w.provider,\n enabled: w.enabled,\n isDefault: w.default,\n ...(w.domains !== undefined ? { domains: w.domains } : {}),\n createdAt: w.created_at,\n };\n}\n\n/** Sub-client for token management and multi-IdP auth. */\nexport interface AuthSubClient {\n /**\n * Refresh an access token using the default IdP connection.\n *\n * ```ts\n * const tokens = await client.auth.refresh(currentRefreshToken);\n * ```\n */\n refresh(refreshToken: string): Promise<TokenResponse>;\n\n /**\n * Refresh an access token against a specific IdP connection.\n *\n * Use this in multi-IdP organisations where the caller needs to\n * specify which SSO connection to use for the token exchange.\n *\n * `idpId` corresponds to the connection ID returned by\n * `listIdpConnections()` (e.g. `\"idp_okta_prod\"`, `\"idp_entra\"`).\n *\n * ```ts\n * const tokens = await client.auth.refreshWithIdp(\n * \"idp_okta_prod\",\n * currentRefreshToken,\n * );\n * ```\n */\n refreshWithIdp(idpId: string, refreshToken: string): Promise<TokenResponse>;\n\n /**\n * List IdP connections available for this organisation.\n *\n * ```ts\n * const connections = await client.auth.listIdpConnections();\n * const primary = connections.find(c => c.isDefault);\n * ```\n */\n listIdpConnections(): Promise<IdpConnection[]>;\n}\n\n/**\n * Factory that returns the auth sub-client bound to a host client.\n * Called internally by AtlaSentClient; not part of the public constructor API.\n */\nexport function makeAuthClient(\n postFn: <T>(path: string, body: unknown) => Promise<{ body: T }>,\n getFn: <T>(path: string) => Promise<{ body: T }>,\n): AuthSubClient {\n return {\n async refresh(refreshToken: string): Promise<TokenResponse> {\n const { body } = await postFn<TokenResponseWire>(\n \"/v1/auth/token/refresh\",\n { refresh_token: refreshToken, grant_type: \"refresh_token\" },\n );\n return wireToTokenResponse(body);\n },\n\n async refreshWithIdp(\n idpId: string,\n refreshToken: string,\n ): Promise<TokenResponse> {\n const path = `/v1/auth/idp/${encodeURIComponent(idpId)}/token/refresh`;\n const { body } = await postFn<TokenResponseWire>(path, {\n refresh_token: refreshToken,\n grant_type: \"refresh_token\",\n idp_id: idpId,\n });\n return wireToTokenResponse(body);\n },\n\n async listIdpConnections(): Promise<IdpConnection[]> {\n const { body } = await getFn<{ connections: IdpConnectionWire[] }>(\n \"/v1/auth/idp-connections\",\n );\n return (body.connections ?? []).map(wireToIdpConnection);\n },\n };\n}\n","/**\n * SSO administration — connections, JIT rules, events, enforcement state\n * machine, and the `client.sso` sub-client.\n *\n * Usage:\n *\n * ```ts\n * import { AtlaSentClient } from \"@atlasent/sdk\";\n *\n * const client = new AtlaSentClient({ apiKey: \"...\" });\n *\n * const { connections } = await client.sso.listConnections();\n * const status = await client.sso.getStatus();\n * await client.sso.enforce(\"enable\");\n * ```\n */\n\n// ── Connections ───────────────────────────────────────────────────────────────\n\n/** An SSO connection record (SAML 2.0 or OIDC). */\nexport interface SsoConnection {\n id: string;\n organizationId: string;\n name: string;\n protocol: \"saml\" | \"oidc\";\n idpEntityId: string;\n metadataUrl: string | null;\n metadataXml: string | null;\n emailDomain: string | null;\n enforceForDomain: boolean;\n isActive: boolean;\n supabaseProviderId: string | null;\n createdBy: string;\n createdAt: string;\n updatedAt: string;\n}\n\n/** Wire (snake_case) shape for SSO connection responses. */\nexport interface SsoConnectionWire {\n id: string;\n organization_id: string;\n name: string;\n protocol: \"saml\" | \"oidc\";\n idp_entity_id: string;\n metadata_url: string | null;\n metadata_xml: string | null;\n email_domain: string | null;\n enforce_for_domain: boolean;\n is_active: boolean;\n supabase_provider_id: string | null;\n created_by: string;\n created_at: string;\n updated_at: string;\n}\n\nexport function wireToSsoConnection(w: SsoConnectionWire): SsoConnection {\n return {\n id: w.id,\n organizationId: w.organization_id,\n name: w.name,\n protocol: w.protocol,\n idpEntityId: w.idp_entity_id,\n metadataUrl: w.metadata_url,\n metadataXml: w.metadata_xml,\n emailDomain: w.email_domain,\n enforceForDomain: w.enforce_for_domain,\n isActive: w.is_active,\n supabaseProviderId: w.supabase_provider_id,\n createdBy: w.created_by,\n createdAt: w.created_at,\n updatedAt: w.updated_at,\n };\n}\n\n// ── JIT provisioning rules ───────────────────────────────────────────────────\n\nexport type SsoRole = \"owner\" | \"admin\" | \"approver\" | \"member\" | \"viewer\";\n\n/** A JIT provisioning rule that maps an IdP claim to an org role. */\nexport interface SsoJitRule {\n id: string;\n connectionId: string;\n organizationId: string;\n claimAttribute: string;\n claimValue: string;\n grantedRole: SsoRole;\n precedence: number;\n isActive: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\n/** Wire (snake_case) shape for JIT rule responses. */\nexport interface SsoJitRuleWire {\n id: string;\n connection_id: string;\n organization_id: string;\n claim_attribute: string;\n claim_value: string;\n granted_role: SsoRole;\n precedence: number;\n is_active: boolean;\n created_at: string;\n updated_at: string;\n}\n\nexport function wireToSsoJitRule(w: SsoJitRuleWire): SsoJitRule {\n return {\n id: w.id,\n connectionId: w.connection_id,\n organizationId: w.organization_id,\n claimAttribute: w.claim_attribute,\n claimValue: w.claim_value,\n grantedRole: w.granted_role,\n precedence: w.precedence,\n isActive: w.is_active,\n createdAt: w.created_at,\n updatedAt: w.updated_at,\n };\n}\n\n// ── Events ───────────────────────────────────────────────────────────────────\n\n/**\n * An SSO lifecycle event — login, session, config change, break-glass, or\n * JIT provisioning.\n */\nexport interface SsoEvent {\n id: string;\n organizationId: string;\n connectionId: string | null;\n eventType: string;\n actorEmail: string | null;\n payload: Record<string, unknown>;\n occurredAt: string;\n}\n\n/** Wire (snake_case) shape for SSO event responses. */\nexport interface SsoEventWire {\n id: string;\n organization_id: string;\n connection_id: string | null;\n event_type: string;\n actor_email: string | null;\n payload: Record<string, unknown>;\n occurred_at: string;\n}\n\nexport function wireToSsoEvent(w: SsoEventWire): SsoEvent {\n return {\n id: w.id,\n organizationId: w.organization_id,\n connectionId: w.connection_id,\n eventType: w.event_type,\n actorEmail: w.actor_email,\n payload: w.payload,\n occurredAt: w.occurred_at,\n };\n}\n\n// ── Enforcement state machine ─────────────────────────────────────────────────\n\n/** Action to pass to `POST /v1/sso/enforce`. */\nexport type SsoEnforceAction = \"enable\" | \"enforce\";\n\n/**\n * Four-boolean readiness checklist returned by `GET /v1/sso/status`.\n * All four must be `true` before enforcement is safe to activate.\n */\nexport interface SsoReadiness {\n /** At least one SSO connection row exists for the org. */\n connectionConfigured: boolean;\n /** At least one connection has been activated (registered with the IdP). */\n connectionTested: boolean;\n /** Break-glass access has been configured (non-default settings). */\n breakGlassSet: boolean;\n /** No unreviewed active service API keys exist. */\n serviceApiKeysReviewed: boolean;\n}\n\n/** Wire (snake_case) shape for the readiness response. */\nexport interface SsoReadinessWire {\n connection_configured: boolean;\n connection_tested: boolean;\n break_glass_set: boolean;\n service_api_keys_reviewed: boolean;\n}\n\nexport function wireToSsoReadiness(w: SsoReadinessWire): SsoReadiness {\n return {\n connectionConfigured: w.connection_configured,\n connectionTested: w.connection_tested,\n breakGlassSet: w.break_glass_set,\n serviceApiKeysReviewed: w.service_api_keys_reviewed,\n };\n}\n\n// ── Sub-client ────────────────────────────────────────────────────────────────\n\n/** Input for creating a JIT provisioning rule. */\nexport interface SsoJitRuleInput {\n connectionId: string;\n claimAttribute: string;\n claimValue: string;\n grantedRole: SsoRole;\n precedence?: number;\n}\n\n/** Patchable fields for an existing JIT rule. */\nexport interface SsoJitRulePatch {\n claimAttribute?: string;\n claimValue?: string;\n grantedRole?: SsoRole;\n precedence?: number;\n isActive?: boolean;\n}\n\n/** Input for creating or updating an SSO connection. */\nexport interface SsoConnectionInput {\n name: string;\n protocol: \"saml\" | \"oidc\";\n idpEntityId: string;\n metadataUrl?: string | null;\n metadataXml?: string | null;\n emailDomain?: string | null;\n enforceForDomain?: boolean;\n}\n\n/** Result of `POST /v1/sso/enforce`. */\nexport interface SsoEnforceResult {\n ok: boolean;\n action: SsoEnforceAction;\n enforceSso: boolean;\n enforceSsoAt: string | null;\n}\n\ninterface SsoEnforceResultWire {\n ok: boolean;\n action: SsoEnforceAction;\n enforce_sso: boolean;\n enforce_sso_at: string | null;\n}\n\n/**\n * Sub-client for SSO administration.\n * Accessed as `client.sso` on {@link AtlaSentClient}.\n */\nexport interface SsoSubClient {\n /** List all SSO connections for the org. */\n listConnections(): Promise<{ connections: SsoConnection[] }>;\n\n /** Get a single SSO connection by ID. */\n getConnection(id: string): Promise<SsoConnection>;\n\n /** Create a new SSO connection. */\n createConnection(input: SsoConnectionInput): Promise<SsoConnection>;\n\n /** Update an existing SSO connection. */\n updateConnection(id: string, input: Partial<SsoConnectionInput>): Promise<SsoConnection>;\n\n /** Delete an SSO connection. */\n deleteConnection(id: string): Promise<void>;\n\n /** Activate (register) a connection with the IdP. */\n activateConnection(id: string): Promise<{ ok: boolean; supabaseProviderId: string | null }>;\n\n /**\n * Advance the SSO enforcement state machine.\n * `\"enable\"` → SSO enabled, not yet enforced.\n * `\"enforce\"` → SSO mandatory for all members (requires readiness checklist to pass).\n */\n enforce(action: SsoEnforceAction): Promise<SsoEnforceResult>;\n\n /** Get the four-boolean enforcement readiness checklist. */\n getStatus(): Promise<SsoReadiness>;\n\n // ── JIT provisioning rules ───────────────────────────────────────────────\n\n /** List JIT provisioning rules, optionally filtered to a single connection. */\n listJitRules(connectionId?: string): Promise<{ rules: SsoJitRule[] }>;\n\n /** Create a new JIT provisioning rule. */\n createJitRule(input: SsoJitRuleInput): Promise<SsoJitRule>;\n\n /** Update fields on an existing JIT rule. */\n patchJitRule(id: string, patch: SsoJitRulePatch): Promise<SsoJitRule>;\n\n /** Delete a JIT provisioning rule. */\n deleteJitRule(id: string): Promise<void>;\n}\n\nfunction ssoConnectionInputToWire(input: SsoConnectionInput | Partial<SsoConnectionInput>): Record<string, unknown> {\n const w: Record<string, unknown> = {};\n if (input.name !== undefined) w[\"name\"] = input.name;\n if (input.protocol !== undefined) w[\"protocol\"] = input.protocol;\n if (input.idpEntityId !== undefined) w[\"idp_entity_id\"] = input.idpEntityId;\n if (input.metadataUrl !== undefined) w[\"metadata_url\"] = input.metadataUrl;\n if (input.metadataXml !== undefined) w[\"metadata_xml\"] = input.metadataXml;\n if (input.emailDomain !== undefined) w[\"email_domain\"] = input.emailDomain;\n if (input.enforceForDomain !== undefined) w[\"enforce_for_domain\"] = input.enforceForDomain;\n return w;\n}\n\n/**\n * Factory that returns the SSO sub-client bound to a host client's transport\n * helpers. Called internally by AtlaSentClient; not part of the public API.\n */\nexport function makeSsoClient(\n getFn: <T>(path: string, query?: URLSearchParams) => Promise<{ body: T }>,\n postFn: <T>(path: string, body: unknown) => Promise<{ body: T }>,\n patchFn: <T>(path: string, body: unknown) => Promise<{ body: T }>,\n deleteFn: (path: string) => Promise<void>,\n): SsoSubClient {\n return {\n async listConnections() {\n const { body } = await getFn<{ connections: SsoConnectionWire[] }>(\"/v1/sso/connections\");\n return { connections: (body.connections ?? []).map(wireToSsoConnection) };\n },\n\n async getConnection(id: string) {\n const { body } = await getFn<SsoConnectionWire>(`/v1/sso/connections/${encodeURIComponent(id)}`);\n return wireToSsoConnection(body);\n },\n\n async createConnection(input: SsoConnectionInput) {\n const { body } = await postFn<SsoConnectionWire>(\"/v1/sso/connections\", ssoConnectionInputToWire(input));\n return wireToSsoConnection(body);\n },\n\n async updateConnection(id: string, input: Partial<SsoConnectionInput>) {\n const { body } = await patchFn<SsoConnectionWire>(\n `/v1/sso/connections/${encodeURIComponent(id)}`,\n ssoConnectionInputToWire(input),\n );\n return wireToSsoConnection(body);\n },\n\n async deleteConnection(id: string) {\n await deleteFn(`/v1/sso/connections/${encodeURIComponent(id)}`);\n },\n\n async activateConnection(id: string) {\n const { body } = await postFn<{ ok: boolean; supabase_provider_id: string | null }>(\n `/v1/sso/connections/${encodeURIComponent(id)}/activate`,\n {},\n );\n return { ok: body.ok, supabaseProviderId: body.supabase_provider_id };\n },\n\n async enforce(action: SsoEnforceAction) {\n const { body } = await postFn<SsoEnforceResultWire>(\"/v1/sso/enforce\", { action });\n return {\n ok: body.ok,\n action: body.action,\n enforceSso: body.enforce_sso,\n enforceSsoAt: body.enforce_sso_at,\n };\n },\n\n async getStatus() {\n const { body } = await getFn<{ readiness: SsoReadinessWire }>(\"/v1/sso/status\");\n return wireToSsoReadiness(body.readiness);\n },\n\n async listJitRules(connectionId?: string) {\n const qs = connectionId ? new URLSearchParams({ connection_id: connectionId }) : undefined;\n const { body } = await getFn<{ rules: SsoJitRuleWire[] }>(\"/v1/sso/jit-rules\", qs);\n return { rules: (body.rules ?? []).map(wireToSsoJitRule) };\n },\n\n async createJitRule(input: SsoJitRuleInput) {\n const payload: Record<string, unknown> = {\n connection_id: input.connectionId,\n claim_attribute: input.claimAttribute,\n claim_value: input.claimValue,\n granted_role: input.grantedRole,\n };\n if (input.precedence !== undefined) payload[\"precedence\"] = input.precedence;\n const { body } = await postFn<SsoJitRuleWire>(\"/v1/sso/jit-rules\", payload);\n return wireToSsoJitRule(body);\n },\n\n async patchJitRule(id: string, patch: SsoJitRulePatch) {\n const payload: Record<string, unknown> = {};\n if (patch.claimAttribute !== undefined) payload[\"claim_attribute\"] = patch.claimAttribute;\n if (patch.claimValue !== undefined) payload[\"claim_value\"] = patch.claimValue;\n if (patch.grantedRole !== undefined) payload[\"granted_role\"] = patch.grantedRole;\n if (patch.precedence !== undefined) payload[\"precedence\"] = patch.precedence;\n if (patch.isActive !== undefined) payload[\"is_active\"] = patch.isActive;\n const { body } = await patchFn<SsoJitRuleWire>(\n `/v1/sso/jit-rules/${encodeURIComponent(id)}`,\n payload,\n );\n return wireToSsoJitRule(body);\n },\n\n async deleteJitRule(id: string) {\n await deleteFn(`/v1/sso/jit-rules/${encodeURIComponent(id)}`);\n },\n };\n}\n","/**\n * Access Governance Log sub-client — paginated identity lifecycle events.\n *\n * Wire surface: GET /v1/access-governance-log\n *\n * Usage:\n *\n * ```ts\n * import { AtlaSentClient } from \"@atlasent/sdk\";\n *\n * const client = new AtlaSentClient({ apiKey: \"...\" });\n *\n * const page = await client.accessGovernanceLog.list({ limit: 50 });\n * for (const event of page.events) {\n * console.log(event.eventType, event.actorEmail);\n * }\n * if (page.nextCursor) {\n * const next = await client.accessGovernanceLog.list({ cursor: page.nextCursor });\n * }\n * ```\n */\n\n// ── Wire shape ────────────────────────────────────────────────────────────────\n\ninterface AccessGovernanceEventWire {\n id: string;\n event_type: string;\n org_id: string;\n actor_id: string | null;\n actor_email: string | null;\n ip_address: string | null;\n metadata: Record<string, unknown>;\n created_at: string;\n}\n\ninterface AccessGovernanceLogResponseWire {\n events: AccessGovernanceEventWire[];\n next_cursor: string | null;\n total_count: number;\n}\n\n// ── SDK shape ─────────────────────────────────────────────────────────────────\n\n/** A single identity lifecycle event from the access governance log. */\nexport interface AccessGovernanceEvent {\n id: string;\n eventType: string;\n orgId: string;\n actorId: string | null;\n actorEmail: string | null;\n ipAddress: string | null;\n metadata: Record<string, unknown>;\n createdAt: string;\n}\n\n/** A page of access governance events with cursor for the next page. */\nexport interface AccessGovernanceLogPage {\n events: AccessGovernanceEvent[];\n /** Pass as `cursor` to `list()` to fetch the next page. `null` means no more pages. */\n nextCursor: string | null;\n totalCount: number;\n}\n\n/** Query parameters for `accessGovernanceLog.list()`. */\nexport interface AccessGovernanceLogQuery {\n /** Max events to return. Default 50, max 200. */\n limit?: number;\n /** Cursor from a previous page's `nextCursor`. */\n cursor?: string;\n /** Filter by event type (e.g. `\"sso.login\"`, `\"jit.provisioned\"`). */\n eventType?: string;\n /** Filter by actor email or UUID. */\n actorId?: string;\n /** Lower bound on event timestamp (ISO 8601). */\n from?: string;\n /** Upper bound on event timestamp (ISO 8601). */\n to?: string;\n}\n\n// ── Converter ─────────────────────────────────────────────────────────────────\n\nfunction wireToEvent(w: AccessGovernanceEventWire): AccessGovernanceEvent {\n return {\n id: w.id,\n eventType: w.event_type,\n orgId: w.org_id,\n actorId: w.actor_id,\n actorEmail: w.actor_email,\n ipAddress: w.ip_address,\n metadata: w.metadata ?? {},\n createdAt: w.created_at,\n };\n}\n\n// ── Sub-client ────────────────────────────────────────────────────────────────\n\n/**\n * Sub-client for the access governance log.\n * Accessed as `client.accessGovernanceLog` on {@link AtlaSentClient}.\n */\nexport interface AccessGovernanceLogSubClient {\n /**\n * Fetch a page of identity lifecycle events for the authenticated org.\n *\n * ```ts\n * const { events, nextCursor } = await client.accessGovernanceLog.list({\n * eventType: \"sso.login\",\n * limit: 100,\n * });\n * ```\n */\n list(query?: AccessGovernanceLogQuery): Promise<AccessGovernanceLogPage>;\n}\n\n/**\n * Factory that returns the access-governance-log sub-client bound to a host\n * client's transport helpers. Called internally by AtlaSentClient.\n */\nexport function makeAccessGovernanceLogClient(\n getFn: <T>(path: string, query?: URLSearchParams) => Promise<{ body: T }>,\n): AccessGovernanceLogSubClient {\n return {\n async list(query: AccessGovernanceLogQuery = {}): Promise<AccessGovernanceLogPage> {\n const qs = new URLSearchParams();\n if (query.limit !== undefined) qs.set(\"limit\", String(query.limit));\n if (query.cursor) qs.set(\"cursor\", query.cursor);\n if (query.eventType) qs.set(\"event_type\", query.eventType);\n if (query.actorId) qs.set(\"actor_id\", query.actorId);\n if (query.from) qs.set(\"from\", query.from);\n if (query.to) qs.set(\"to\", query.to);\n\n const { body } = await getFn<AccessGovernanceLogResponseWire>(\n \"/v1/access-governance-log\",\n qs.size > 0 ? qs : undefined,\n );\n\n return {\n events: (body.events ?? []).map(wireToEvent),\n nextCursor: body.next_cursor,\n totalCount: body.total_count ?? 0,\n };\n },\n };\n}\n","/**\n * AtlaSent HTTP client.\n *\n * Two public methods, both backed by native `fetch`:\n * - {@link AtlaSentClient.evaluate} → POST {baseUrl}/v1-evaluate\n * - {@link AtlaSentClient.verifyPermit} → POST {baseUrl}/v1-verify-permit\n *\n * Fail-closed: a clean policy DENY is returned (not thrown), but\n * network, timeout, bad response, 4xx/5xx, and rate-limit conditions\n * all throw {@link AtlaSentError}.\n */\n\nimport type {\n AuditEventsPage,\n AuditEventsQuery,\n AuditExport,\n} from \"./audit.js\";\nimport type { ReplayDecisionResponse } from \"./replay.js\";\nimport type {\n ReplayRequest,\n ReplayResponse,\n ReplayVarianceKind,\n} from \"./replay.js\";\nimport {\n AtlaSentError,\n StreamParseError,\n StreamTimeoutError,\n type AtlaSentErrorCode,\n type AtlaSentErrorInit,\n} from \"./errors.js\";\nimport {\n TrustRootManager,\n getGlobalTrustRootManager,\n type TrustRootSnapshot,\n} from \"./trustRoot.js\";\nimport { PRODUCTION_DEPLOY_ACTION } from \"./types.js\";\nimport type {\n ApiKeySelfResponse,\n AtlaSentClientOptions,\n Decision,\n AuditEventsResult,\n AuditExportRequest,\n AuditExportResult,\n ConstraintTrace,\n DecisionCanonical,\n DecisionStreamEvent,\n DeployGateEvidence,\n DeployGateRequest,\n DeployGateResponse,\n BatchEvalItem,\n BatchEvalResponse,\n EvaluateBatchResultItem,\n EvaluatePreflightResponse,\n SubscribeDecisionsOptions,\n EvaluateRequest,\n EvaluateResponse,\n GetPermitResponse,\n LicenseStatus,\n LicenseVerifyResult,\n ListPermitsRequest,\n ListPermitsResponse,\n PermitRecord,\n PermitValidResponse,\n RateLimitState,\n RevokePermitByIdInput,\n RevokePermitByIdResponse,\n RevokePermitRequest,\n RevokePermitResponse,\n StreamDecisionEvent,\n StreamEvent,\n StreamOptions,\n StreamProgressEvent,\n VerifyPermitByIdResponse,\n VerifyPermitRequest,\n VerifyPermitResponse,\n} from \"./types.js\";\nimport {\n normalizeEvaluateRequest,\n type LegacyEvaluateRequest,\n type V2EvaluateRequest,\n} from \"./compat.js\";\nimport {\n computeBackoffMs,\n hasAttemptsLeft,\n isRetryable,\n mergePolicy,\n type RetryPolicy,\n} from \"./retry.js\";\nimport type {\n GovernanceAgent,\n GovernanceAgentEvaluation,\n GovernanceAgentFinding,\n ListGovernanceAgentsResponse,\n ListGovernanceEvaluationsQuery,\n ListGovernanceEvaluationsResponse,\n ListGovernanceFindingsQuery,\n ListGovernanceFindingsResponse,\n} from \"./governanceAgents.js\";\nimport type {\n HitlApprovalRecord,\n HitlApproveRequest,\n HitlChainHop,\n HitlCreateRequest,\n HitlEscalateRequest,\n HitlEscalation,\n HitlRejectRequest,\n ListHitlEscalationsRequest,\n ListHitlEscalationsResponse,\n} from \"./hitl.js\";\nimport type {\n GovernanceGraphQueryType,\n GovernanceGraphQueryParams,\n GovernanceGraphQueryResponse,\n GovernanceGraphResultRow,\n} from \"./governanceGraph.js\";\nimport type { IncidentTimelineResponse } from \"./incidentReconstruction.js\";\nimport type {\n ConnectorType,\n InstallConnectorInput,\n AuthenticateConnectorInput,\n UpsertEnforcementPolicyInput,\n ListConnectorsResponse,\n InstallConnectorResponse,\n AuthenticateConnectorResponse,\n SyncConnectorResponse,\n RevokeConnectorResponse,\n RotateCredentialsResponse,\n ListEnforcementPoliciesResponse,\n UpsertEnforcementPolicyResponse,\n} from \"./connectorManagement.js\";\nimport type {\n ComputeOrgRiskOptions,\n ComputeOrgRiskResponse,\n GetLatestOrgRiskResponse,\n ListOrgRiskHistoryResponse,\n} from \"./orgRiskGraph.js\";\nimport type {\n CrossOrgPermissionCheckRequest,\n CrossOrgPermissionCheckResult,\n CrossOrgPermissionCheckListParams,\n} from \"./crossOrgPermission.js\";\nimport type {\n AnomalyResponseRule,\n AnomalyResponseEvent,\n CreateAnomalyResponseRuleRequest,\n TriggerAnomalyResponseRequest,\n} from \"./anomalyResponse.js\";\nimport type {\n BudgetExceptionRequest,\n BudgetExceptionStatus,\n CreateBudgetExceptionRequest,\n ApproveBudgetExceptionRequest,\n} from \"./budgetExceptions.js\";\nimport type {\n RegulatoryAuthorityLevel,\n RegulatoryEscalation,\n RegulatoryEscalationStatus,\n CreateRegulatoryEscalationRequest,\n} from \"./regulatoryEscalation.js\";\nimport type {\n GovernanceSignalAction,\n RecordSignalActionRequest,\n RecordSignalOutcomeRequest,\n SignalActionSummary,\n} from \"./incentiveSignalFeedback.js\";\nimport type {\n CrossOrgImpersonationGrant,\n CreateImpersonationGrantRequest,\n ImpersonationToken,\n ImpersonationValidationResult,\n} from \"./crossOrgImpersonation.js\";\nimport {\n makeScimClient,\n type ScimSubClient,\n} from \"./scim.js\";\nimport {\n makeEvidenceBundleClient,\n type EvidenceBundleSubClient,\n} from \"./evidence-bundle.js\";\nimport {\n makeAuthClient,\n type AuthSubClient,\n} from \"./auth.js\";\nimport {\n makeSsoClient,\n type SsoSubClient,\n} from \"./sso.js\";\nimport {\n makeAccessGovernanceLogClient,\n type AccessGovernanceLogSubClient,\n} from \"./access-governance-log.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.atlasent.io\";\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst SDK_VERSION = \"2.10.0\";\n\n/**\n * Guard flag: emit the browser-environment warning at most once per\n * module-load lifetime. Prevents console spam when many client\n * instances are constructed in the same bundle.\n */\nlet warnedBrowser = false;\nconst V1_EVALUATE_BATCH_PATH = \"/v1/evaluate/batch\";\nconst V1_EVALUATE_BATCH_LEGACY_PATH = \"/v1-evaluate-batch\";\nconst V1_EVALUATE_STREAM_PATH = \"/v1/evaluate/stream\";\nconst V1_EVALUATE_STREAM_LEGACY_PATH = \"/v1-evaluate-stream\";\n\nfunction _buildUserAgent(): string {\n const isNode =\n typeof process !== \"undefined\" &&\n typeof process?.versions?.node === \"string\";\n return isNode\n ? `@atlasent/sdk/${SDK_VERSION} node/${process.version}`\n : `@atlasent/sdk/${SDK_VERSION} browser`;\n}\n\n// Soft cap on top-level context properties. Mirrors the Python SDK\n// (atlasent.models._CONTEXT_PROPERTIES_SOFT_CAP) and the OpenAPI\n// `maxProperties: 64` declaration. The hosted API is the canonical\n// enforcer; this helper warns the developer in dev rather than\n// raising, so production traffic isn't broken on the day this ships.\nconst CONTEXT_PROPERTIES_SOFT_CAP = 64;\n\nfunction _warnOversizeContext(\n context: Record<string, unknown> | undefined,\n): void {\n if (context && Object.keys(context).length > CONTEXT_PROPERTIES_SOFT_CAP) {\n // eslint-disable-next-line no-console\n console.warn(\n `[atlasent] context has ${Object.keys(context).length} top-level keys ` +\n `(soft cap ${CONTEXT_PROPERTIES_SOFT_CAP}); the server may reject this. ` +\n \"Pack richer payloads under a single top-level key.\",\n );\n }\n}\n\n/**\n * Reject non-TLS base URLs unless the dev escape hatch is set.\n *\n * `ATLASENT_ALLOW_INSECURE_HTTP=1` (Node) or\n * `globalThis.ATLASENT_ALLOW_INSECURE_HTTP === \"1\"` (browser dev) permits\n * `http://` for local fixtures — production callers never set this.\n * Non-`http(s)` schemes (data:, file:, ...) are rejected unconditionally.\n *\n * Guards `process.env` access with an explicit `typeof` check so this\n * function is safe in browser and edge-runtime environments where\n * `process` is not defined as a global.\n */\nfunction _enforceTls(baseUrl: string): string {\n const nodeEnvValue =\n typeof process !== \"undefined\" && process.env\n ? process.env.ATLASENT_ALLOW_INSECURE_HTTP\n : undefined;\n const allow =\n nodeEnvValue === \"1\" ||\n (globalThis as { ATLASENT_ALLOW_INSECURE_HTTP?: string })\n .ATLASENT_ALLOW_INSECURE_HTTP === \"1\";\n if (allow) return baseUrl;\n let parsed: URL;\n try {\n parsed = new URL(baseUrl);\n } catch {\n throw new AtlaSentError(`Invalid baseUrl: ${baseUrl}`, {\n code: \"bad_request\",\n });\n }\n if (parsed.protocol !== \"https:\") {\n throw new AtlaSentError(\n `AtlaSent baseUrl must use https:// (got ${parsed.protocol}). ` +\n `For local development, set ATLASENT_ALLOW_INSECURE_HTTP=1.`,\n { code: \"bad_request\" },\n );\n }\n return baseUrl;\n}\n\n// API-key prefix contract per atlasent-api/_shared/auth.ts:\n// \"ask_live_<entropy>\" — production\n// \"ask_test_<entropy>\" — non-production\n// Validated client-side so a mis-pasted key (with whitespace, quotes,\n// or a leftover wrapping char) trips loudly at construction rather\n// than yielding a 401 mid-conversation.\nconst API_KEY_PATTERN = /^ask_(?:live|test)_[A-Za-z0-9_-]+$/;\n\nfunction _validateApiKey(apiKey: string): string {\n if (typeof apiKey !== \"string\" || apiKey.length === 0) {\n throw new AtlaSentError(\"apiKey is required\", { code: \"invalid_api_key\" });\n }\n if (!API_KEY_PATTERN.test(apiKey)) {\n const head = apiKey.slice(0, 8);\n throw new AtlaSentError(\n `AtlaSent apiKey does not match expected shape ` +\n `\\`ask_(live|test)_<entropy>\\` (got prefix=${JSON.stringify(head)}). ` +\n \"Check for whitespace, quotes, or trailing characters.\",\n { code: \"invalid_api_key\" },\n );\n }\n return apiKey;\n}\n\n/**\n * True when running in Node.js (or a Node-compatible server runtime that\n * exposes `process.versions.node`). False in browsers and browser-like\n * environments such as jsdom / Cloudflare Workers.\n */\nconst isNode =\n typeof process !== \"undefined\" && typeof process.versions?.node === \"string\";\n\n/**\n * Node.js version string captured at module-load time so request code\n * never accesses `process` lazily — safe even if `process` is absent\n * (browsers) or replaced after load (bundlers, test environments).\n * `null` in every non-Node runtime.\n */\nconst NODE_VERSION: string | null = isNode ? process.version : null;\n\n/**\n * Raw JSON shape received from `POST /v1-evaluate`.\n *\n * Canonical fields (per `atlasent-api/.../v1-evaluate/handler.ts`):\n * decision: \"allow\" | \"deny\" | \"hold\" | \"escalate\"\n * permit_token: string (present iff decision === \"allow\")\n * request_id: string\n * expires_at?: string\n * denial?: { reason, code }\n *\n * Legacy fields kept on the type so older atlasent-api deployments\n * (pre-handler.ts entry swap) still parse cleanly. The client below\n * checks canonical first and falls back to legacy.\n */\ninterface EvaluateWire {\n decision: \"allow\" | \"deny\" | \"hold\" | \"escalate\";\n permit_token?: string;\n request_id?: string;\n expires_at?: string;\n denial?: { reason?: string; code?: string };\n /**\n * Optional sub-object — present iff the request URL carried\n * `?include=constraint_trace`. Older atlasent-api deployments\n * omit this even when `include` was requested; the preflight\n * helper degrades to `null` in that case.\n */\n constraint_trace?: unknown;\n // Legacy passthrough.\n permitted?: boolean;\n decision_id?: string;\n reason?: string;\n audit_hash?: string;\n timestamp?: string;\n risk_envelope?: {\n weighted_score: number;\n engine_decision: string;\n envelope_decision: string;\n promoted: boolean;\n hard_blocks: string[];\n factors?: Array<{ factor: string; value: number; weight: number; reason: string }>;\n };\n // State-context response fields (control-plane v2+).\n risk_class?: string;\n authority_basis?: {\n kind: string;\n reference?: string;\n granted_by?: string;\n rationale?: string;\n expires_at?: string;\n };\n escalation_id?: string;\n}\n\ninterface EvaluateBatchWireItem {\n index: number;\n decision?: string;\n decision_id?: string;\n permit_token?: string | null;\n reason?: string | null;\n audit_entry_hash?: string;\n timestamp?: string;\n error?: string;\n message?: string;\n status?: number;\n}\n\ninterface EvaluateBatchWire {\n batch_id: string;\n items: EvaluateBatchWireItem[];\n partial?: boolean;\n replayed?: boolean;\n}\n\nfunction deployGateEvidence(input: {\n permitId?: string;\n permitHash?: string;\n auditHash?: string;\n verifiedAt?: string;\n}): DeployGateEvidence {\n const evidence: DeployGateEvidence = {};\n if (input.permitId) evidence.permitId = input.permitId;\n if (input.permitHash) evidence.permitHash = input.permitHash;\n if (input.auditHash) evidence.auditHash = input.auditHash;\n if (input.verifiedAt) evidence.verifiedAt = input.verifiedAt;\n return evidence;\n}\n\n/** Raw JSON shape received from `GET /v1-api-key-self`. */\ninterface ApiKeySelfWire {\n key_id: string;\n org_id: string;\n environment: string;\n scopes?: string[];\n allowed_cidrs?: string[] | null;\n rate_limit_per_minute: number;\n client_ip?: string | null;\n expires_at?: string | null;\n}\n\n/**\n * Raw JSON shape received from `POST /v1-verify-permit`.\n *\n * Canonical fields:\n * valid: boolean\n * outcome: \"allow\" | \"deny\"\n * verify_error_code?: string (populated on outcome === \"deny\")\n * reason?: string\n *\n * Legacy `verified` kept for backward-compat with older deployments.\n */\ninterface VerifyPermitWire {\n valid: boolean;\n outcome: \"allow\" | \"deny\";\n verify_error_code?: string;\n reason?: string;\n expires_at?: string | null;\n // Legacy passthrough.\n verified?: boolean;\n permit_hash?: string;\n timestamp?: string;\n}\n\nexport class AtlaSentClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly timeoutMs: number;\n private readonly fetchImpl: typeof fetch;\n private readonly userAgent: string;\n private readonly retryPolicy: Required<RetryPolicy>;\n\n /** SCIM 2.0 provisioning sub-client. Access as `client.scim`. */\n readonly scim: ScimSubClient;\n /** Evidence bundle sub-client. Access as `client.evidenceBundles`. */\n readonly evidenceBundles: EvidenceBundleSubClient;\n /** Auth / token management sub-client. Access as `client.auth`. */\n readonly auth: AuthSubClient;\n /** SSO administration sub-client. Access as `client.sso`. */\n readonly sso: SsoSubClient;\n /** Access governance log sub-client. Access as `client.accessGovernanceLog`. */\n readonly accessGovernanceLog: AccessGovernanceLogSubClient;\n /** Trust-root snapshot manager for this client instance. */\n readonly trustRoot: TrustRootManager;\n\n constructor(options: AtlaSentClientOptions) {\n if (!options.apiKey || typeof options.apiKey !== \"string\") {\n throw new AtlaSentError(\"apiKey is required\", {\n code: \"invalid_api_key\",\n });\n }\n if (typeof AbortSignal.timeout !== \"function\") {\n throw new AtlaSentError(\n \"@atlasent/sdk requires AbortSignal.timeout, which is not available in this runtime. \" +\n \"Minimum supported browsers: Chrome 103+, Firefox 100+, Safari 16+. \" +\n \"Upgrade your browser or add an AbortSignal.timeout polyfill.\",\n { code: \"network\" },\n );\n }\n if (\n !warnedBrowser &&\n typeof (globalThis as Record<string, unknown>)[\"window\"] !== \"undefined\" &&\n typeof process === \"undefined\"\n ) {\n warnedBrowser = true;\n // eslint-disable-next-line no-console\n console.warn(\n \"[@atlasent/sdk] Running in a browser environment. \" +\n \"API keys should not be exposed in client-side bundles. \" +\n \"Use a server-side proxy instead.\",\n );\n }\n this.apiKey = _validateApiKey(options.apiKey);\n this.baseUrl = _enforceTls(options.baseUrl ?? DEFAULT_BASE_URL).replace(\n /\\/+$/,\n \"\",\n );\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);\n this.userAgent = _buildUserAgent();\n this.retryPolicy = mergePolicy(options.retryPolicy ?? {});\n this.scim = makeScimClient(\n (path, body, query) => this._post(path, body, query),\n (path, query) => this._get(path, query),\n (path, body) => this._put(path, body),\n (path) => this._delete(path),\n );\n this.evidenceBundles = makeEvidenceBundleClient(\n (path, body) => this._post(path, body),\n (path, query) => this._get(path, query),\n (path) => this._getRaw(path),\n );\n this.auth = makeAuthClient(\n (path, body) => this._post(path, body),\n (path) => this._get(path),\n );\n this.sso = makeSsoClient(\n (path, query) => this._get(path, query),\n (path, body) => this._post(path, body),\n (path, body) => this._patch(path, body),\n (path) => this._delete(path),\n );\n this.accessGovernanceLog = makeAccessGovernanceLogClient(\n (path, query) => this._get(path, query),\n );\n // Wire trust-root manager. Prefer custom options over the global manager\n // so clients with custom trustRootUrl or trustSnapshotRefreshMs get their\n // own manager; otherwise share the process-global singleton.\n if (options.trustRootUrl !== undefined || options.trustSnapshotRefreshMs !== undefined) {\n const globalSnap = getGlobalTrustRootManager({ disableRefresh: true }).getSnapshot();\n this.trustRoot = new TrustRootManager(globalSnap, {\n ...(options.trustRootUrl !== undefined && { refreshBaseUrl: options.trustRootUrl }),\n ...(options.trustSnapshotRefreshMs !== undefined && { refreshIntervalMs: options.trustSnapshotRefreshMs }),\n });\n } else {\n this.trustRoot = getGlobalTrustRootManager();\n }\n // Emit expiry warning once at construction time.\n this.trustRoot.checkExpiry();\n }\n\n /** Return the current trust-root snapshot (pinned or last successful refresh). */\n getTrustSnapshot(): TrustRootSnapshot {\n return this.trustRoot.getSnapshot();\n }\n\n /**\n * Ask the policy engine whether an agent action is permitted.\n *\n * Accepts either the current v2.0 shape (`action_type` / `actor_id`)\n * or the legacy v1.x shape (`action` / `agent`). Legacy callers\n * receive a deprecation warning via `console.warn`; the shim is\n * handled by {@link normalizeEvaluateRequest} and will be removed\n * in v3.0.0.\n *\n * A \"deny\" is **not** thrown — it is returned in\n * `response.decision`. Network errors, invalid API key, rate\n * limits, timeouts, and malformed responses throw\n * {@link AtlaSentError}.\n */\n async evaluate(\n input: EvaluateRequest | LegacyEvaluateRequest,\n ): Promise<EvaluateResponse> {\n _warnOversizeContext(input.context);\n\n // Run the dual-shape bridge: legacy {action, agent} → {action_type, actor_id}.\n // For callers already on the current EvaluateRequest shape the bridge is a\n // transparent pass-through (no warn, no allocation).\n const normalized = normalizeEvaluateRequest(\n input as LegacyEvaluateRequest | V2EvaluateRequest,\n );\n\n const body: Record<string, unknown> = {\n action_type: normalized.action_type,\n actor_id: normalized.actor_id,\n context: normalized.context ?? {},\n };\n if (normalized.explain !== undefined) body.explain = normalized.explain;\n if (normalized.environment !== undefined) body.environment = normalized.environment;\n if (normalized.resource !== undefined) body.resource = normalized.resource;\n if (normalized.current_state !== undefined) body.current_state = normalized.current_state;\n if (normalized.proposed_state !== undefined) body.proposed_state = normalized.proposed_state;\n if (normalized.execution_binding !== undefined) body.execution_binding = normalized.execution_binding;\n const { body: wire, rateLimit } = await this.post<EvaluateWire>(\n \"/v1-evaluate\",\n body,\n );\n\n // Normalise decision to lowercase canonical form. API responses may\n // arrive as uppercase (legacy deployments) or lowercase (canonical);\n // we always emit lowercase so callers can rely on a stable vocabulary.\n let decision = (\n typeof wire.decision === \"string\"\n ? wire.decision.toLowerCase()\n : wire.decision\n ) as EvaluateWire[\"decision\"] | undefined;\n\n // Tolerate both canonical {decision, permit_token} and legacy\n // {permitted, decision_id} server responses.\n if (decision === undefined && typeof wire.permitted === \"boolean\") {\n decision = wire.permitted ? \"allow\" : \"deny\";\n }\n const permitToken = wire.permit_token ?? wire.decision_id;\n\n if (\n decision !== \"allow\" &&\n decision !== \"deny\" &&\n decision !== \"hold\" &&\n decision !== \"escalate\"\n ) {\n throw new AtlaSentError(\n \"Malformed response from /v1-evaluate: missing `decision` (or legacy `permitted`)\",\n { code: \"bad_response\" },\n );\n }\n if (\n decision === \"allow\" &&\n (typeof permitToken !== \"string\" || permitToken.length === 0)\n ) {\n throw new AtlaSentError(\n \"Malformed response from /v1-evaluate: decision='allow' but no `permit_token` (or legacy `decision_id`)\",\n { code: \"bad_response\" },\n );\n }\n\n const reason = wire.denial?.reason ?? wire.reason ?? \"\";\n const permitId = permitToken ?? \"\";\n return {\n decision,\n decision_canonical: decision,\n evaluationId: permitId,\n permitId,\n // /v1-evaluate does not return a control-plane-shaped Permit body;\n // callers needing the full record fetch GET /v1/permits/:id.\n permit: null,\n permitToken: decision === \"allow\" ? (permitToken ?? null) : null,\n reasons: reason ? [reason] : [],\n reason,\n auditHash: wire.audit_hash ?? \"\",\n timestamp: wire.timestamp ?? \"\",\n rateLimit,\n ...(wire.risk_envelope && {\n riskEnvelope: {\n weightedScore: wire.risk_envelope.weighted_score,\n engineDecision: wire.risk_envelope.engine_decision as Decision,\n envelopeDecision: wire.risk_envelope.envelope_decision as Decision,\n promoted: wire.risk_envelope.promoted,\n hardBlocks: wire.risk_envelope.hard_blocks ?? [],\n ...(wire.risk_envelope.factors && { factors: wire.risk_envelope.factors }),\n },\n }),\n ...(wire.risk_class !== undefined && { riskClass: wire.risk_class }),\n ...(wire.authority_basis && {\n authorityBasis: {\n kind: wire.authority_basis.kind as NonNullable<EvaluateResponse[\"authorityBasis\"]>[\"kind\"],\n ...(wire.authority_basis.reference !== undefined && { reference: wire.authority_basis.reference }),\n ...(wire.authority_basis.granted_by !== undefined && { grantedBy: wire.authority_basis.granted_by }),\n ...(wire.authority_basis.rationale !== undefined && { rationale: wire.authority_basis.rationale }),\n ...(wire.authority_basis.expires_at !== undefined && { expiresAt: wire.authority_basis.expires_at }),\n },\n }),\n ...(wire.escalation_id !== undefined && { escalationId: wire.escalation_id }),\n };\n }\n\n /**\n * Batch evaluate — send up to 100 decisions in a single round-trip.\n *\n * Wraps `POST /v1/evaluate/batch` (with fallback to\n * `POST /v1-evaluate-batch` on older runtimes). The server evaluates each item\n * against the active policy bundle and returns results in the same\n * order as the input. One rate-limit token is consumed for the\n * whole batch, and one audit-chain entry lists every included\n * decision id.\n *\n * A per-item policy `deny` is **not** thrown — it appears as\n * `item.decision === \"deny\"` in the returned items. A whole-batch\n * network error, 4xx, or 5xx throws {@link AtlaSentError}.\n *\n * Requires the `v2_batch` tenant feature flag to be enabled on the\n * org (returns 404 when off). Requires scope `evaluate:write`.\n *\n * @param requests - 1–100 evaluate items.\n * @param batchId - Optional caller-supplied UUID for idempotency.\n * A retried call with the same `batchId` and identical items\n * returns the cached response within 24 h (`replayed: true`).\n */\n async evaluateBatch(\n requests: BatchEvalItem[],\n batchId?: string,\n ): Promise<BatchEvalResponse> {\n if (!Array.isArray(requests) || requests.length === 0) {\n throw new AtlaSentError(\n \"evaluateBatch: requests must be a non-empty array\",\n { code: \"bad_request\" },\n );\n }\n if (requests.length > 100) {\n throw new AtlaSentError(\n `evaluateBatch: requests.length ${requests.length} exceeds the 100-item cap`,\n { code: \"bad_request\" },\n );\n }\n\n const wireItems = requests.map((r) => ({\n action_type: r.action,\n actor_id: r.agent,\n context: r.context ?? {},\n }));\n\n const wireBody: Record<string, unknown> = { items: wireItems };\n if (batchId) wireBody.batch_id = batchId;\n\n const { body: wire, rateLimit } = await this.postWithPathFallback<EvaluateBatchWire>(\n V1_EVALUATE_BATCH_PATH,\n V1_EVALUATE_BATCH_LEGACY_PATH,\n wireBody,\n );\n\n const items: EvaluateBatchResultItem[] = (wire.items ?? []).map(\n (item: EvaluateBatchWireItem) => {\n const rawDecision = typeof item.decision === \"string\"\n ? item.decision.toLowerCase()\n : undefined;\n const decision = (\n rawDecision === \"allow\" ||\n rawDecision === \"deny\" ||\n rawDecision === \"hold\" ||\n rawDecision === \"escalate\"\n ? rawDecision\n : undefined\n ) as DecisionCanonical | undefined;\n\n return {\n index: item.index,\n ...(decision !== undefined ? { decision } : {}),\n ...(item.decision_id ? { decisionId: item.decision_id } : {}),\n ...(item.permit_token != null ? { permitToken: item.permit_token } : {}),\n ...(item.reason != null ? { reason: item.reason } : {}),\n ...(item.audit_entry_hash ? { auditHash: item.audit_entry_hash } : {}),\n ...(item.timestamp ? { timestamp: item.timestamp } : {}),\n ...(item.error ? { error: item.error } : {}),\n ...(item.message ? { message: item.message } : {}),\n } satisfies EvaluateBatchResultItem;\n },\n );\n\n return {\n batchId: wire.batch_id,\n items,\n partial: wire.partial ?? false,\n ...(wire.replayed ? { replayed: wire.replayed } : {}),\n rateLimit,\n };\n }\n\n /**\n * Subscribe to a live stream of decisions for this org.\n *\n * Wraps `GET /v1-decisions-stream`. The server emits one SSE frame\n * per audit event and sends a heartbeat every 15 s. The session\n * auto-closes after `maxSeconds` (default 30 min); reconnect with\n * the last received `event.id` to resume without replaying history.\n *\n * ```ts\n * const controller = new AbortController();\n * for await (const event of client.subscribeDecisions({ signal: controller.signal })) {\n * if (event.type === \"heartbeat\") continue;\n * console.log(event.type, event.decision, event.actorId);\n * if (event.type === \"session_end\") break; // reconnect\n * }\n * ```\n *\n * Requires scope `audit:read`. Requires the `v2_decisions_stream`\n * tenant feature flag (returns 404 when off).\n */\n async *subscribeDecisions(\n opts: SubscribeDecisionsOptions = {},\n ): AsyncGenerator<DecisionStreamEvent> {\n const url = new URL(`${this.baseUrl}/v1-decisions-stream`);\n if (opts.types?.length) url.searchParams.set(\"types\", opts.types.join(\",\"));\n if (opts.actorId) url.searchParams.set(\"actor_id\", opts.actorId);\n if (opts.maxSeconds !== undefined) url.searchParams.set(\"max_seconds\", String(opts.maxSeconds));\n\n const headers: Record<string, string> = {\n Accept: \"text/event-stream\",\n Authorization: `Bearer ${this.apiKey}`,\n \"User-Agent\": this.userAgent,\n // ADR-025: declare the wire-protocol version we were built\n // against. Runtime serves this version's response shape; older\n // versions outside the compatibility window get 426.\n \"X-AtlaSent-Protocol-Version\": \"1\",\n };\n if (opts.lastEventId) headers[\"Last-Event-ID\"] = opts.lastEventId;\n\n let response: Response;\n try {\n response = await this.fetchImpl(url.toString(), {\n method: \"GET\",\n headers,\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") return;\n throw new AtlaSentError(\n `Failed to connect to decisions stream: ${err instanceof Error ? err.message : String(err)}`,\n { code: \"network\" },\n );\n }\n\n if (!response.ok) {\n const code = response.status === 401 ? \"invalid_api_key\" : \"server_error\";\n throw new AtlaSentError(\n `Decisions stream returned ${response.status}`,\n { code, status: response.status },\n );\n }\n\n if (!response.body) {\n throw new AtlaSentError(\"Decisions stream response has no body\", { code: \"bad_response\" });\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder(\"utf-8\");\n let buf = \"\";\n\n try {\n while (true) {\n let chunk: Awaited<ReturnType<typeof reader.read>>;\n try {\n chunk = await reader.read();\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") return;\n throw new AtlaSentError(\n `Decisions stream read error: ${err instanceof Error ? err.message : String(err)}`,\n { code: \"network\" },\n );\n }\n if (chunk.done) break;\n\n buf += decoder.decode(chunk.value, { stream: true });\n const rawBlocks = buf.split(\"\\n\\n\");\n buf = rawBlocks.pop() ?? \"\";\n\n for (const block of rawBlocks) {\n if (!block.trim()) continue;\n\n // SSE comment / heartbeat line (\": …\")\n if (block.trimStart().startsWith(\":\")) {\n yield { type: \"heartbeat\" };\n continue;\n }\n\n let id: string | undefined;\n let eventType = \"audit_event\";\n let dataLine = \"\";\n\n for (const line of block.split(\"\\n\")) {\n if (line.startsWith(\"id:\")) id = line.slice(3).trim();\n else if (line.startsWith(\"event:\")) eventType = line.slice(6).trim();\n else if (line.startsWith(\"data:\")) dataLine = line.slice(5).trim();\n }\n\n if (!dataLine) continue;\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(dataLine) as Record<string, unknown>;\n } catch {\n continue;\n }\n\n if (eventType === \"session_end\") {\n yield { ...(id !== undefined ? { id } : {}), type: \"session_end\", payload: parsed };\n return;\n }\n\n const decision = typeof parsed.decision === \"string\"\n ? parsed.decision.toLowerCase() as DecisionCanonical\n : undefined;\n\n yield {\n ...(id !== undefined ? { id } : {}),\n type: eventType,\n ...(decision ? { decision } : {}),\n ...(typeof parsed.actor_id === \"string\" ? { actorId: parsed.actor_id } : {}),\n ...(typeof parsed.resource_type === \"string\" ? { resourceType: parsed.resource_type } : {}),\n ...(typeof parsed.resource_id === \"string\" ? { resourceId: parsed.resource_id } : {}),\n ...(parsed.payload && typeof parsed.payload === \"object\" ? { payload: parsed.payload as Record<string, unknown> } : {}),\n ...(typeof parsed.hash === \"string\" ? { hash: parsed.hash } : {}),\n ...(typeof parsed.previous_hash === \"string\" ? { previousHash: parsed.previous_hash } : {}),\n ...(typeof parsed.occurred_at === \"string\" ? { occurredAt: parsed.occurred_at } : {}),\n } satisfies DecisionStreamEvent;\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Pre-flight evaluation that always returns the constraint trace.\n *\n * Wraps `POST /v1-evaluate?include=constraint_trace`. Use this from\n * a workflow's submission step to surface trivial defects (missing\n * fields, wrong roles, mis-set context) BEFORE pushing the request\n * onto an approval queue — only requests that would actually pass\n * make it through to a human reviewer.\n *\n * Returns an {@link EvaluatePreflightResponse} carrying the regular\n * {@link EvaluateResponse} plus the {@link ConstraintTrace}. Unlike\n * {@link evaluate}, this method does NOT mark a non-allow as a\n * thrown condition — the whole point is to inspect both the outcome\n * AND the per-policy trace, so the caller branches on\n * `result.evaluation.decision` and reads `result.constraintTrace`\n * to render the failing stages.\n *\n * The constraint-trace shape mirrors `ConstraintTraceResponse` in\n * atlasent-api (`packages/types/src/index.ts`). On older\n * atlasent-api deployments that omit the trace, `constraintTrace`\n * is `null` rather than throwing — forward-compatible degradation.\n *\n * Performance: one extra round-trip on submission. Latency is\n * comparable to {@link evaluate}; the response body is fuller\n * (includes the per-stage trace) so the wire payload is larger.\n * If the caller does not need the trace, prefer {@link evaluate}.\n */\n async evaluatePreflight(\n input: EvaluateRequest,\n ): Promise<EvaluatePreflightResponse> {\n _warnOversizeContext(input.context);\n const body = {\n action_type: input.action,\n actor_id: input.agent,\n context: input.context ?? {},\n };\n const query = new URLSearchParams({ include: \"constraint_trace\" });\n const { body: wire, rateLimit } = await this.post<EvaluateWire>(\n \"/v1-evaluate\",\n body,\n query,\n );\n\n // Normalise decision to lowercase canonical form.\n let decision = (\n typeof wire.decision === \"string\"\n ? wire.decision.toLowerCase()\n : wire.decision\n ) as EvaluateWire[\"decision\"] | undefined;\n\n if (decision === undefined && typeof wire.permitted === \"boolean\") {\n decision = wire.permitted ? \"allow\" : \"deny\";\n }\n if (\n decision !== \"allow\" &&\n decision !== \"deny\" &&\n decision !== \"hold\" &&\n decision !== \"escalate\"\n ) {\n throw new AtlaSentError(\n \"Malformed response from /v1-evaluate: missing `decision` (or legacy `permitted`)\",\n { code: \"bad_response\" },\n );\n }\n const permitToken = wire.permit_token ?? wire.decision_id;\n\n const reason = wire.denial?.reason ?? wire.reason ?? \"\";\n const permitId = permitToken ?? \"\";\n const evaluation: EvaluateResponse = {\n decision,\n decision_canonical: decision,\n evaluationId: permitId,\n permitId,\n // /v1-evaluate does not return a control-plane-shaped Permit body;\n // callers needing the full record fetch GET /v1/permits/:id.\n permit: null,\n permitToken: decision === \"allow\" ? (permitToken ?? null) : null,\n reasons: reason ? [reason] : [],\n reason,\n auditHash: wire.audit_hash ?? \"\",\n timestamp: wire.timestamp ?? \"\",\n rateLimit,\n ...(wire.risk_envelope && {\n riskEnvelope: {\n weightedScore: wire.risk_envelope.weighted_score,\n engineDecision: wire.risk_envelope.engine_decision as Decision,\n envelopeDecision: wire.risk_envelope.envelope_decision as Decision,\n promoted: wire.risk_envelope.promoted,\n hardBlocks: wire.risk_envelope.hard_blocks ?? [],\n ...(wire.risk_envelope.factors && { factors: wire.risk_envelope.factors }),\n },\n }),\n };\n\n // Forward-compat: if the server omits `constraint_trace` (older\n // atlasent-api version), surface trace=null rather than throwing.\n // Unknown engine-side keys inside the trace are tolerated by the\n // ConstraintTrace interface's index signature.\n let constraintTrace: ConstraintTrace | null = null;\n if (\n wire.constraint_trace !== undefined &&\n wire.constraint_trace !== null &&\n typeof wire.constraint_trace === \"object\"\n ) {\n constraintTrace = wire.constraint_trace as ConstraintTrace;\n }\n\n return { evaluation, constraintTrace };\n }\n\n /**\n * Verify that a previously issued permit is still valid.\n *\n * @deprecated Use {@link verifyPermitById} — the canonical REST\n * surface (`POST /v1/permits/{id}/verify`) returns the unified\n * verification envelope plus the full {@link PermitRecord}, instead\n * of the legacy `{verified, outcome, permitHash}` shape this method\n * emits. Will be removed in `@atlasent/sdk@3`.\n *\n * A `verified: false` response is **not** thrown — inspect the\n * returned object. Only transport / server errors throw.\n */\n async verifyPermit(\n input: VerifyPermitRequest,\n ): Promise<VerifyPermitResponse> {\n _warnOversizeContext(input.context);\n // Canonical wire shape per handler.ts: only permit_token is required.\n // action_type / actor_id are optional cross-checks; context / api_key\n // are NOT consulted by the verify handler.\n const body: Record<string, unknown> = {\n permit_token: input.permitId,\n action_type: input.action ?? \"\",\n actor_id: input.agent ?? \"\",\n };\n if (input.environment !== undefined) {\n body.environment = input.environment;\n }\n if (input.execution_hash !== undefined) {\n body.execution_hash = input.execution_hash;\n }\n const { body: wire, rateLimit } = await this.post<VerifyPermitWire>(\n \"/v1-verify-permit\",\n body,\n );\n\n // Tolerate both canonical {valid, outcome} and legacy {verified} server\n // responses.\n const valid = typeof wire.valid === \"boolean\" ? wire.valid : wire.verified;\n if (typeof valid !== \"boolean\") {\n throw new AtlaSentError(\n \"Malformed response from /v1-verify-permit: missing `valid` (or legacy `verified`)\",\n { code: \"bad_response\" },\n );\n }\n\n return {\n verified: valid,\n outcome: wire.outcome ?? \"\",\n permitHash: wire.permit_hash ?? \"\",\n timestamp: wire.timestamp ?? \"\",\n expiresAt: wire.expires_at ?? null,\n rateLimit,\n };\n }\n\n /**\n * Run the canonical Deploy Gate V1 flow:\n * evaluate `production.deploy`, verify the issued permit server-side,\n * and return allow/block plus audit/evidence metadata.\n *\n * This helper never treats a signed/offline permit artifact as sufficient\n * authorization. Execution is allowed only when `POST /v1-evaluate` returns\n * `decision: \"allow\"` with a permit AND `POST /v1-verify-permit` returns\n * `verified: true` / `valid: true`.\n */\n async deployGate(input: DeployGateRequest = {}): Promise<DeployGateResponse> {\n const agent = input.agent ?? \"ci-deploy-bot\";\n const action = input.action ?? PRODUCTION_DEPLOY_ACTION;\n const context = input.context ?? {};\n const environment =\n typeof (context as Record<string, unknown>).environment === \"string\"\n ? ((context as Record<string, unknown>).environment as string)\n : typeof (context as Record<string, unknown>).environment_name === \"string\"\n ? ((context as Record<string, unknown>).environment_name as string)\n : undefined;\n\n const evaluation = await this.evaluate({ agent, action, context });\n if (evaluation.decision !== \"allow\") {\n return {\n allowed: false,\n evaluation,\n reason:\n evaluation.reason ||\n `Deploy Gate blocked by decision=${evaluation.decision}`,\n evidence: deployGateEvidence({\n permitId: evaluation.permitId,\n auditHash: evaluation.auditHash,\n }),\n };\n }\n\n const verification = await this.verifyPermit({\n permitId: evaluation.permitId,\n agent,\n action,\n context,\n ...(environment !== undefined ? { environment } : {}),\n });\n\n if (!verification.verified) {\n return {\n allowed: false,\n evaluation,\n verification,\n reason: verification.outcome\n ? `Deploy Gate blocked by permit verification outcome=${verification.outcome}`\n : \"Deploy Gate blocked because permit verification failed\",\n evidence: deployGateEvidence({\n permitId: evaluation.permitId,\n permitHash: verification.permitHash,\n auditHash: evaluation.auditHash,\n verifiedAt: verification.timestamp,\n }),\n };\n }\n\n return {\n allowed: true,\n evaluation,\n verification,\n reason: evaluation.reason || \"Deploy Gate permit verified\",\n evidence: deployGateEvidence({\n permitId: evaluation.permitId,\n permitHash: verification.permitHash,\n auditHash: evaluation.auditHash,\n verifiedAt: verification.timestamp,\n }),\n };\n }\n\n /**\n * Revoke a previously-issued permit so it can no longer pass\n * {@link verifyPermit}.\n *\n * @deprecated Use {@link revokePermitById} — the canonical REST\n * surface (`POST /v1/permits/{id}/revoke`) returns the full updated\n * {@link PermitRecord} with `revoked_at`/`revoked_by`/`revoke_reason`\n * populated, instead of the legacy `{revoked, permitId}` envelope\n * this method emits. Will be removed in `@atlasent/sdk@3`.\n *\n * Use this when an agent's action is cancelled, superseded, or\n * determined to be unauthorized after the fact. The revocation is\n * recorded in the audit log with the optional `reason`.\n *\n * Throws {@link AtlaSentError} on transport / auth failures.\n */\n async revokePermit(\n input: RevokePermitRequest,\n ): Promise<RevokePermitResponse> {\n const body = {\n decision_id: input.permitId,\n reason: input.reason ?? \"\",\n api_key: this.apiKey,\n };\n const { body: wire, rateLimit } = await this.post<{\n revoked: boolean;\n decision_id: string;\n revoked_at?: string;\n audit_hash?: string;\n }>(\"/v1-revoke-permit\", body);\n\n if (\n typeof wire.revoked !== \"boolean\" ||\n typeof wire.decision_id !== \"string\"\n ) {\n throw new AtlaSentError(\n \"Malformed response from /v1-revoke-permit: missing `revoked` or `decision_id`\",\n { code: \"bad_response\" },\n );\n }\n\n return {\n revoked: wire.revoked,\n permitId: wire.decision_id,\n revokedAt: wire.revoked_at,\n auditHash: wire.audit_hash,\n rateLimit,\n };\n }\n\n /**\n * Revoke a permit through the canonical REST surface\n * (`POST /v1/permits/{permitId}/revoke`).\n *\n * Returns the full updated {@link PermitRecord} with `status === 'revoked'`\n * and `revoked_at` / `revoked_by` / `revoke_reason` populated. After\n * revocation, subsequent verify calls return `410 PERMIT_REVOKED`.\n *\n * Idempotent on `409 permit_revoked` for already-revoked permits;\n * server returns the existing revoked row in that case.\n *\n * Throws {@link AtlaSentError} on `404` (permit not in calling org),\n * `409` (already in a terminal state), `410` (expired before revoke),\n * or `429` (rate limited).\n */\n async revokePermitById(\n permitId: string,\n input: RevokePermitByIdInput = {},\n ): Promise<RevokePermitByIdResponse> {\n if (!permitId) {\n throw new AtlaSentError(\"permitId is required\", { code: \"bad_request\" });\n }\n const body: { reason?: string } = {};\n if (input.reason !== undefined) body.reason = input.reason;\n const { body: wire, rateLimit } = await this.post<PermitRecord>(\n `/v1/permits/${encodeURIComponent(permitId)}/revoke`,\n body,\n );\n return { permit: wire, rateLimit };\n }\n\n /**\n * Verify a permit through the canonical REST surface\n * (`POST /v1/permits/{permitId}/verify`).\n *\n * Returns the unified verification envelope (`valid`,\n * `verification_type: 'permit'`, `reason`, `verified_at`, `evidence`)\n * plus the full {@link PermitRecord} fields preserved at the top\n * level. The `valid` field is the contract — pin to it.\n *\n * A `valid: false` is **not** thrown when the server returns 200 with\n * a denial reason (matches the verify-shape unification on the wire);\n * it is thrown on 4xx (`404` not found, `410` expired/consumed).\n */\n async verifyPermitById(permitId: string): Promise<VerifyPermitByIdResponse> {\n if (!permitId) {\n throw new AtlaSentError(\"permitId is required\", { code: \"bad_request\" });\n }\n const { body: wire, rateLimit } = await this.post<\n VerifyPermitByIdResponse & PermitRecord\n >(`/v1/permits/${encodeURIComponent(permitId)}/verify`, {});\n // Server returns the canonical envelope merged with the Permit row\n // (allOf in openapi). Pull out the legacy permit row into `permit`\n // for callers that want it as a sub-object too.\n const { valid, verification_type, reason, verified_at, evidence, ...row } =\n wire as VerifyPermitByIdResponse & PermitRecord;\n return {\n valid,\n verification_type,\n reason,\n verified_at,\n evidence,\n permit: row as PermitRecord,\n rateLimit,\n };\n }\n\n /**\n * Get a single permit's full lifecycle state.\n *\n * Calls `GET /v1/permits/{permitId}` (the canonical REST surface).\n * Returns `status`, all timestamps, `revoked_at` / `revoked_by` /\n * `revoke_reason` (when applicable), and the bound `payload_hash`\n * / `decision_id`.\n *\n * Operator-facing introspection — answers \"what state is this permit\n * in, and why?\" without reading audit logs.\n *\n * Throws {@link AtlaSentError} on `404` (permit not in calling org)\n * or `410` (expired before retrieval).\n */\n async getPermit(permitId: string): Promise<GetPermitResponse> {\n if (!permitId) {\n throw new AtlaSentError(\"permitId is required\", { code: \"bad_request\" });\n }\n const { body: wire, rateLimit } = await this.get<PermitRecord>(\n `/v1/permits/${encodeURIComponent(permitId)}`,\n );\n return { permit: wire, rateLimit };\n }\n\n /**\n * Poll whether a permit is currently valid.\n *\n * Calls `GET /v1/permits/{permitId}/valid` — a lightweight read\n * returning only the status snapshot optimised for guard heartbeat\n * polling. Guards with `permitRevalidationIntervalMs` set race this\n * against `tool.execute()` and throw {@link PermitRevoked} when\n * `status === \"revoked\"` arrives.\n *\n * Throws {@link AtlaSentError} on transport / auth failures.\n */\n async checkPermitValid(permitId: string): Promise<PermitValidResponse> {\n if (!permitId) {\n throw new AtlaSentError(\"permitId is required\", { code: \"bad_request\" });\n }\n const { body } = await this.get<PermitValidResponse>(\n `/v1/permits/${encodeURIComponent(permitId)}/valid`,\n );\n return body;\n }\n\n /**\n * List permits issued to the calling org, most-recently-issued first.\n *\n * Calls `GET /v1/permits` (the canonical REST surface). Cursor-paged.\n * Filters narrow on server side; pagination uses the `created_at`\n * timestamp opaquely (`nextCursor`).\n *\n * Designed for incident review, debugging, and compliance\n * reconstruction.\n */\n async listPermits(\n input: ListPermitsRequest = {},\n ): Promise<ListPermitsResponse> {\n const params = new URLSearchParams();\n if (input.status) params.set(\"status\", input.status);\n if (input.actorId) params.set(\"actor_id\", input.actorId);\n if (input.actionType) params.set(\"action_type\", input.actionType);\n if (input.from) params.set(\"from\", input.from);\n if (input.to) params.set(\"to\", input.to);\n if (input.limit !== undefined) params.set(\"limit\", String(input.limit));\n if (input.cursor) params.set(\"cursor\", input.cursor);\n\n const { body: wire, rateLimit } = await this.get<{\n permits?: PermitRecord[];\n total?: number;\n next_cursor?: string;\n }>(\"/v1/permits\", params);\n\n if (!Array.isArray(wire.permits)) {\n throw new AtlaSentError(\n \"Malformed response from /v1/permits: missing `permits` array\",\n { code: \"bad_response\" },\n );\n }\n const result: ListPermitsResponse = {\n permits: wire.permits,\n total: typeof wire.total === \"number\" ? wire.total : wire.permits.length,\n rateLimit,\n };\n if (wire.next_cursor !== undefined) result.nextCursor = wire.next_cursor;\n return result;\n }\n\n /**\n * Self-introspection: ask the server to describe the API key this\n * client was constructed with. Returns the key's ID, organization,\n * environment, scopes, IP allowlist, per-minute rate limit, the\n * client IP the server observed, and the expiry (if any).\n *\n * Never includes the raw key or its hash. Safe to surface in operator\n * dashboards. Useful for `IP_NOT_ALLOWED` debugging (the server tells\n * you exactly which IP it saw) and for proactive expiry warnings.\n *\n * Throws {@link AtlaSentError} on transport / auth failures — same\n * taxonomy as {@link AtlaSentClient.evaluate}.\n */\n async keySelf(): Promise<ApiKeySelfResponse> {\n const { body: wire, rateLimit } =\n await this.get<ApiKeySelfWire>(\"/v1-api-key-self\");\n\n if (\n typeof wire.key_id !== \"string\" ||\n typeof wire.org_id !== \"string\"\n ) {\n throw new AtlaSentError(\n \"Malformed response from /v1-api-key-self: missing `key_id` or `org_id`\",\n { code: \"bad_response\" },\n );\n }\n\n return {\n keyId: wire.key_id,\n orgId: wire.org_id,\n environment: wire.environment,\n scopes: wire.scopes ?? [],\n allowedCidrs: wire.allowed_cidrs ?? null,\n rateLimitPerMinute: wire.rate_limit_per_minute,\n clientIp: wire.client_ip ?? null,\n expiresAt: wire.expires_at ?? null,\n rateLimit,\n };\n }\n\n /**\n * List persisted audit events for the authenticated organization\n * (`GET /v1-audit/events`). Returned rows are wire-identical with\n * the server: snake_case field names, including `previous_hash` and\n * the `hash` chain, so the response can be fed straight into the\n * offline verifier when paired with a signed export.\n *\n * `query.types` is a comma-joined list (e.g.\n * `\"evaluate.allow,policy.updated\"`). `cursor` is the opaque\n * `next_cursor` from the prior page. All fields are optional; the\n * server defaults `limit` to 50 (capped at 500).\n *\n * Throws {@link AtlaSentError} on transport / auth failures — same\n * taxonomy as {@link AtlaSentClient.evaluate}.\n */\n async listAuditEvents(\n query: AuditEventsQuery = {},\n ): Promise<AuditEventsResult> {\n const { body: wire, rateLimit } = await this.get<AuditEventsPage>(\n \"/v1-audit/events\",\n buildAuditEventsQuery(query),\n );\n\n if (!Array.isArray(wire.events) || typeof wire.total !== \"number\") {\n throw new AtlaSentError(\n \"Malformed response from /v1-audit/events: missing `events` or `total`\",\n { code: \"bad_response\" },\n );\n }\n\n return { ...wire, rateLimit };\n }\n\n /**\n * Request a signed audit export bundle\n * (`POST /v1-audit/exports`). The returned object is wire-identical\n * with the server — `signature`, `chain_head_hash`, `events`, and\n * friends survive untouched so the bundle can be persisted to disk\n * and handed to the offline verifier (`verifyBundle` /\n * `verifyAuditBundle`) without any reshaping.\n *\n * Pass `filter.types`, `filter.from`, `filter.to`, or `filter.actor_id`\n * to narrow the export; omit for a full-org bundle. `rateLimit` is\n * attached alongside the wire fields for observability.\n *\n * Throws {@link AtlaSentError} on transport / auth failures — same\n * taxonomy as {@link AtlaSentClient.evaluate}.\n */\n async createAuditExport(\n filter: AuditExportRequest = {},\n ): Promise<AuditExportResult> {\n const { body: wire, rateLimit } = await this.post<AuditExport>(\n \"/v1-audit/exports\",\n filter,\n );\n\n if (\n typeof wire.export_id !== \"string\" ||\n typeof wire.chain_head_hash !== \"string\" ||\n !Array.isArray(wire.events)\n ) {\n throw new AtlaSentError(\n \"Malformed response from /v1-audit/exports: missing `export_id`, `chain_head_hash`, or `events`\",\n { code: \"bad_response\" },\n );\n }\n\n return { ...wire, rateLimit };\n }\n\n /**\n * Re-evaluate a recorded decision against its originally-pinned policy\n * bundle and engine version, and report whether the result agrees with\n * what was recorded.\n *\n * Wraps `POST /v1-decisions-replay/:id/replay`. **Side-effect-free** — no\n * audit chain row is written and no permit is issued (per ADR-016).\n * Useful for compliance review, regression testing of bundle changes,\n * and post-incident investigation.\n *\n * Outcomes encoded in the response:\n * - `variance: \"NONE\"` — replay agrees with the original decision.\n * - `variance: \"DECISION_CHANGED\"` — same envelope, same bundle, different\n * decision. Almost always indicates non-determinism in a rule\n * (e.g. wall-clock comparison) and warrants investigation.\n * - `variance: \"ENVELOPE_DRIFT\"` — the recorded request envelope no longer\n * hashes to the recorded value. The replay short-circuits without\n * running the engine; `replay_decision` is absent. Treat as evidence\n * of substrate tamper or a recorder bug.\n *\n * Server-side 409 responses (replay refused because the engine version\n * does not accept replay, or because no bundle was pinned) surface as\n * `AtlaSentError` with `code: \"replay_not_eligible\"` — callers should\n * treat them as expected for old / un-pinned decisions, not as bugs.\n *\n * Requires the `evaluate:write` API key scope.\n *\n * @param decisionId The UUID of the recorded decision to replay.\n * Matches `execution_evaluations.request_id`.\n *\n * @example\n * ```ts\n * const result = await client.replayDecision(\"dec_abc123\");\n * if (result.variance === \"DECISION_CHANGED\") {\n * console.warn(\n * `Decision ${result.decision_id} changed on replay: ` +\n * `${result.original_decision} → ${result.replay_decision}`,\n * );\n * }\n * ```\n */\n async replayDecision(\n decisionId: string,\n ): Promise<ReplayDecisionResponse & { rateLimit: RateLimitState | null }> {\n if (typeof decisionId !== \"string\" || decisionId.length === 0) {\n throw new AtlaSentError(\"decisionId is required\", {\n code: \"bad_request\",\n });\n }\n\n const path = `/v1-decisions-replay/${encodeURIComponent(decisionId)}/replay`;\n const { body: wire, rateLimit } = await this.post<ReplayDecisionResponse>(\n path,\n {},\n );\n\n // Defensive validation. The replay endpoint is alpha (see\n // STABLE_V2_PROMOTION.md) — wire shapes can shift without a\n // deprecation cycle, so guard the contract fields callers will\n // branch on rather than trusting the cast.\n if (\n typeof wire.decision_id !== \"string\" ||\n typeof wire.original_decision !== \"string\" ||\n typeof wire.engine_version_kind !== \"string\" ||\n typeof wire.accepts_replay !== \"boolean\" ||\n typeof wire.variance !== \"string\" ||\n typeof wire.envelope_verification !== \"string\" ||\n typeof wire.replayed_at !== \"string\"\n ) {\n throw new AtlaSentError(\n \"Malformed response from /v1-decisions-replay/:id/replay: missing required fields\",\n { code: \"bad_response\" },\n );\n }\n\n return { ...wire, rateLimit };\n }\n\n /**\n * ADR-015 Phase C — SDK-canonical replay runtime.\n *\n * Re-evaluates a recorded decision against its originally-pinned policy\n * bundle and engine version via `POST /v1/decisions/:id/replay`.\n * Side-effect-free server-side: no audit chain row is written and no\n * permit is issued (ADR-016 `mode: \"replay\"` sentinel).\n *\n * Differences from {@link replayDecision} (the 2.7.0 raw-wire surface):\n *\n * | | `replayDecision()` | `replay()` |\n * | --- | --- | --- |\n * | Path | `/v1-decisions-replay/:id/replay` | `/v1/decisions/:id/replay` |\n * | Variance | raw wire (`DECISION_CHANGED`) | SDK-canonical (`POLICY_DRIFT`) |\n * | 409 handling | throws `AtlaSentError` | returns `ENGINE_DRIFT` / `BUNDLE_MISSING` |\n * | Input shape | `decisionId: string` | `{ evaluationId }` |\n *\n * **Never throws on `409 replay_not_eligible`** — instead returns a\n * `ReplayResponse` with `varianceKind: \"ENGINE_DRIFT\"` (engine retired\n * beyond archival window) or `\"BUNDLE_MISSING\"` (no bundle pinned on\n * the original evaluation). Callers can always `switch` on\n * `result.varianceKind` without a try/catch.\n *\n * Fix-forward note: this method was originally landed in PR #275 but\n * dropped from the squash merge. The TS types (`ReplayResponse`,\n * `ReplayRequest`) and CHANGELOG made it through; the method itself\n * did not. Restored here to match the Python {@link\n * AtlaSentClient}.replay() that landed in atlasent-sdk@2.6.0 (Python).\n */\n async replay(input: ReplayRequest): Promise<ReplayResponse> {\n if (!input || typeof input.evaluationId !== \"string\" || input.evaluationId.length === 0) {\n throw new AtlaSentError(\"evaluationId is required\", {\n code: \"bad_request\",\n });\n }\n\n const path = `/v1/decisions/${encodeURIComponent(input.evaluationId)}/replay`;\n let wire: Record<string, unknown>;\n let rateLimit: RateLimitState | null;\n try {\n const result = await this.post<Record<string, unknown>>(path, {});\n wire = result.body;\n rateLimit = result.rateLimit;\n } catch (err) {\n if (err instanceof AtlaSentError && err.status === 409) {\n const msg = (err.message ?? \"\").toLowerCase();\n const varianceKind: ReplayVarianceKind = msg.includes(\"bundle\")\n ? \"BUNDLE_MISSING\"\n : \"ENGINE_DRIFT\";\n return {\n decisionId: input.evaluationId,\n varianceKind,\n originalDecision: \"deny\",\n acceptsReplay: false,\n replayedAt: new Date().toISOString(),\n rateLimit: null,\n };\n }\n throw err;\n }\n\n // Map raw wire variance → SDK-canonical. Unknown values default to\n // NONE per the additive-contract policy (the SDK never breaks on a\n // forward-introduced wire kind).\n const VARIANCE_MAP: Record<string, ReplayVarianceKind> = {\n NONE: \"NONE\",\n DECISION_CHANGED: \"POLICY_DRIFT\",\n ENVELOPE_DRIFT: \"ENVELOPE_DRIFT\",\n CHAIN_TAMPER: \"CHAIN_TAMPER\",\n BUNDLE_MISSING: \"BUNDLE_MISSING\",\n ENGINE_DRIFT: \"ENGINE_DRIFT\",\n };\n const rawVariance = typeof wire.variance === \"string\" ? wire.variance : \"\";\n const varianceKind: ReplayVarianceKind = VARIANCE_MAP[rawVariance] ?? \"NONE\";\n\n const replayDec = typeof wire.replay_decision === \"string\"\n ? (wire.replay_decision.toLowerCase() as DecisionCanonical)\n : undefined;\n const originalDec = (\n typeof wire.original_decision === \"string\"\n ? wire.original_decision.toLowerCase()\n : \"deny\"\n ) as DecisionCanonical;\n\n const response: ReplayResponse = {\n decisionId: typeof wire.decision_id === \"string\" ? wire.decision_id : input.evaluationId,\n varianceKind,\n originalDecision: originalDec,\n acceptsReplay: typeof wire.accepts_replay === \"boolean\" ? wire.accepts_replay : true,\n replayedAt: typeof wire.replayed_at === \"string\" ? wire.replayed_at : new Date().toISOString(),\n rateLimit,\n };\n if (typeof wire.original_deny_code === \"string\") response.originalDenyCode = wire.original_deny_code;\n if (replayDec !== undefined) response.replayedDecision = replayDec;\n if (typeof wire.replay_deny_code === \"string\") response.replayedDenyCode = wire.replay_deny_code;\n if (typeof wire.engine_version === \"string\") response.engineVersion = wire.engine_version;\n if (typeof wire.engine_version_kind === \"string\") response.engineVersionKind = wire.engine_version_kind;\n if (typeof wire.envelope_verification === \"string\") response.envelopeVerification = wire.envelope_verification;\n return response;\n }\n\n /**\n * Open a streaming evaluation session against `POST /v1/evaluate/stream`\n * (with fallback to `POST /v1-evaluate-stream` on older runtimes).\n *\n * Yields {@link StreamDecisionEvent} and {@link StreamProgressEvent} objects\n * as the server emits them. The iterator ends cleanly when the server sends\n * `event: done`; it throws {@link AtlaSentError} on transport errors or when\n * the server sends `event: error`.\n *\n * The final {@link StreamDecisionEvent} (isFinal: true) carries a `permitId`\n * suitable for passing to {@link verifyPermit} after the stream closes.\n *\n * Hardening:\n * - Throws {@link StreamTimeoutError} when no event arrives within\n * `opts.timeoutMs` (default 30 s). Pass `0` to disable.\n * - Retries up to `opts.maxRetries` times (default 3) with 1 s / 2 s / 4 s\n * delays on network drop (before a terminal event). Sends `Last-Event-ID`\n * on reconnect when the server has emitted event IDs.\n * - Throws {@link StreamParseError} on partial / malformed JSON rather than\n * crashing with a raw `SyntaxError`.\n * - Closes cleanly on `event: done` or a decision event with `done: true`.\n *\n * ```ts\n * for await (const event of client.protectStream({ agent, action })) {\n * if (event.type === \"decision\" && event.isFinal) {\n * await client.verifyPermit({ permitId: event.permitId });\n * }\n * }\n * ```\n */\n async *protectStream(\n input: EvaluateRequest,\n opts: StreamOptions = {},\n ): AsyncIterable<StreamEvent> {\n const streamTimeoutMs = opts.timeoutMs ?? 30_000;\n const maxRetries = opts.maxRetries ?? 3;\n\n const body = {\n action: input.action,\n agent: input.agent,\n context: input.context ?? {},\n api_key: this.apiKey,\n };\n\n const requestId = globalThis.crypto.randomUUID();\n let streamPath = V1_EVALUATE_STREAM_PATH;\n\n let lastEventId: string | undefined;\n let retryCount = 0;\n\n while (true) {\n const headers: Record<string, string> = {\n Accept: \"text/event-stream\",\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n \"User-Agent\": this.userAgent,\n // ADR-025: wire-protocol version declared on every request.\n \"X-AtlaSent-Protocol-Version\": \"1\",\n \"X-Request-ID\": requestId,\n };\n if (lastEventId !== undefined) {\n headers[\"Last-Event-ID\"] = lastEventId;\n }\n\n const connectionTimeoutSignal = AbortSignal.timeout(this.timeoutMs);\n const signal = opts.signal\n ? (\n AbortSignal as unknown as { any(s: AbortSignal[]): AbortSignal }\n ).any([connectionTimeoutSignal, opts.signal])\n : connectionTimeoutSignal;\n\n let response: Response;\n try {\n response = await this.fetchImpl(`${this.baseUrl}${streamPath}`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal,\n });\n } catch (err) {\n const mapped = mapFetchError(err, requestId);\n if (mapped.code === \"network\" && retryCount < maxRetries) {\n retryCount++;\n await sleep(1_000 * Math.pow(2, retryCount - 1)); // 1s, 2s, 4s\n continue;\n }\n throw mapped;\n }\n\n if (!response.ok) {\n if (\n streamPath === V1_EVALUATE_STREAM_PATH &&\n (response.status === 404 || response.status === 405)\n ) {\n streamPath = V1_EVALUATE_STREAM_LEGACY_PATH;\n continue;\n }\n throw await buildHttpError(response, requestId);\n }\n\n if (!response.body) {\n throw new AtlaSentError(\"Expected streaming body from AtlaSent API\", {\n code: \"bad_response\",\n status: response.status,\n requestId,\n });\n }\n\n let streamDone = false;\n let networkDrop = false;\n\n try {\n for await (const event of parseSseStream(\n response.body,\n requestId,\n streamTimeoutMs,\n (id) => {\n lastEventId = id;\n },\n )) {\n yield event;\n if (event.type === \"decision\" && event.isFinal) {\n streamDone = true;\n }\n }\n // parseSseStream returned normally (saw event: done or stream ended)\n streamDone = true;\n } catch (err) {\n if (err instanceof AtlaSentError && err.code === \"network\") {\n networkDrop = true;\n } else {\n throw err;\n }\n }\n\n if (streamDone) break;\n\n // Network drop before terminal event — attempt reconnect\n if (networkDrop && retryCount < maxRetries) {\n retryCount++;\n await sleep(1_000 * Math.pow(2, retryCount - 1)); // 1s, 2s, 4s\n continue;\n }\n if (networkDrop) {\n throw new AtlaSentError(\n `AtlaSent stream dropped after ${retryCount} reconnection attempts`,\n { code: \"network\", requestId },\n );\n }\n break;\n }\n }\n\n // ── License verification (self-hosted / air-gapped) ──────────────────────\n\n /**\n * Retrieve the license status of this self-hosted or air-gapped deployment.\n *\n * Calls `GET /v1/license`. Returns the current validity state, expiry,\n * enabled feature flags, and optional capacity limits for the installed\n * license key.\n *\n * Callers should check `result.status === \"active\"` before proceeding.\n * A `\"grace\"` status means the license has lapsed but a grace window\n * (`grace_until`) is still open — the deployment continues to function\n * but the license should be renewed immediately.\n *\n * Throws {@link AtlaSentError} on transport / auth failures.\n */\n async getLicense(): Promise<LicenseStatus & { rateLimit: RateLimitState | null }> {\n const { body, rateLimit } = await this.get<LicenseStatus>(\"/v1/license\");\n return { ...body, rateLimit };\n }\n\n /**\n * Validate a signed license blob against this deployment's installed\n * public key.\n *\n * Calls `POST /v1/license/verify`. Use this when onboarding a new license\n * key or rotating an expiring one — submit the blob received from AtlaSent\n * and check `result.valid` before applying the new license.\n *\n * A `valid: false` response is **not** thrown — inspect the returned\n * object. Only transport / server errors throw {@link AtlaSentError}.\n *\n * @param blob — The signed license blob string provided by AtlaSent.\n */\n async verifyLicense(\n blob: string,\n ): Promise<LicenseVerifyResult & { rateLimit: RateLimitState | null }> {\n if (!blob || typeof blob !== \"string\") {\n throw new AtlaSentError(\"blob is required\", { code: \"bad_request\" });\n }\n const { body, rateLimit } = await this.post<LicenseVerifyResult>(\n \"/v1/license/verify\",\n { blob },\n );\n return { ...body, rateLimit };\n }\n\n private async post<T>(\n path: string,\n body: unknown,\n query?: URLSearchParams,\n ): Promise<{ body: T; rateLimit: RateLimitState | null }> {\n return this.request<T>(path, \"POST\", body, query);\n }\n\n private async postWithPathFallback<T>(\n primaryPath: string,\n fallbackPath: string,\n body: unknown,\n query?: URLSearchParams,\n ): Promise<{ body: T; rateLimit: RateLimitState | null }> {\n try {\n return await this.post<T>(primaryPath, body, query);\n } catch (err) {\n if (\n err instanceof AtlaSentError &&\n (err.status === 404 || err.status === 405)\n ) {\n return this.post<T>(fallbackPath, body, query);\n }\n throw err;\n }\n }\n\n private async get<T>(\n path: string,\n query?: URLSearchParams,\n ): Promise<{ body: T; rateLimit: RateLimitState | null }> {\n return this.request<T>(path, \"GET\", undefined, query);\n }\n\n private async request<T>(\n path: string,\n method: \"GET\" | \"POST\",\n body: unknown,\n query: URLSearchParams | undefined,\n ): Promise<{ body: T; rateLimit: RateLimitState | null }> {\n const qs =\n query && Array.from(query).length > 0 ? `?${query.toString()}` : \"\";\n const url = `${this.baseUrl}${path}${qs}`;\n const requestId = globalThis.crypto.randomUUID();\n\n /**\n * Canonical auth header. The API also accepts X-AtlaSent-Key for legacy\n * compatibility but that path is deprecated and will be removed in a future\n * version. Always use Authorization: Bearer <api_key>.\n */\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n \"User-Agent\": this.userAgent,\n \"X-Request-ID\": requestId,\n // ADR-025: wire-protocol version declared on every request.\n \"X-AtlaSent-Protocol-Version\": \"1\",\n };\n if (method === \"POST\") headers[\"Content-Type\"] = \"application/json\";\n\n const bodyStr = method === \"POST\" ? JSON.stringify(body) : undefined;\n\n for (let attempt = 0; ; attempt++) {\n const init: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(this.timeoutMs),\n };\n if (bodyStr !== undefined) init.body = bodyStr;\n\n let response: Response;\n try {\n response = await this.fetchImpl(url, init);\n } catch (err) {\n const mapped = mapFetchError(err, requestId);\n if (isRetryable(mapped) && hasAttemptsLeft(attempt, this.retryPolicy)) {\n await sleep(computeBackoffMs(attempt, this.retryPolicy, mapped));\n continue;\n }\n throw mapped;\n }\n\n if (!response.ok) {\n const httpErr = await buildHttpError(response, requestId);\n if (\n isRetryable(httpErr) &&\n hasAttemptsLeft(attempt, this.retryPolicy)\n ) {\n await sleep(computeBackoffMs(attempt, this.retryPolicy, httpErr));\n continue;\n }\n throw httpErr;\n }\n\n let parsed: unknown;\n try {\n parsed = await response.json();\n } catch (err) {\n const jsonErr = new AtlaSentError(\n \"Invalid JSON response from AtlaSent API\",\n {\n code: \"bad_response\",\n status: response.status,\n requestId,\n cause: err,\n },\n );\n if (\n isRetryable(jsonErr) &&\n hasAttemptsLeft(attempt, this.retryPolicy)\n ) {\n await sleep(computeBackoffMs(attempt, this.retryPolicy, jsonErr));\n continue;\n }\n throw jsonErr;\n }\n\n if (parsed === null || typeof parsed !== \"object\") {\n const shapeErr = new AtlaSentError(\n \"Expected a JSON object from AtlaSent API\",\n {\n code: \"bad_response\",\n status: response.status,\n requestId,\n },\n );\n if (\n isRetryable(shapeErr) &&\n hasAttemptsLeft(attempt, this.retryPolicy)\n ) {\n await sleep(computeBackoffMs(attempt, this.retryPolicy, shapeErr));\n continue;\n }\n throw shapeErr;\n }\n\n return {\n body: parsed as T,\n rateLimit: parseRateLimitHeaders(response.headers),\n };\n }\n }\n\n /**\n * Open a new HITL escalation. Bridges a `hold` outcome from\n * `protect()` to the approval queue: an agent that receives a\n * `hold` decision calls this to enroll the proposed action for\n * human review. The returned escalation can then be polled with\n * `getHitlEscalation()` or driven to terminal by\n * `approveHitlEscalation()` / `rejectHitlEscalation()`.\n *\n * Quorum, pool size, fallback decision and routing inherit from\n * the server-side policy when omitted from `input`.\n *\n * Calls `POST /v1/hitl`.\n */\n async createHitlEscalation(\n input: HitlCreateRequest,\n ): Promise<{ escalation: HitlEscalation; rateLimit: RateLimitState | null }> {\n const { body, rateLimit } = await this.post<HitlEscalation>(\n \"/v1/hitl\",\n input,\n );\n return { escalation: body, rateLimit };\n }\n\n /**\n * List HITL escalations for the calling org. Defaults to\n * `status=pending`; pass `status` to query other queues\n * (`escalated`, `approved`, `rejected`, `auto_approved`,\n * `timed_out`).\n *\n * Calls `GET /v1/hitl`.\n */\n async listHitlEscalations(input: ListHitlEscalationsRequest = {}): Promise<{\n data: ListHitlEscalationsResponse;\n rateLimit: RateLimitState | null;\n }> {\n const params = new URLSearchParams();\n if (input.status) params.set(\"status\", input.status);\n if (input.agentId) params.set(\"agent_id\", input.agentId);\n if (input.assignedToUserId)\n params.set(\"assigned_to_user_id\", input.assignedToUserId);\n if (input.limit !== undefined) params.set(\"limit\", String(input.limit));\n if (input.cursor) params.set(\"cursor\", input.cursor);\n const { body, rateLimit } = await this.get<ListHitlEscalationsResponse>(\n \"/v1/hitl\",\n params,\n );\n return { data: body, rateLimit };\n }\n\n /**\n * Get a HITL escalation. The server payload includes a live\n * `quorum_progress` snapshot when the escalation is still open.\n *\n * Calls `GET /v1/hitl/:id`.\n */\n async getHitlEscalation(\n escalationId: string,\n ): Promise<{ escalation: HitlEscalation; rateLimit: RateLimitState | null }> {\n if (!escalationId) {\n throw new AtlaSentError(\"escalationId is required\", {\n code: \"bad_request\",\n });\n }\n const { body, rateLimit } = await this.get<HitlEscalation>(\n `/v1/hitl/${encodeURIComponent(escalationId)}`,\n );\n return { escalation: body, rateLimit };\n }\n\n /**\n * List per-approver vote rows for an escalation.\n * Calls `GET /v1/hitl/:id/approvals`.\n */\n async listHitlApprovals(escalationId: string): Promise<{\n approvals: HitlApprovalRecord[];\n rateLimit: RateLimitState | null;\n }> {\n const { body, rateLimit } = await this.get<{\n approvals: HitlApprovalRecord[];\n }>(`/v1/hitl/${encodeURIComponent(escalationId)}/approvals`);\n return { approvals: body.approvals ?? [], rateLimit };\n }\n\n /**\n * List the escalation chain hops for an escalation. Each `/escalate`\n * call appends one row.\n * Calls `GET /v1/hitl/:id/chain`.\n */\n async getHitlChain(\n escalationId: string,\n ): Promise<{ chain: HitlChainHop[]; rateLimit: RateLimitState | null }> {\n const { body, rateLimit } = await this.get<{ chain: HitlChainHop[] }>(\n `/v1/hitl/${encodeURIComponent(escalationId)}/chain`,\n );\n return { chain: body.chain ?? [], rateLimit };\n }\n\n /**\n * Record an approve vote. Resolves the escalation only once the\n * server-side quorum count is satisfied; before that the response\n * carries a refreshed escalation row with the latest\n * `quorum_progress`.\n *\n * Calls `POST /v1/hitl/:id/approve`. The server returns 409\n * `duplicate_vote` if the same principal has already voted, and\n * 409 `already_rejected` if a concurrent reject crossed the line.\n */\n async approveHitlEscalation(\n escalationId: string,\n input: HitlApproveRequest = {},\n ): Promise<{ escalation: HitlEscalation; rateLimit: RateLimitState | null }> {\n const { body, rateLimit } = await this.post<HitlEscalation>(\n `/v1/hitl/${encodeURIComponent(escalationId)}/approve`,\n input,\n );\n return { escalation: body, rateLimit };\n }\n\n /**\n * Record a reject vote. Reject is short-circuit terminal — a single\n * reject closes the escalation regardless of how many approves have\n * accumulated.\n *\n * Calls `POST /v1/hitl/:id/reject`.\n */\n async rejectHitlEscalation(\n escalationId: string,\n input: HitlRejectRequest = {},\n ): Promise<{ escalation: HitlEscalation; rateLimit: RateLimitState | null }> {\n const { body, rateLimit } = await this.post<HitlEscalation>(\n `/v1/hitl/${encodeURIComponent(escalationId)}/reject`,\n input,\n );\n return { escalation: body, rateLimit };\n }\n\n /**\n * Re-route an open escalation to a higher tier. Bounded by the\n * escalation's `max_escalation_depth` — the server returns 409\n * `chain_exhausted` and applies the configured fallback decision\n * once the ceiling is hit.\n *\n * Calls `POST /v1/hitl/:id/escalate`.\n */\n async escalateHitlEscalation(\n escalationId: string,\n input: HitlEscalateRequest,\n ): Promise<{ escalation: HitlEscalation; rateLimit: RateLimitState | null }> {\n const { body, rateLimit } = await this.post<HitlEscalation>(\n `/v1/hitl/${encodeURIComponent(escalationId)}/escalate`,\n input,\n );\n return { escalation: body, rateLimit };\n }\n\n /**\n * Manually apply the escalation's `fallback_decision`. Useful for\n * admin recovery of a hung escalation when the cron sweeper hasn't\n * run yet, or to short-circuit a stuck flow during incident\n * response.\n *\n * Calls `POST /v1/hitl/:id/timeout`.\n */\n async timeoutHitlEscalation(\n escalationId: string,\n ): Promise<{ escalation: HitlEscalation; rateLimit: RateLimitState | null }> {\n const { body, rateLimit } = await this.post<HitlEscalation>(\n `/v1/hitl/${encodeURIComponent(escalationId)}/timeout`,\n {},\n );\n return { escalation: body, rateLimit };\n }\n\n /**\n * Run a named governance graph traversal query.\n *\n * Dispatches to `GET /v1/governance/graph/query?type=<queryType>`.\n * Each query type returns a different row shape — the return type\n * narrows automatically based on the literal `queryType` argument.\n *\n * `\"user_approvals\"` requires `params.actor_id` — the server returns\n * a 400 if it is absent.\n */\n async queryGovernanceGraph<T extends GovernanceGraphQueryType>(\n queryType: T,\n params: GovernanceGraphQueryParams = {},\n ): Promise<GovernanceGraphQueryResponse<T>> {\n const qs = new URLSearchParams({ type: queryType });\n if (params.actor_id) qs.set(\"actor_id\", params.actor_id);\n const { body, rateLimit } = await this.get<{\n query_type: T;\n results: GovernanceGraphResultRow<T>[];\n org_id: string;\n }>(\"/v1/governance/graph/query\", qs);\n return { ...body, rateLimit };\n }\n\n /**\n * Reconstruct the multi-system execution timeline for a specific incident.\n *\n * Calls `GET /v1/governance/timeline/incident/{incidentId}`. Backed\n * server-side by `reconstruct_incident_chains_v2()`, which fixes the\n * `executor_id → actor_id` bug that silently produced empty timelines\n * in the original function.\n *\n * Returns full execution rows including the §13.1 columns\n * (`delegation_chain_id`, `replay_of_execution_id`, `incident_id`,\n * `policy_version_id`, `bundle_version_id`) alongside the actor\n * timeline and evidence rows.\n */\n async getIncidentTimeline(\n incidentId: string,\n ): Promise<IncidentTimelineResponse> {\n if (!incidentId) {\n throw new AtlaSentError(\"incidentId is required\", {\n code: \"bad_request\",\n });\n }\n const { body, rateLimit } = await this.get<\n Omit<IncidentTimelineResponse, \"rateLimit\">\n >(`/v1/governance/timeline/incident/${encodeURIComponent(incidentId)}`);\n return { ...body, rateLimit };\n }\n\n // ── Connector Management ─────────────────────────────────────────────────\n\n /**\n * List connectors registered for the calling org.\n * Calls `GET /v1/governance/connectors`.\n */\n async listConnectors(\n options: { cursor?: string; limit?: number } = {},\n ): Promise<ListConnectorsResponse> {\n const params = new URLSearchParams();\n if (options.cursor) params.set(\"cursor\", options.cursor);\n if (options.limit !== undefined) params.set(\"limit\", String(options.limit));\n const { body, rateLimit } = await this.get<{\n connectors: ListConnectorsResponse[\"connectors\"];\n total: number;\n next_cursor?: string;\n }>(\"/v1/governance/connectors\", params);\n const result: ListConnectorsResponse = {\n connectors: body.connectors ?? [],\n total: body.total,\n rateLimit,\n };\n if (body.next_cursor) result.nextCursor = body.next_cursor;\n return result;\n }\n\n /**\n * Register and install a new connector for the calling org.\n * Calls `POST /v1/governance/connectors`.\n */\n async installConnector(\n input: InstallConnectorInput,\n ): Promise<InstallConnectorResponse> {\n const { body, rateLimit } = await this.post<\n InstallConnectorResponse[\"connector\"]\n >(\"/v1/governance/connectors\", input);\n return { connector: body, rateLimit };\n }\n\n /**\n * Store encrypted credentials for a connector.\n * Calls `POST /v1/governance/connectors/{id}/authenticate`.\n */\n async authenticateConnector(\n connectorId: string,\n input: AuthenticateConnectorInput,\n ): Promise<AuthenticateConnectorResponse> {\n if (!connectorId) {\n throw new AtlaSentError(\"connectorId is required\", {\n code: \"bad_request\",\n });\n }\n const { body, rateLimit } = await this.post<{\n credential_id: string;\n version: number;\n }>(\n `/v1/governance/connectors/${encodeURIComponent(connectorId)}/authenticate`,\n input,\n );\n return {\n credential_id: body.credential_id,\n version: body.version,\n rateLimit,\n };\n }\n\n /**\n * Trigger an incremental sync for a connector.\n * Calls `POST /v1/governance/connectors/{id}/sync`.\n */\n async syncConnector(connectorId: string): Promise<SyncConnectorResponse> {\n if (!connectorId) {\n throw new AtlaSentError(\"connectorId is required\", {\n code: \"bad_request\",\n });\n }\n const { body, rateLimit } = await this.post<{\n connector_id: string;\n status: SyncConnectorResponse[\"status\"];\n sync_started_at: string;\n }>(`/v1/governance/connectors/${encodeURIComponent(connectorId)}/sync`, {});\n return { ...body, rateLimit };\n }\n\n /**\n * Revoke a connector and all its associated credentials.\n * Calls `POST /v1/governance/connectors/{id}/revoke`.\n */\n async revokeConnector(\n connectorId: string,\n reason?: string,\n ): Promise<RevokeConnectorResponse> {\n if (!connectorId) {\n throw new AtlaSentError(\"connectorId is required\", {\n code: \"bad_request\",\n });\n }\n const body: { reason?: string } = {};\n if (reason !== undefined) body.reason = reason;\n const { body: wire, rateLimit } = await this.post<{\n connector_id: string;\n revoked_at: string;\n }>(\n `/v1/governance/connectors/${encodeURIComponent(connectorId)}/revoke`,\n body,\n );\n return { ...wire, rateLimit };\n }\n\n /**\n * Rotate the credentials for a connector.\n * Calls `POST /v1/governance/connectors/{id}/rotate-credentials`.\n */\n async rotateConnectorCredentials(\n connectorId: string,\n ): Promise<RotateCredentialsResponse> {\n if (!connectorId) {\n throw new AtlaSentError(\"connectorId is required\", {\n code: \"bad_request\",\n });\n }\n const { body, rateLimit } = await this.post<{\n connector_id: string;\n new_version: number;\n rotated_at: string;\n }>(\n `/v1/governance/connectors/${encodeURIComponent(connectorId)}/rotate-credentials`,\n {},\n );\n return { ...body, rateLimit };\n }\n\n /**\n * List enforcement policies for the calling org, optionally filtered by connector type.\n * Calls `GET /v1/governance/enforcement-policies`.\n */\n async listEnforcementPolicies(\n connectorType?: ConnectorType,\n ): Promise<ListEnforcementPoliciesResponse> {\n const params = new URLSearchParams();\n if (connectorType) params.set(\"connector_type\", connectorType);\n const { body, rateLimit } = await this.get<{\n policies: ListEnforcementPoliciesResponse[\"policies\"];\n total: number;\n }>(\"/v1/governance/enforcement-policies\", params);\n return { policies: body.policies ?? [], total: body.total, rateLimit };\n }\n\n /**\n * Create or update a connector enforcement policy.\n * Calls `POST /v1/governance/enforcement-policies`.\n */\n async upsertEnforcementPolicy(\n input: UpsertEnforcementPolicyInput,\n ): Promise<UpsertEnforcementPolicyResponse> {\n const { body, rateLimit } = await this.post<\n UpsertEnforcementPolicyResponse[\"policy\"]\n >(\"/v1/governance/enforcement-policies\", input);\n return { policy: body, rateLimit };\n }\n\n // ── Organizational Risk Graph ─────────────────────────────────────────────\n\n /**\n * Trigger a fresh org-level risk score computation.\n * Calls `POST /v1/governance/risk/compute`.\n */\n async computeOrgRisk(\n options: ComputeOrgRiskOptions = {},\n ): Promise<ComputeOrgRiskResponse> {\n const { body, rateLimit } = await this.post<\n ComputeOrgRiskResponse[\"score\"]\n >(\"/v1/governance/risk/compute\", options);\n return { score: body, rateLimit };\n }\n\n /**\n * Retrieve the most recently computed risk score for the calling org.\n * Calls `GET /v1/governance/risk/latest`.\n */\n async getLatestOrgRisk(): Promise<GetLatestOrgRiskResponse> {\n const { body, rateLimit } = await this.get<{\n score: GetLatestOrgRiskResponse[\"score\"];\n }>(\"/v1/governance/risk/latest\");\n return { score: body.score ?? null, rateLimit };\n }\n\n /**\n * Page through historical org risk scores, most-recent first.\n * Calls `GET /v1/governance/risk/history`.\n */\n async listOrgRiskHistory(\n options: { cursor?: string; limit?: number } = {},\n ): Promise<ListOrgRiskHistoryResponse> {\n const params = new URLSearchParams();\n if (options.cursor) params.set(\"cursor\", options.cursor);\n if (options.limit !== undefined) params.set(\"limit\", String(options.limit));\n const { body, rateLimit } = await this.get<{\n scores: ListOrgRiskHistoryResponse[\"scores\"];\n total: number;\n next_cursor?: string;\n }>(\"/v1/governance/risk/history\", params);\n const result: ListOrgRiskHistoryResponse = {\n scores: body.scores ?? [],\n total: body.total,\n rateLimit,\n };\n if (body.next_cursor) result.nextCursor = body.next_cursor;\n return result;\n }\n // ── Cross-Org Permission Negotiation ──────────────────────────────────────\n\n async checkCrossOrgPermission(\n req: CrossOrgPermissionCheckRequest,\n ): Promise<CrossOrgPermissionCheckResult> {\n const { body } = await this.post<CrossOrgPermissionCheckResult>(\n \"/v1/cross-org/permissions/check\",\n req,\n );\n return body;\n }\n\n async listCrossOrgPermissionChecks(\n params?: CrossOrgPermissionCheckListParams,\n ): Promise<CrossOrgPermissionCheckResult[]> {\n const qs = new URLSearchParams();\n if (params?.source_org_id) qs.set(\"source_org_id\", params.source_org_id);\n if (params?.target_org_id) qs.set(\"target_org_id\", params.target_org_id);\n if (params?.allowed !== undefined)\n qs.set(\"allowed\", String(params.allowed));\n if (params?.limit !== undefined) qs.set(\"limit\", String(params.limit));\n const { body } = await this.get<{\n checks: CrossOrgPermissionCheckResult[];\n }>(\"/v1/cross-org/permissions/checks\", qs);\n return body.checks ?? [];\n }\n\n // ── Anomaly Response Automation ───────────────────────────────────────────\n\n async listAnomalyResponseRules(): Promise<AnomalyResponseRule[]> {\n const { body } = await this.get<{ rules: AnomalyResponseRule[] }>(\n \"/v1/anomaly-response/rules\",\n );\n return body.rules ?? [];\n }\n\n async createAnomalyResponseRule(\n req: CreateAnomalyResponseRuleRequest,\n ): Promise<AnomalyResponseRule> {\n const { body } = await this.post<AnomalyResponseRule>(\n \"/v1/anomaly-response/rules\",\n req,\n );\n return body;\n }\n\n async updateAnomalyResponseRule(\n id: string,\n updates: Partial<CreateAnomalyResponseRuleRequest>,\n ): Promise<AnomalyResponseRule> {\n const { body } = await this.post<AnomalyResponseRule>(\n `/v1/anomaly-response/rules/${encodeURIComponent(id)}/update`,\n updates,\n );\n return body;\n }\n\n async deleteAnomalyResponseRule(id: string): Promise<void> {\n await this.post<Record<string, unknown>>(\n `/v1/anomaly-response/rules/${encodeURIComponent(id)}/delete`,\n {},\n );\n }\n\n async triggerAnomalyResponse(\n req: TriggerAnomalyResponseRequest,\n ): Promise<AnomalyResponseEvent[]> {\n const { body } = await this.post<{ events: AnomalyResponseEvent[] }>(\n \"/v1/anomaly-response/trigger\",\n req,\n );\n return body.events ?? [];\n }\n\n async listAnomalyResponseEvents(params?: {\n limit?: number;\n execution_id?: string;\n }): Promise<AnomalyResponseEvent[]> {\n const qs = new URLSearchParams();\n if (params?.execution_id) qs.set(\"execution_id\", params.execution_id);\n if (params?.limit !== undefined) qs.set(\"limit\", String(params.limit));\n const { body } = await this.get<{ events: AnomalyResponseEvent[] }>(\n \"/v1/anomaly-response/events\",\n qs,\n );\n return body.events ?? [];\n }\n\n // ── Budget Exception Workflows ────────────────────────────────────────────\n\n async listBudgetExceptions(params?: {\n status?: BudgetExceptionStatus;\n budget_policy_id?: string;\n limit?: number;\n offset?: number;\n }): Promise<BudgetExceptionRequest[]> {\n const qs = new URLSearchParams();\n if (params?.status) qs.set(\"status\", params.status);\n if (params?.budget_policy_id)\n qs.set(\"budget_policy_id\", params.budget_policy_id);\n if (params?.limit !== undefined) qs.set(\"limit\", String(params.limit));\n if (params?.offset !== undefined) qs.set(\"offset\", String(params.offset));\n const { body } = await this.get<{ exceptions: BudgetExceptionRequest[] }>(\n \"/v1/budget-exceptions\",\n qs,\n );\n return body.exceptions ?? [];\n }\n\n async getBudgetException(id: string): Promise<BudgetExceptionRequest> {\n const { body } = await this.get<BudgetExceptionRequest>(\n `/v1/budget-exceptions/${encodeURIComponent(id)}`,\n );\n return body;\n }\n\n async createBudgetException(\n req: CreateBudgetExceptionRequest,\n ): Promise<BudgetExceptionRequest> {\n const { body } = await this.post<BudgetExceptionRequest>(\n \"/v1/budget-exceptions\",\n req,\n );\n return body;\n }\n\n async approveBudgetException(\n id: string,\n req: ApproveBudgetExceptionRequest,\n ): Promise<BudgetExceptionRequest> {\n const { body } = await this.post<BudgetExceptionRequest>(\n `/v1/budget-exceptions/${encodeURIComponent(id)}/approve`,\n req,\n );\n return body;\n }\n\n async rejectBudgetException(\n id: string,\n review_notes?: string,\n ): Promise<BudgetExceptionRequest> {\n const { body } = await this.post<BudgetExceptionRequest>(\n `/v1/budget-exceptions/${encodeURIComponent(id)}/reject`,\n { review_notes },\n );\n return body;\n }\n\n async cancelBudgetException(id: string): Promise<BudgetExceptionRequest> {\n const { body } = await this.post<BudgetExceptionRequest>(\n `/v1/budget-exceptions/${encodeURIComponent(id)}/cancel`,\n {},\n );\n return body;\n }\n\n // ── Regulatory Escalation Chain ───────────────────────────────────────────\n\n async listRegulatoryAuthorityLevels(): Promise<RegulatoryAuthorityLevel[]> {\n const { body } = await this.get<{ levels: RegulatoryAuthorityLevel[] }>(\n \"/v1/regulatory/authority-levels\",\n );\n return body.levels ?? [];\n }\n\n async createRegulatoryAuthorityLevel(\n req: Omit<RegulatoryAuthorityLevel, \"id\" | \"org_id\" | \"created_at\">,\n ): Promise<RegulatoryAuthorityLevel> {\n const { body } = await this.post<RegulatoryAuthorityLevel>(\n \"/v1/regulatory/authority-levels\",\n req,\n );\n return body;\n }\n\n async listRegulatoryEscalations(params?: {\n status?: RegulatoryEscalationStatus;\n subject_type?: string;\n subject_id?: string;\n }): Promise<RegulatoryEscalation[]> {\n const qs = new URLSearchParams();\n if (params?.status) qs.set(\"status\", params.status);\n if (params?.subject_type) qs.set(\"subject_type\", params.subject_type);\n if (params?.subject_id) qs.set(\"subject_id\", params.subject_id);\n const { body } = await this.get<{ escalations: RegulatoryEscalation[] }>(\n \"/v1/regulatory/escalations\",\n qs,\n );\n return body.escalations ?? [];\n }\n\n async createRegulatoryEscalation(\n req: CreateRegulatoryEscalationRequest,\n ): Promise<RegulatoryEscalation> {\n const { body } = await this.post<RegulatoryEscalation>(\n \"/v1/regulatory/escalations\",\n req,\n );\n return body;\n }\n\n async acknowledgeRegulatoryEscalation(\n id: string,\n ): Promise<RegulatoryEscalation> {\n const { body } = await this.post<RegulatoryEscalation>(\n `/v1/regulatory/escalations/${encodeURIComponent(id)}/acknowledge`,\n {},\n );\n return body;\n }\n\n async resolveRegulatoryEscalation(\n id: string,\n resolution: string,\n resolution_details?: Record<string, unknown>,\n ): Promise<RegulatoryEscalation> {\n const { body } = await this.post<RegulatoryEscalation>(\n `/v1/regulatory/escalations/${encodeURIComponent(id)}/resolve`,\n { resolution, resolution_details },\n );\n return body;\n }\n\n async overrideRegulatoryEscalation(\n id: string,\n reason: string,\n ): Promise<RegulatoryEscalation> {\n const { body } = await this.post<RegulatoryEscalation>(\n `/v1/regulatory/escalations/${encodeURIComponent(id)}/override`,\n { reason },\n );\n return body;\n }\n\n // ── Incentive Signal Feedback Loop ────────────────────────────────────────\n\n async listSignalActions(\n signal_id: string,\n ): Promise<GovernanceSignalAction[]> {\n const { body } = await this.get<{ actions: GovernanceSignalAction[] }>(\n `/v1/governance/signals/${encodeURIComponent(signal_id)}/actions`,\n );\n return body.actions ?? [];\n }\n\n async recordSignalAction(\n signal_id: string,\n req: RecordSignalActionRequest,\n ): Promise<GovernanceSignalAction> {\n const { body } = await this.post<GovernanceSignalAction>(\n `/v1/governance/signals/${encodeURIComponent(signal_id)}/actions`,\n req,\n );\n return body;\n }\n\n async recordSignalOutcome(\n signal_id: string,\n action_id: string,\n req: RecordSignalOutcomeRequest,\n ): Promise<GovernanceSignalAction> {\n const { body } = await this.post<GovernanceSignalAction>(\n `/v1/governance/signals/${encodeURIComponent(signal_id)}/actions/${encodeURIComponent(action_id)}/outcome`,\n req,\n );\n return body;\n }\n\n async getSignalActionSummary(): Promise<SignalActionSummary> {\n const { body } = await this.get<SignalActionSummary>(\n \"/v1/governance/signals/actions/summary\",\n );\n return body;\n }\n\n // ── Cross-Org Impersonation ───────────────────────────────────────────────\n\n async listImpersonationGrants(): Promise<CrossOrgImpersonationGrant[]> {\n const { body } = await this.get<{ grants: CrossOrgImpersonationGrant[] }>(\n \"/v1/cross-org/impersonation/grants\",\n );\n return body.grants ?? [];\n }\n\n async createImpersonationGrant(\n req: CreateImpersonationGrantRequest,\n ): Promise<CrossOrgImpersonationGrant> {\n const { body } = await this.post<CrossOrgImpersonationGrant>(\n \"/v1/cross-org/impersonation/grants\",\n req,\n );\n return body;\n }\n\n async revokeImpersonationGrant(id: string): Promise<void> {\n await this.post<Record<string, unknown>>(\n `/v1/cross-org/impersonation/grants/${encodeURIComponent(id)}/revoke`,\n {},\n );\n }\n\n async issueImpersonationToken(\n grant_id: string,\n requested_duration_seconds?: number,\n ): Promise<ImpersonationToken> {\n const { body } = await this.post<ImpersonationToken>(\n `/v1/cross-org/impersonation/grants/${encodeURIComponent(grant_id)}/token`,\n { requested_duration_seconds },\n );\n return body;\n }\n\n async validateImpersonationToken(\n token: string,\n ): Promise<ImpersonationValidationResult> {\n const { body } = await this.post<ImpersonationValidationResult>(\n \"/v1/cross-org/impersonation/validate\",\n { token },\n );\n return body;\n }\n\n // ── Constrained governance agents (read surface) ──────────────────────────\n //\n // Three GETs onto the v1-governance-agents edge function. Doctrine:\n // findings produced by these endpoints are advisory signal, never\n // authority. There is no `runGovernanceAgent` method on this client —\n // invocation belongs in CI (atlasent-action `governance-agents` mode),\n // not in application code.\n\n /**\n * List the advisory governance-agent registry for the calling org.\n *\n * Calls `GET /v1/governance/agents`. The registry is reference data\n * seeded at runtime-DB migration time; every row has\n * `authority_class = \"advisory\"` and `can_authorize = false` —\n * structural invariants enforced by the schema, not policy.\n */\n async listGovernanceAgents(): Promise<GovernanceAgent[]> {\n const { body } = await this.get<ListGovernanceAgentsResponse>(\n \"/v1/governance/agents\",\n );\n return [...(body.agents ?? [])];\n }\n\n /**\n * List advisory findings emitted against one governed change.\n *\n * Calls `GET /v1/governance/findings?change_id=…[&agent_slug=…]`.\n * Returns the typed-finding rows in `created_at DESC` order, including\n * `routed_gate_id` when the finding→gate trigger linked them. Findings\n * with `can_authorize === false` (always) are advisory; rendering them\n * never satisfies a gate.\n */\n async listGovernanceFindings(\n query: ListGovernanceFindingsQuery,\n ): Promise<GovernanceAgentFinding[]> {\n if (!query?.change_id) {\n throw new AtlaSentError(\"change_id is required\", { code: \"bad_request\" });\n }\n const params = new URLSearchParams({ change_id: query.change_id });\n if (query.agent_slug) params.set(\"agent_slug\", query.agent_slug);\n const { body } = await this.get<ListGovernanceFindingsResponse>(\n \"/v1/governance/findings\",\n params,\n );\n return [...(body.findings ?? [])];\n }\n\n /**\n * List agent run records against one governed change.\n *\n * Calls `GET /v1/governance/evaluations?change_id=…[&agent_slug=…]`.\n * Returns every persisted evaluation, including `failed` / `timeout`\n * runs and `completed` runs with zero findings — the latter is the\n * positive signal \"the agent ran and found nothing\", which the UI\n * surfaces as `clear`.\n */\n async listGovernanceEvaluations(\n query: ListGovernanceEvaluationsQuery,\n ): Promise<GovernanceAgentEvaluation[]> {\n if (!query?.change_id) {\n throw new AtlaSentError(\"change_id is required\", { code: \"bad_request\" });\n }\n const params = new URLSearchParams({ change_id: query.change_id });\n if (query.agent_slug) params.set(\"agent_slug\", query.agent_slug);\n const { body } = await this.get<ListGovernanceEvaluationsResponse>(\n \"/v1/governance/evaluations\",\n params,\n );\n return [...(body.evaluations ?? [])];\n }\n\n // ── Private adapters for sub-client factories ──────────────────────────────\n // Thin wrappers that expose the private request infrastructure to sub-client\n // factories (scim, evidenceBundles, auth) without widening the public API.\n\n private async _post<T>(\n path: string,\n body: unknown,\n query?: URLSearchParams,\n ): Promise<{ body: T }> {\n const { body: b } = await this.post<T>(path, body, query);\n return { body: b };\n }\n\n private async _get<T>(\n path: string,\n query?: URLSearchParams,\n ): Promise<{ body: T }> {\n const { body: b } = await this.get<T>(path, query);\n return { body: b };\n }\n\n private async _put<T>(path: string, body: unknown): Promise<{ body: T }> {\n return this._requestRaw<T>(path, \"PUT\", body, undefined);\n }\n\n private async _patch<T>(path: string, body: unknown): Promise<{ body: T }> {\n return this._requestRaw<T>(path, \"PATCH\", body, undefined);\n }\n\n private async _delete(path: string): Promise<void> {\n await this._requestRaw<Record<string, unknown>>(path, \"DELETE\", undefined, undefined);\n }\n\n private async _getRaw(path: string): Promise<ArrayBuffer> {\n const url = `${this.baseUrl}${path}`;\n const requestId = globalThis.crypto.randomUUID();\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n \"User-Agent\": this.userAgent,\n \"X-Request-ID\": requestId,\n \"X-AtlaSent-Protocol-Version\": \"1\",\n };\n const response = await this.fetchImpl(url, {\n method: \"GET\",\n headers,\n signal: AbortSignal.timeout(this.timeoutMs),\n });\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new AtlaSentError(`GET ${path} returned ${response.status}`, {\n code: response.status >= 500 ? \"server_error\" : \"bad_request\",\n status: response.status,\n requestId,\n });\n }\n return response.arrayBuffer();\n }\n\n private async _requestRaw<T>(\n path: string,\n method: \"PUT\" | \"PATCH\" | \"DELETE\",\n body: unknown,\n query: URLSearchParams | undefined,\n ): Promise<{ body: T }> {\n const qs =\n query && Array.from(query).length > 0 ? `?${query.toString()}` : \"\";\n const url = `${this.baseUrl}${path}${qs}`;\n const requestId = globalThis.crypto.randomUUID();\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n \"User-Agent\": this.userAgent,\n \"X-Request-ID\": requestId,\n \"X-AtlaSent-Protocol-Version\": \"1\",\n };\n if (method === \"PUT\" && body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n const init: RequestInit = { method, headers, signal: AbortSignal.timeout(this.timeoutMs) };\n if (method === \"PUT\" && body !== undefined) {\n init.body = JSON.stringify(body);\n }\n const response = await this.fetchImpl(url, init);\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new AtlaSentError(`${method} ${path} returned ${response.status}`, {\n code: response.status >= 500 ? \"server_error\" : \"bad_request\",\n status: response.status,\n requestId,\n });\n }\n if (method === \"DELETE\") {\n return { body: {} as T };\n }\n return { body: (await response.json()) as T };\n }\n}\n\n/**\n * Parse the server's `X-RateLimit-*` header triple into a typed\n * {@link RateLimitState}. Returns `null` when any of the three headers\n * is missing or unparseable — callers treat that as \"the server didn't\n * emit rate-limit state\" rather than \"the window is empty\".\n *\n * `X-RateLimit-Reset` is accepted as either unix-seconds (what the\n * AtlaSent edge functions emit today) or an ISO 8601 timestamp.\n */\nfunction parseRateLimitHeaders(headers: Headers): RateLimitState | null {\n const rawLimit = headers.get(\"x-ratelimit-limit\");\n const rawRemaining = headers.get(\"x-ratelimit-remaining\");\n const rawReset = headers.get(\"x-ratelimit-reset\");\n if (rawLimit === null || rawRemaining === null || rawReset === null) {\n return null;\n }\n const limit = Number(rawLimit);\n const remaining = Number(rawRemaining);\n if (!Number.isFinite(limit) || !Number.isFinite(remaining)) {\n return null;\n }\n const resetAt = parseResetHeader(rawReset);\n if (resetAt === null) {\n return null;\n }\n return { limit, remaining, resetAt };\n}\n\nfunction parseResetHeader(raw: string): Date | null {\n const seconds = Number(raw);\n if (Number.isFinite(seconds)) {\n // Standard shape: unix seconds. 10-digit values are in the valid\n // range ~2001–2286 so this heuristic won't confuse a tiny\n // `remaining`-like number for an epoch.\n return new Date(seconds * 1000);\n }\n const ms = Date.parse(raw);\n if (Number.isFinite(ms)) {\n return new Date(ms);\n }\n return null;\n}\n\nfunction mapFetchError(err: unknown, requestId: string): AtlaSentError {\n if (err instanceof AtlaSentError) return err;\n if (err instanceof DOMException && err.name === \"TimeoutError\") {\n return new AtlaSentError(\"Request to AtlaSent API timed out\", {\n code: \"timeout\",\n requestId,\n cause: err,\n });\n }\n if (err instanceof Error && err.name === \"AbortError\") {\n return new AtlaSentError(\"Request to AtlaSent API timed out\", {\n code: \"timeout\",\n requestId,\n cause: err,\n });\n }\n const message = err instanceof Error ? err.message : \"network error\";\n return new AtlaSentError(`Failed to reach AtlaSent API: ${message}`, {\n code: \"network\",\n requestId,\n cause: err,\n });\n}\n\nasync function buildHttpError(\n response: Response,\n requestId: string,\n): Promise<AtlaSentError> {\n const status = response.status;\n const classified = await classifyHttpStatus(response);\n const init: AtlaSentErrorInit = {\n status,\n code: classified.code,\n requestId,\n };\n if (classified.retryAfterMs !== undefined) {\n init.retryAfterMs = classified.retryAfterMs;\n }\n return new AtlaSentError(classified.message, init);\n}\n\nasync function classifyHttpStatus(response: Response): Promise<{\n message: string;\n code: AtlaSentErrorCode;\n retryAfterMs: number | undefined;\n}> {\n const status = response.status;\n const serverMessage = await readServerMessage(response);\n\n if (status === 401) {\n return {\n message: serverMessage ?? \"Invalid API key\",\n code: \"invalid_api_key\",\n retryAfterMs: undefined,\n };\n }\n if (status === 403) {\n return {\n message:\n serverMessage ?? \"Access forbidden — check your API key permissions\",\n code: \"forbidden\",\n retryAfterMs: undefined,\n };\n }\n if (status === 429) {\n return {\n message: serverMessage ?? \"Rate limited by AtlaSent API\",\n code: \"rate_limited\",\n retryAfterMs: parseRetryAfter(response.headers.get(\"retry-after\")),\n };\n }\n if (status >= 500) {\n return {\n message: serverMessage ?? `AtlaSent API returned HTTP ${status}`,\n code: \"server_error\",\n retryAfterMs: undefined,\n };\n }\n return {\n message: serverMessage ?? `AtlaSent API returned HTTP ${status}`,\n code: \"bad_request\",\n retryAfterMs: undefined,\n };\n}\n\nasync function readServerMessage(response: Response): Promise<string | null> {\n try {\n const text = await response.text();\n if (!text) return null;\n try {\n const parsed = JSON.parse(text);\n if (parsed && typeof parsed === \"object\") {\n const msg = (parsed as Record<string, unknown>).message;\n const reason = (parsed as Record<string, unknown>).reason;\n if (typeof msg === \"string\" && msg.length > 0) return msg;\n if (typeof reason === \"string\" && reason.length > 0) return reason;\n }\n } catch {\n // Fall through — treat as plain text.\n }\n return text.length > 500 ? `${text.slice(0, 500)}…` : text;\n } catch {\n return null;\n }\n}\n\n/**\n * Translate an {@link AuditEventsQuery} into `URLSearchParams`. The\n * server expects snake_case keys (`actor_id`) and accepts\n * comma-joined values for `types`; numeric `limit` serializes via\n * `String(n)`. Undefined / empty fields are dropped so the query\n * string stays minimal.\n */\nfunction buildAuditEventsQuery(query: AuditEventsQuery): URLSearchParams {\n const params = new URLSearchParams();\n if (query.types !== undefined && query.types !== \"\") {\n params.set(\"types\", query.types);\n }\n if (query.actor_id !== undefined && query.actor_id !== \"\") {\n params.set(\"actor_id\", query.actor_id);\n }\n if (query.from !== undefined && query.from !== \"\") {\n params.set(\"from\", query.from);\n }\n if (query.to !== undefined && query.to !== \"\") {\n params.set(\"to\", query.to);\n }\n if (query.limit !== undefined) {\n params.set(\"limit\", String(query.limit));\n }\n if (query.cursor !== undefined && query.cursor !== \"\") {\n params.set(\"cursor\", query.cursor);\n }\n return params;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction parseRetryAfter(raw: string | null): number | undefined {\n if (!raw) return undefined;\n const seconds = Number(raw);\n if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);\n const date = Date.parse(raw);\n if (Number.isFinite(date)) {\n const delta = date - Date.now();\n return delta > 0 ? delta : 0;\n }\n return undefined;\n}\n\n// ── SSE stream parser ─────────────────────────────────────────────────────────\n\n/**\n * Parse an SSE `ReadableStream<Uint8Array>` into typed {@link StreamEvent}s.\n *\n * Hardening additions over the original:\n * - Per-event timeout: if no chunk arrives within `timeoutMs` (0 = disabled),\n * throws {@link StreamTimeoutError}.\n * - Partial-JSON guard: wraps `JSON.parse` failures in {@link StreamParseError}\n * rather than letting the raw `SyntaxError` escape.\n * - Calls `onEventId` whenever the server emits an `id:` field so the caller\n * can track the `Last-Event-ID` for reconnection.\n * - Terminal detection: returns on `event: done` OR when a `decision` event\n * carries `done: true` at the top level (server-side terminal signal).\n */\nasync function* parseSseStream(\n body: ReadableStream<Uint8Array>,\n requestId: string,\n timeoutMs: number,\n onEventId: (id: string) => void,\n): AsyncIterable<StreamEvent> {\n const reader = body.getReader();\n const decoder = new TextDecoder(\"utf-8\");\n let buf = \"\";\n\n type ChunkResult =\n | { done: true; value?: undefined }\n | { done: false; value: Uint8Array };\n\n /**\n * Read the next chunk from the reader, applying a per-read timeout when\n * `timeoutMs > 0`. Returns `{ done: true }` when the stream ends, throws\n * {@link StreamTimeoutError} on timeout.\n */\n async function readChunk(): Promise<ChunkResult> {\n if (timeoutMs <= 0) {\n return reader.read() as Promise<ChunkResult>;\n }\n return new Promise<ChunkResult>((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(new StreamTimeoutError(timeoutMs));\n }, timeoutMs);\n (reader.read() as Promise<ChunkResult>).then(\n (result) => {\n clearTimeout(timer);\n resolve(result);\n },\n (err: unknown) => {\n clearTimeout(timer);\n reject(err);\n },\n );\n });\n }\n\n try {\n for (;;) {\n let done: boolean;\n let value: Uint8Array | undefined;\n try {\n const result = await readChunk();\n done = result.done;\n value = result.value;\n } catch (err) {\n if (err instanceof StreamTimeoutError) throw err;\n // Network error mid-stream: surface as AtlaSentError(network) so the\n // caller's reconnection loop can catch and retry.\n throw new AtlaSentError(\n `AtlaSent stream read failed: ${err instanceof Error ? err.message : String(err)}`,\n { code: \"network\", requestId, cause: err },\n );\n }\n\n if (done) break;\n buf += decoder.decode(value, { stream: true });\n\n let boundary: number;\n while ((boundary = buf.indexOf(\"\\n\\n\")) !== -1) {\n const block = buf.slice(0, boundary);\n buf = buf.slice(boundary + 2);\n\n let eventType = \"message\";\n let data = \"\";\n let eventId: string | undefined;\n for (const line of block.split(\"\\n\")) {\n if (line.startsWith(\"event: \")) eventType = line.slice(7).trim();\n else if (line.startsWith(\"data: \")) data = line.slice(6);\n else if (line.startsWith(\"id: \")) eventId = line.slice(4).trim();\n else if (line.startsWith(\"id:\")) eventId = line.slice(3).trim();\n }\n\n if (eventId !== undefined) onEventId(eventId);\n\n if (!data) continue;\n if (eventType === \"done\") return;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(data);\n } catch (err) {\n throw new StreamParseError(data, err);\n }\n\n if (eventType === \"error\") {\n const e = parsed as {\n code?: string;\n message?: string;\n request_id?: string;\n };\n throw new AtlaSentError(\n e.message ?? \"Stream error from AtlaSent API\",\n {\n code: (e.code as AtlaSentErrorCode | undefined) ?? \"server_error\",\n requestId: e.request_id ?? requestId,\n },\n );\n }\n\n if (eventType === \"decision\") {\n const d = parsed as {\n permitted?: boolean;\n decision_id?: string;\n reason?: string;\n audit_hash?: string;\n timestamp?: string;\n is_final?: boolean;\n done?: boolean;\n };\n if (\n typeof d.permitted !== \"boolean\" ||\n typeof d.decision_id !== \"string\"\n ) {\n throw new AtlaSentError(\n \"Malformed decision event from AtlaSent API\",\n {\n code: \"bad_response\",\n requestId,\n },\n );\n }\n // Streaming wire uses legacy {permitted, decision_id} shape;\n // normalise to canonical lowercase decision vocabulary.\n const streamDecision = d.permitted ? \"allow\" : \"deny\";\n const isFinal = d.is_final ?? false;\n yield {\n type: \"decision\",\n decision: streamDecision,\n decision_canonical: streamDecision,\n permitId: d.decision_id,\n reason: d.reason ?? \"\",\n auditHash: d.audit_hash ?? \"\",\n timestamp: d.timestamp ?? \"\",\n isFinal,\n } satisfies StreamDecisionEvent;\n\n // Terminal: final decision OR inline done: true closes the stream.\n if (isFinal || d.done === true) return;\n } else if (eventType === \"progress\") {\n const p = parsed as Record<string, unknown>;\n yield {\n type: \"progress\",\n stage: String(p[\"stage\"] ?? \"\"),\n ...p,\n } satisfies StreamProgressEvent;\n // Server may signal terminal state via done: true on any event type.\n if ((p as Record<string, unknown>).done === true) return;\n } else {\n // Unknown event type: check for done: true as a terminal signal.\n if (\n parsed !== null &&\n typeof parsed === \"object\" &&\n (parsed as Record<string, unknown>).done === true\n ) {\n return;\n }\n }\n // Unknown event types skipped for forward compatibility.\n }\n }\n\n // Stream closed before an explicit `event: done`. If there's leftover\n // partial data in the buffer, it means the stream was cut mid-event.\n if (buf.trim().length > 0) {\n throw new StreamParseError(buf);\n }\n } finally {\n reader.releaseLock();\n }\n}\n","/**\n * Offline verification for audit export bundles.\n *\n * Mirrors `atlasent-api/supabase/functions/v1-audit/verify.ts`. The\n * reference verifier there is the source of truth; this module must\n * stay byte-identical with it on the canonicalization + signing path\n * so a bundle that verifies in the backend verifies here (and vice\n * versa).\n *\n * Primary entry point:\n *\n * ```ts\n * import { verifyBundle } from \"@atlasent/sdk\";\n * const result = await verifyBundle(\"export.json\", { publicKeysPem: [pem] });\n * ```\n *\n * Node 20+ ships Ed25519 in `crypto.webcrypto.subtle`, so no extra\n * dependencies are required.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { webcrypto } from \"node:crypto\";\nimport type { TrustRootSnapshot } from \"./trustRoot.js\";\nimport { getGlobalTrustRootManager } from \"./trustRoot.js\";\nimport { BundleVerificationError } from \"./errors.js\";\n\nconst GENESIS_HASH = \"0\".repeat(64);\n\nconst subtle = webcrypto.subtle;\n\n/** Node's webcrypto CryptoKey — kept local so the module doesn't depend on DOM types. */\ntype WebCryptoKey = webcrypto.CryptoKey;\n\n/** Public key candidate the verifier will try, tagged with its registry id. */\nexport interface VerifyKey {\n keyId: string;\n publicKey: WebCryptoKey;\n}\n\nexport interface BundleVerificationResult {\n /**\n * AND of three checks: adjacency (each event's `previous_hash`\n * equals the prior event's `hash`), per-event hash recomputation\n * from the canonical payload, and `chain_head_hash` matching the\n * last event's stored hash.\n */\n chainIntegrityOk: boolean;\n /** Ed25519 signature verified against one of the supplied public keys. */\n signatureValid: boolean;\n /** `chain_head_hash` equals the last event's stored `hash`. */\n headHashMatches: boolean;\n /** Event ids whose recomputed hash != stored hash. */\n tamperedEventIds: string[];\n /** Which registry key id matched, when `signatureValid` is true. */\n matchedKeyId?: string | undefined;\n /** Non-fatal explanation when a flag is false. */\n reason?: string | undefined;\n /** Convenience: `chainIntegrityOk && signatureValid`. */\n verified: boolean;\n}\n\n/** Parsed bundle shape the verifier consumes. Fields beyond these are ignored. */\nexport interface AuditBundle {\n export_id?: unknown;\n org_id?: unknown;\n chain_head_hash?: unknown;\n event_count?: unknown;\n signed_at?: unknown;\n events?: unknown;\n signature?: unknown;\n signing_key_id?: unknown;\n [k: string]: unknown;\n}\n\nexport interface VerifyBundleOptions {\n /** SPKI-PEM strings (one per key in the active trust set). */\n publicKeysPem?: readonly string[];\n /** Already-imported keys, paired with registry ids (rotation hint). */\n keys?: readonly VerifyKey[];\n /** Trust-root snapshot for revocation + expiry checks. */\n trustRoot?: TrustRootSnapshot;\n /**\n * Opt out of fail-closed snapshot expiry check (ADR-005 D3).\n * Intended for air-gap / offline use cases.\n * Emits a one-time warning per process start.\n */\n allowExpiredSnapshot?: boolean;\n}\n\n// ─── Canonicalization ─────────────────────────────────────────────────────────\n\n/**\n * Reproduces `_shared/rules.ts::canonicalJSON` byte-for-byte:\n * - object keys sorted at every depth\n * - no whitespace\n * - `null`, `undefined`, `NaN`, `±Infinity` all render as `\"null\"`\n * - strings use standard `JSON.stringify` escapes\n */\nexport function canonicalJSON(value: unknown): string {\n if (value === null || value === undefined) return \"null\";\n if (typeof value === \"number\") return Number.isFinite(value) ? String(value) : \"null\";\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n if (typeof value === \"string\") return JSON.stringify(value);\n if (Array.isArray(value)) return \"[\" + value.map(canonicalJSON).join(\",\") + \"]\";\n if (typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n return \"{\" + keys.map((k) => JSON.stringify(k) + \":\" + canonicalJSON(obj[k])).join(\",\") + \"}\";\n }\n return \"null\";\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n const buf = await subtle.digest(\"SHA-256\", new TextEncoder().encode(input));\n return Array.from(new Uint8Array(buf))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n// ─── Envelope reconstruction ──────────────────────────────────────────────────\n\n/**\n * Recreate the exact bytes `handleExport` signed. Key order is\n * load-bearing — must match the object literal in\n * `v1-audit/index.ts::handleExport`. V8 preserves insertion order, so\n * the literal below is byte-identical with what the backend signs.\n */\nexport function signedBytesFor(bundle: AuditBundle): Uint8Array<ArrayBuffer> {\n const envelope = {\n export_id: bundle.export_id,\n org_id: bundle.org_id,\n chain_head_hash: bundle.chain_head_hash,\n event_count: bundle.event_count,\n signed_at: bundle.signed_at,\n events: bundle.events,\n };\n return new TextEncoder().encode(JSON.stringify(envelope));\n}\n\n// ─── Chain verification ───────────────────────────────────────────────────────\n\ninterface ChainEvent {\n id?: unknown;\n hash?: unknown;\n previous_hash?: unknown;\n payload?: unknown;\n}\n\nasync function verifyChainEvents(\n events: ChainEvent[],\n): Promise<{ adjacencyOk: boolean; tamperedIds: string[] }> {\n const tamperedIds: string[] = [];\n let adjacencyOk = true;\n const first = events[0];\n let prevHash =\n first && typeof first.previous_hash === \"string\" ? first.previous_hash : GENESIS_HASH;\n\n for (let i = 0; i < events.length; i++) {\n const e = events[i];\n if (!e || typeof e.hash !== \"string\" || typeof e.previous_hash !== \"string\") {\n tamperedIds.push(String(e?.id ?? `index_${i}`));\n adjacencyOk = false;\n continue;\n }\n if (e.previous_hash !== prevHash) adjacencyOk = false;\n\n const canonical = canonicalJSON(e.payload ?? {});\n const recomputed = await sha256Hex(prevHash + canonical);\n if (recomputed !== e.hash) tamperedIds.push(String(e.id));\n\n prevHash = e.hash;\n }\n\n return { adjacencyOk, tamperedIds };\n}\n\n// ─── Signature verification ───────────────────────────────────────────────────\n\nfunction base64UrlDecode(s: string): Uint8Array<ArrayBuffer> {\n const pad = s.length % 4 === 0 ? \"\" : \"=\".repeat(4 - (s.length % 4));\n const b64 = s.replace(/-/g, \"+\").replace(/_/g, \"/\") + pad;\n const bin = Buffer.from(b64, \"base64\");\n const out = new Uint8Array(bin.byteLength);\n out.set(bin);\n return out;\n}\n\nasync function importSpkiPem(pem: string): Promise<WebCryptoKey> {\n const b64 = pem\n .replace(/-----BEGIN PUBLIC KEY-----/, \"\")\n .replace(/-----END PUBLIC KEY-----/, \"\")\n .replace(/\\s+/g, \"\");\n const bytes = Uint8Array.from(Buffer.from(b64, \"base64\"));\n return subtle.importKey(\"spki\", bytes, { name: \"Ed25519\" }, false, [\"verify\"]);\n}\n\nasync function resolveKeys(options: VerifyBundleOptions | undefined): Promise<VerifyKey[]> {\n const out: VerifyKey[] = [];\n if (options?.keys) out.push(...options.keys);\n if (options?.publicKeysPem) {\n for (let i = 0; i < options.publicKeysPem.length; i++) {\n const pem = options.publicKeysPem[i];\n if (!pem) continue;\n try {\n const pk = await importSpkiPem(pem);\n out.push({ keyId: `pem_${i}`, publicKey: pk });\n } catch {\n // Malformed PEM — skip it, try the rest.\n }\n }\n }\n return out;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\nexport async function verifyAuditBundle(\n bundle: AuditBundle,\n keys: readonly VerifyKey[],\n trustRootOpts?: {\n trustRoot?: TrustRootSnapshot;\n allowExpiredSnapshot?: boolean;\n },\n): Promise<BundleVerificationResult> {\n // ── ADR-005 D3: fail-closed snapshot expiry check ──────────────────\n if (trustRootOpts?.trustRoot) {\n const snap = trustRootOpts.trustRoot;\n const now = Date.now();\n const validUntil = new Date(snap.valid_until).getTime();\n if (now > validUntil && !trustRootOpts.allowExpiredSnapshot) {\n throw new BundleVerificationError({\n reason: \"trust_snapshot_expired\",\n snapshotValidUntil: snap.valid_until,\n snapshotFetchedAt: snap.issued_at,\n });\n }\n }\n\n const events: ChainEvent[] = Array.isArray(bundle.events) ? (bundle.events as ChainEvent[]) : [];\n\n const { adjacencyOk, tamperedIds } = await verifyChainEvents(events);\n\n const last = events[events.length - 1];\n const lastHash = last && typeof last.hash === \"string\" ? last.hash : GENESIS_HASH;\n const headHashMatches =\n typeof bundle.chain_head_hash === \"string\" ? bundle.chain_head_hash === lastHash : false;\n\n const chainIntegrityOk = adjacencyOk && tamperedIds.length === 0 && headHashMatches;\n\n let signatureValid = false;\n let matchedKeyId: string | undefined;\n let reason: string | undefined;\n\n if (keys.length === 0) {\n reason =\n \"no signing keys configured (signing_keys table empty and ATLASENT_EXPORT_SIGNING_KEY_PUBLIC unset)\";\n } else if (typeof bundle.signature !== \"string\" || bundle.signature.length === 0) {\n reason = \"bundle carries no signature\";\n } else {\n try {\n const sigBytes = base64UrlDecode(bundle.signature);\n const envelopeBytes = signedBytesFor(bundle);\n const hint = typeof bundle.signing_key_id === \"string\" ? bundle.signing_key_id : null;\n const ordered = hint\n ? [\n ...keys.filter((k) => k.keyId === hint),\n ...keys.filter((k) => k.keyId !== hint),\n ]\n : Array.from(keys);\n for (const k of ordered) {\n const ok = await subtle.verify(\"Ed25519\", k.publicKey, sigBytes, envelopeBytes);\n if (ok) {\n signatureValid = true;\n matchedKeyId = k.keyId;\n break;\n }\n }\n if (!signatureValid) {\n reason = `signature did not verify under any of ${keys.length} configured public key(s)`;\n }\n } catch (err) {\n reason = `signature check failed: ${err instanceof Error ? err.message : String(err)}`;\n }\n }\n\n // ── ADR-005: revocation check (after signature, before returning) ──\n if (signatureValid && trustRootOpts?.trustRoot) {\n const snap = trustRootOpts.trustRoot;\n const kid = typeof bundle.signing_key_id === \"string\" ? bundle.signing_key_id : null;\n if (kid !== null) {\n const isRevoked = snap.revoked_keys.some((r) => r.kid === kid);\n if (isRevoked) {\n throw new BundleVerificationError({\n reason: \"key_revoked\",\n snapshotValidUntil: snap.valid_until,\n snapshotFetchedAt: snap.issued_at,\n kid,\n });\n }\n // Check role: audit bundles must be signed by R3_audit\n const keyEntry = snap.keys.find((k) => k.kid === kid);\n if (keyEntry && keyEntry.role !== \"R3_audit\") {\n throw new BundleVerificationError({\n reason: \"key_role_mismatch\",\n snapshotValidUntil: snap.valid_until,\n snapshotFetchedAt: snap.issued_at,\n kid,\n });\n }\n }\n }\n\n if (!chainIntegrityOk && reason === undefined) {\n if (tamperedIds.length > 0) reason = `hash mismatch for ${tamperedIds.length} event(s)`;\n else if (!adjacencyOk) reason = \"chain adjacency broken\";\n else if (!headHashMatches) reason = \"chain_head_hash does not match last event\";\n }\n\n return {\n chainIntegrityOk,\n signatureValid,\n headHashMatches,\n tamperedEventIds: tamperedIds,\n matchedKeyId,\n reason,\n verified: chainIntegrityOk && signatureValid,\n };\n}\n\n/**\n * Load a bundle from disk (or a parsed object) and verify it.\n *\n * `publicKeysPem` is the active SPKI-PEM set from\n * `GET /v1-signing-keys`. When omitted, the chain check still runs\n * but `signatureValid` will be false with an explanatory `reason` —\n * callers that want a complete offline check MUST supply the trust\n * set.\n *\n * When `trustRoot` is not supplied, the global trust-root manager's\n * current snapshot is used automatically (B2.3 bootstrap wire-in).\n * Pass `allowExpiredSnapshot: true` to disable fail-closed expiry\n * for air-gap environments.\n */\nexport async function verifyBundle(\n pathOrBundle: string | AuditBundle,\n options?: VerifyBundleOptions,\n): Promise<BundleVerificationResult> {\n let bundle: AuditBundle;\n if (typeof pathOrBundle === \"string\") {\n const raw = await readFile(pathOrBundle, \"utf8\");\n const parsed = JSON.parse(raw);\n // Fixture wrapper shape: { description, bundle }. Accepted for ergonomics.\n bundle =\n parsed && typeof parsed === \"object\" && \"bundle\" in parsed && typeof parsed.bundle === \"object\"\n ? (parsed.bundle as AuditBundle)\n : (parsed as AuditBundle);\n } else {\n bundle = pathOrBundle;\n }\n const keys = await resolveKeys(options);\n // Auto-inject the global trust-root snapshot when none is explicitly provided.\n const effectiveTrustRoot =\n options?.trustRoot ?? getGlobalTrustRootManager().getSnapshot();\n return verifyAuditBundle(bundle, keys, {\n trustRoot: effectiveTrustRoot,\n ...(options?.allowExpiredSnapshot !== undefined && {\n allowExpiredSnapshot: options.allowExpiredSnapshot,\n }),\n });\n}\n","/**\n * Evidence Engine — per-decision proof artifacts, \"why\" traces, and\n * compliance-ready bundles.\n *\n * Turn every AtlaSent decision into tamper-evident proof that buyers\n * can hand to auditors, compliance teams, and regulators.\n *\n * Primary entry points:\n *\n * 1. `buildWhyTrace(decision, reasons, constraintTrace)` — converts\n * the ConstraintTrace from `?include=constraint_trace` into a\n * structured human/machine-readable \"why allowed / why denied\" trace.\n *\n * 2. `buildDecisionReceiptPayload(args)` — assembles the canonical\n * signable payload for a per-decision receipt.\n *\n * 3. `signDecisionReceiptHmac(payload, secret)` — HMAC-SHA256 sign.\n *\n * 4. `verifyDecisionReceiptHmac(receipt, secret)` — offline verify.\n *\n * 5. `computeBundleHash(bundle)` — SHA-256 of an ActionEvidenceBundle.\n *\n * 6. `soc2ControlCoverageForDecision(opts)` — map a decision to SOC 2\n * control coverage.\n *\n * The {@link DecisionReceipt} is the category-defining artifact: a\n * self-contained, signed, human-readable proof that a specific action\n * was (or was not) authorized at a specific moment. Every enforcement\n * adapter produces one; every compliance bundle includes one.\n */\n\nimport type {\n ConstraintTrace,\n ConstraintTracePolicy,\n ConstraintTraceStage,\n DecisionCanonical,\n PermitRecord,\n} from \"./types.js\";\nimport type { AuditEvent } from \"./audit.js\";\nimport type { OverrideV1 } from \"./overrides.js\";\nimport type { ComplianceFramework } from \"./complianceEvidence.js\";\n\n// ── Why Trace ─────────────────────────────────────────────────────────────────\n\n/**\n * One evaluated stage within a policy, in the order the engine ran it.\n */\nexport interface WhyStage {\n /** Engine stage name (e.g. `\"role_check\"`, `\"context\"`). */\n stage: string;\n /** Rule identifier, if the stage is rule-bound. */\n rule?: string;\n /** Whether this stage's predicate fired / matched. */\n matched: boolean;\n /** Non-obvious detail from the engine. */\n detail?: string;\n /**\n * Impact classification:\n * - `\"terminal\"` — this stage caused the outer decision.\n * - `\"contributing\"` — matched but was not the decisive stage.\n * - `\"passing\"` — did not match; execution continued.\n */\n impact: \"terminal\" | \"contributing\" | \"passing\";\n}\n\n/** Per-policy evaluation block within a WhyTrace. */\nexport interface WhyPolicyEvaluation {\n policy_id: string;\n /** Policy-level decision. */\n decision: string;\n /** Engine-side fingerprint of the policy bundle row. */\n fingerprint: string;\n /** Optional risk score from a `risk` rule clause. */\n risk_score?: number;\n /** Stages evaluated for this policy, in order. */\n stages: WhyStage[];\n /** `true` iff this policy's decision drove the outer envelope decision. */\n was_decisive: boolean;\n}\n\n/**\n * Structured \"why allowed / why denied\" trace.\n *\n * Produced by `buildWhyTrace()` from the `ConstraintTrace` returned\n * by `/v1-evaluate?include=constraint_trace`. Suitable for:\n *\n * - UI display (\"Why was this denied?\")\n * - Email / Slack notifications\n * - Compliance-bundle human-readable section\n * - Machine-readable policy audit by external verifiers\n *\n * `summary` is a one-sentence plain-English explanation.\n */\nexport interface WhyTrace {\n decision: DecisionCanonical;\n /** One-sentence human-readable explanation. */\n summary: string;\n /** Policy whose decision drove the outer result. Absent on clean allow. */\n matched_policy_id?: string;\n /** Per-policy evaluation blocks in evaluation order. */\n policy_evaluations: WhyPolicyEvaluation[];\n /**\n * The single stage that caused the terminal outcome, extracted for\n * quick access. `undefined` on a clean allow (no blocking stage).\n */\n terminal_stage?: WhyStage;\n /** Total stages evaluated across all policies. */\n total_stages_evaluated: number;\n}\n\n// ── Decision Receipt ──────────────────────────────────────────────────────────\n\n/** Signing algorithm tag on a {@link DecisionReceipt}. */\nexport type DecisionReceiptAlgorithm = \"hmac-sha256\" | \"ed25519\" | \"none\";\n\n/**\n * The canonical signed payload of a {@link DecisionReceipt}.\n *\n * Field order is load-bearing: HMAC and chain verifiers stringify\n * this object and must reproduce byte-identical output. Never reorder\n * the fields; add new optional fields at the end only.\n */\nexport interface DecisionReceiptPayload {\n receipt_id: string;\n evaluation_id: string;\n org_id: string;\n decision: DecisionCanonical;\n action: string;\n actor: string;\n resource_type: string | null;\n resource_id: string | null;\n reasons: string[];\n /** One-sentence human-readable summary from the WhyTrace. */\n why_summary: string;\n /** Permit ID when the decision was `\"allow\"`. */\n permit_id: string | null;\n /** Permit verification hash when the decision was `\"allow\"`. */\n permit_hash: string | null;\n /** Hash-chained audit-trail entry from the evaluate response. */\n audit_hash: string;\n /** SHA-256 hex of canonical JSON of the evaluate context. */\n context_hash: string;\n /** ISO-8601 when this receipt was issued. */\n issued_at: string;\n /** ISO-8601 TTL, or `null` for non-expiring receipts. */\n expires_at: string | null;\n}\n\n/**\n * A signed, tamper-evident record of a single AtlaSent authorization\n * decision. Self-contained: contains everything an auditor needs to\n * verify the decision without querying the API.\n *\n * **Signature semantics (HMAC-SHA256):**\n *\n * `HMAC-SHA256(secret,\n * receipt_id + \"\\\\n\" + issued_at + \"\\\\n\" + JSON.stringify(payload))`\n *\n * When `algorithm === \"ed25519\"`, `signature` is hex-encoded Ed25519\n * over the same input string encoded as UTF-8.\n *\n * Offline verification: `verifyDecisionReceiptHmac(receipt, secret)`.\n *\n * Callers MUST reject receipts where `algorithm === \"none\"` in any\n * context requiring tamper-evidence.\n */\nexport interface DecisionReceipt {\n receipt_id: string;\n evaluation_id: string;\n org_id: string;\n decision: DecisionCanonical;\n action: string;\n actor: string;\n resource_type: string | null;\n resource_id: string | null;\n reasons: string[];\n /**\n * Full structured \"why\" trace. `null` when the evaluation was\n * performed without `?include=constraint_trace`.\n */\n why_trace: WhyTrace | null;\n permit_id: string | null;\n permit_hash: string | null;\n audit_hash: string;\n /** SHA-256 hex of canonical JSON of the evaluate context. */\n context_hash: string;\n issued_at: string;\n expires_at: string | null;\n algorithm: DecisionReceiptAlgorithm;\n /**\n * Hex (HMAC-SHA256 or Ed25519) signature, or `null` when\n * `algorithm === \"none\"`.\n */\n signature: string | null;\n /** Registry key ID that signed, when `algorithm !== \"none\"`. */\n signing_key_id: string | null;\n /**\n * Full payload that was signed. Pass to `verifyDecisionReceiptHmac`\n * or reconstruct independently for external verification.\n */\n payload: DecisionReceiptPayload;\n}\n\n// ── Action Evidence Bundle ────────────────────────────────────────────────────\n\n/** Coverage summary for one compliance control within a bundle. */\nexport interface ComplianceControlCoverage {\n framework: ComplianceFramework;\n control_id: string;\n title: string;\n /** `true` when this bundle provides sufficient evidence for the control. */\n covered: boolean;\n /** Evidence kinds present in the bundle that map to this control. */\n evidence_kinds: string[];\n}\n\n/**\n * A compliance-ready evidence bundle for a single protected action.\n *\n * Contains everything an auditor needs to verify the authorization\n * decision without querying the API:\n *\n * - The signed {@link DecisionReceipt}\n * - The \"why\" trace (why allowed / why denied)\n * - Audit events from the decision window\n * - Permit chain (when the decision was `\"allow\"`)\n * - Active overrides that influenced the decision\n * - Per-control SOC 2 / compliance coverage map\n *\n * `bundle_hash` is SHA-256 of `JSON.stringify(bundle)` with\n * `bundle_hash` omitted, computed by `computeBundleHash()`. Use it\n * to verify the bundle was not modified after assembly.\n */\nexport interface ActionEvidenceBundle {\n /** Wire format version. */\n v: 1;\n bundle_id: string;\n evaluation_id: string;\n org_id: string;\n action: string;\n actor: string;\n decision: DecisionCanonical;\n receipt: DecisionReceipt;\n why_trace: WhyTrace | null;\n /** Audit events from the evaluation window related to this action. */\n audit_events: AuditEvent[];\n /** Permit chain when the decision was `\"allow\"`. */\n permit_chain: PermitRecord[];\n /** Active overrides that influenced the decision. */\n overrides: OverrideV1[];\n compliance_controls: ComplianceControlCoverage[];\n generated_at: string;\n /** SHA-256 hex of canonical JSON of this bundle (sans this field). */\n bundle_hash: string;\n}\n\n// ── buildWhyTrace ─────────────────────────────────────────────────────────────\n\n/**\n * Convert a raw `ConstraintTrace` (from `?include=constraint_trace`)\n * into a structured {@link WhyTrace} with a human-readable summary.\n *\n * Safe to call with `trace === null` — returns a minimal trace with\n * the decision and a generic summary derived from `reasons`.\n *\n * ```ts\n * import { buildWhyTrace } from \"@atlasent/sdk\";\n *\n * const preflight = await client.evaluatePreflight({ agent, action, context });\n * const why = buildWhyTrace(\n * preflight.evaluation.decision_canonical,\n * preflight.evaluation.reasons,\n * preflight.constraintTrace,\n * );\n * console.log(why.summary);\n * // \"Denied at stage 'role_check': actor lacks deploy role\"\n * ```\n */\nexport function buildWhyTrace(\n decision: DecisionCanonical,\n reasons: readonly string[],\n trace: ConstraintTrace | null,\n): WhyTrace {\n if (!trace) {\n return {\n decision,\n summary: formatSummary(decision, reasons, undefined, undefined),\n policy_evaluations: [],\n total_stages_evaluated: 0,\n };\n }\n\n const matchedPolicyId: string | undefined =\n typeof trace.matching_policy_id === \"string\"\n ? trace.matching_policy_id\n : undefined;\n\n let terminalStage: WhyStage | undefined;\n let totalStages = 0;\n\n const policyEvaluations: WhyPolicyEvaluation[] = (\n trace.rules_evaluated ?? []\n ).map((policy: ConstraintTracePolicy) => {\n const wasDecisive = matchedPolicyId === policy.policy_id;\n let foundTerminal = false;\n\n const stages: WhyStage[] = (policy.stages ?? []).map(\n (s: ConstraintTraceStage, idx: number) => {\n totalStages++;\n const isLast = idx === (policy.stages?.length ?? 1) - 1;\n const candidateForTerminal =\n wasDecisive && !foundTerminal && (s.matched || isLast);\n\n let impact: WhyStage[\"impact\"] = \"passing\";\n\n if (candidateForTerminal) {\n impact = \"terminal\";\n foundTerminal = true;\n terminalStage = {\n stage: s.stage,\n ...(s.rule !== undefined ? { rule: s.rule } : {}),\n matched: s.matched,\n ...(s.detail !== undefined ? { detail: s.detail } : {}),\n impact: \"terminal\",\n };\n } else if (s.matched) {\n impact = \"contributing\";\n }\n\n return {\n stage: s.stage,\n ...(s.rule !== undefined ? { rule: s.rule } : {}),\n matched: s.matched,\n ...(s.detail !== undefined ? { detail: s.detail } : {}),\n impact,\n };\n },\n );\n\n return {\n policy_id: policy.policy_id,\n decision: policy.decision,\n fingerprint: policy.fingerprint,\n ...(policy.risk_score !== undefined ? { risk_score: policy.risk_score } : {}),\n stages,\n was_decisive: wasDecisive,\n };\n });\n\n return {\n decision,\n summary: formatSummary(decision, reasons, matchedPolicyId, terminalStage),\n ...(matchedPolicyId !== undefined ? { matched_policy_id: matchedPolicyId } : {}),\n policy_evaluations: policyEvaluations,\n ...(terminalStage !== undefined ? { terminal_stage: terminalStage } : {}),\n total_stages_evaluated: totalStages,\n };\n}\n\nfunction formatSummary(\n decision: DecisionCanonical,\n reasons: readonly string[],\n matchedPolicyId: string | undefined,\n terminalStage: WhyStage | undefined,\n): string {\n const reason0 = reasons.length > 0 ? reasons[0] : undefined;\n switch (decision) {\n case \"allow\":\n return reason0\n ? `Allowed: ${reason0}`\n : \"Allowed: all policy checks passed.\";\n case \"deny\":\n if (reason0) return `Denied: ${reason0}`;\n if (terminalStage?.detail)\n return `Denied at stage \"${terminalStage.stage}\": ${terminalStage.detail}`;\n if (terminalStage)\n return `Denied at stage \"${terminalStage.stage}\".`;\n if (matchedPolicyId)\n return `Denied by policy ${matchedPolicyId}.`;\n return \"Denied: policy check failed.\";\n case \"hold\":\n return reason0\n ? `Held for review: ${reason0}`\n : \"Held pending human review.\";\n case \"escalate\":\n return reason0\n ? `Escalated: ${reason0}`\n : \"Escalated to a human reviewer.\";\n }\n}\n\n// ── Crypto helpers ────────────────────────────────────────────────────────────\n\nfunction sortedJSON(val: unknown): string {\n if (val === null || val === undefined) return \"null\";\n if (typeof val === \"number\")\n return Number.isFinite(val) ? String(val) : \"null\";\n if (typeof val === \"boolean\") return val ? \"true\" : \"false\";\n if (typeof val === \"string\") return JSON.stringify(val);\n if (Array.isArray(val)) return \"[\" + val.map(sortedJSON).join(\",\") + \"]\";\n if (typeof val === \"object\") {\n const obj = val as Record<string, unknown>;\n return (\n \"{\" +\n Object.keys(obj)\n .sort()\n .map((k) => JSON.stringify(k) + \":\" + sortedJSON(obj[k]))\n .join(\",\") +\n \"}\"\n );\n }\n return \"null\";\n}\n\nfunction hexEncode(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n const bytes = new TextEncoder().encode(input);\n if (\n typeof globalThis !== \"undefined\" &&\n globalThis.crypto?.subtle?.digest\n ) {\n const buf = await globalThis.crypto.subtle.digest(\"SHA-256\", bytes);\n return hexEncode(new Uint8Array(buf));\n }\n try {\n const { createHash } = await import(\n /* @vite-ignore */ /* webpackIgnore: true */ \"node:crypto\"\n );\n return createHash(\"sha256\").update(input, \"utf8\").digest(\"hex\");\n } catch {\n return \"\";\n }\n}\n\n// ── Context hash ──────────────────────────────────────────────────────────────\n\n/**\n * Compute SHA-256 hex of the recursively key-sorted canonical JSON of\n * `context`. Used as `context_hash` on a `DecisionReceipt` so the\n * original evaluate context can be independently verified offline.\n */\nexport async function computeContextHash(\n context: Record<string, unknown>,\n): Promise<string> {\n return sha256Hex(sortedJSON(context));\n}\n\n// ── Receipt payload builder ───────────────────────────────────────────────────\n\n/**\n * Assemble a {@link DecisionReceiptPayload} — the canonical object\n * that is serialised and signed. Field insertion order is fixed;\n * do NOT reorder the fields below.\n */\nexport function buildDecisionReceiptPayload(args: {\n receipt_id: string;\n evaluation_id: string;\n org_id: string;\n decision: DecisionCanonical;\n action: string;\n actor: string;\n resource_type?: string | null;\n resource_id?: string | null;\n reasons: readonly string[];\n why_summary: string;\n permit_id?: string | null;\n permit_hash?: string | null;\n audit_hash: string;\n context_hash: string;\n issued_at: string;\n expires_at?: string | null;\n}): DecisionReceiptPayload {\n return {\n receipt_id: args.receipt_id,\n evaluation_id: args.evaluation_id,\n org_id: args.org_id,\n decision: args.decision,\n action: args.action,\n actor: args.actor,\n resource_type: args.resource_type ?? null,\n resource_id: args.resource_id ?? null,\n reasons: Array.from(args.reasons),\n why_summary: args.why_summary,\n permit_id: args.permit_id ?? null,\n permit_hash: args.permit_hash ?? null,\n audit_hash: args.audit_hash,\n context_hash: args.context_hash,\n issued_at: args.issued_at,\n expires_at: args.expires_at ?? null,\n };\n}\n\n/**\n * Canonical input string signed by both HMAC-SHA256 and Ed25519\n * receipt signers.\n *\n * Format: `receipt_id + \"\\n\" + issued_at + \"\\n\" + JSON.stringify(payload)`\n */\nexport function receiptSigningInput(payload: DecisionReceiptPayload): string {\n return (\n payload.receipt_id +\n \"\\n\" +\n payload.issued_at +\n \"\\n\" +\n JSON.stringify(payload)\n );\n}\n\n// ── HMAC-SHA256 sign / verify ─────────────────────────────────────────────────\n\n/**\n * HMAC-SHA256 sign a {@link DecisionReceiptPayload}. Returns the\n * hex-encoded MAC. Store as `receipt.signature` with\n * `algorithm: \"hmac-sha256\"`.\n *\n * Uses `crypto.subtle` (browser / Node 20+ / Cloudflare) or falls\n * back to `node:crypto` on older Node runtimes.\n */\nexport async function signDecisionReceiptHmac(\n payload: DecisionReceiptPayload,\n secret: string,\n): Promise<string> {\n const input = receiptSigningInput(payload);\n const keyBytes = new TextEncoder().encode(secret);\n const msgBytes = new TextEncoder().encode(input);\n\n if (typeof globalThis !== \"undefined\" && globalThis.crypto?.subtle) {\n const key = await globalThis.crypto.subtle.importKey(\n \"raw\",\n keyBytes,\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n const sig = await globalThis.crypto.subtle.sign(\"HMAC\", key, msgBytes);\n return hexEncode(new Uint8Array(sig));\n }\n\n try {\n const { createHmac } = await import(\n /* @vite-ignore */ /* webpackIgnore: true */ \"node:crypto\"\n );\n return createHmac(\"sha256\", secret).update(input).digest(\"hex\");\n } catch {\n return \"\";\n }\n}\n\n/**\n * Verify an HMAC-SHA256-signed {@link DecisionReceipt} offline.\n * Returns `false` (does not throw) on any verification failure.\n *\n * Callers MUST reject receipts where `receipt.algorithm !== \"hmac-sha256\"`.\n */\nexport async function verifyDecisionReceiptHmac(\n receipt: DecisionReceipt,\n secret: string,\n): Promise<boolean> {\n if (receipt.algorithm !== \"hmac-sha256\" || !receipt.signature) return false;\n const expected = await signDecisionReceiptHmac(receipt.payload, secret);\n return timingSafeEqual(expected, receipt.signature);\n}\n\nfunction timingSafeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let result = 0;\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return result === 0;\n}\n\n// ── Bundle hash ───────────────────────────────────────────────────────────────\n\n/**\n * Compute SHA-256 hex of `JSON.stringify(bundle)` with `bundle_hash`\n * omitted. Store as `bundle.bundle_hash` after assembly.\n *\n * An external verifier can reproduce this value independently to\n * confirm the bundle was not modified after export.\n */\nexport async function computeBundleHash(\n bundle: Omit<ActionEvidenceBundle, \"bundle_hash\">,\n): Promise<string> {\n return sha256Hex(JSON.stringify(bundle));\n}\n\n// ── Compliance control coverage ───────────────────────────────────────────────\n\n/**\n * Return the SOC 2 controls covered by a single authorization decision,\n * given what the bundle contains. Suitable for populating\n * `ActionEvidenceBundle.compliance_controls`.\n *\n * For ISO 27001 / GDPR / HIPAA coverage use the `@atlasent/evidence-bundle`\n * package's `buildEvidenceBundle()` which handles multi-framework mapping.\n */\nexport function soc2ControlCoverageForDecision(opts: {\n decision: DecisionCanonical;\n hasPermitChain: boolean;\n hasAuditEvents: boolean;\n hasOverrides: boolean;\n}): ComplianceControlCoverage[] {\n return [\n {\n framework: \"soc2\",\n control_id: \"CC7.2\",\n title: \"Audit trail completeness\",\n covered: opts.hasAuditEvents,\n evidence_kinds: [\"audit_log_slice\"],\n },\n {\n framework: \"soc2\",\n control_id: \"CC8.1\",\n title: \"Change management / HITL authorization\",\n covered: opts.decision === \"allow\" && opts.hasPermitChain,\n evidence_kinds: [\"permit_chain\"],\n },\n {\n framework: \"soc2\",\n control_id: \"CC6.1\",\n title: \"Logical access controls — authorization enforcement\",\n covered: true,\n evidence_kinds: [\"policy_snapshot\"],\n },\n {\n framework: \"soc2\",\n control_id: \"CC3.2\",\n title: \"Policy violations and override tracking\",\n covered: opts.hasOverrides,\n evidence_kinds: [\"policy_snapshot\", \"permit_chain\"],\n },\n ];\n}\n","/**\n * `atlasent.protect(...)` — the one-call, fail-closed execution-time\n * authorization boundary.\n *\n * ```ts\n * import atlasent from \"@atlasent/sdk\";\n *\n * const permit = await atlasent.protect({\n * agent: \"deploy-bot\",\n * action: \"production.deploy\",\n * context: { commit, approver },\n * });\n * // …run the action. If we got here, AtlaSent authorized it\n * // end-to-end (evaluate + verifyPermit).\n * ```\n *\n * Unlike {@link AtlaSentClient.evaluate}, `protect` never returns a\n * denied decision. On deny, it throws {@link AtlaSentDeniedError};\n * on transport / auth / server failure it throws\n * {@link AtlaSentError}. The action cannot execute unless a valid\n * {@link Permit} is returned — this is the SDK's category boundary,\n * not a helper.\n *\n * `protectWithEvidence` is the same contract plus a signed\n * {@link DecisionReceipt} minted on the way out. Use it when you need\n * tamper-evident proof of authorization stored alongside the action\n * record (deploy logs, payment records, close workflows).\n */\n\nimport { AtlaSentClient } from \"./client.js\";\nimport type { DeployGateRequest, DeployGateResponse } from \"./types.js\";\nimport {\n AtlaSentDeniedError,\n AtlaSentError,\n BundleVerificationError,\n normalizePermitOutcome,\n type AtlaSentDecision,\n} from \"./errors.js\";\nimport { getGlobalTrustRootManager } from \"./trustRoot.js\";\nimport type { AtlaSentClientOptions, ConstraintTrace } from \"./types.js\";\nimport {\n buildDecisionReceiptPayload,\n buildWhyTrace,\n computeContextHash,\n signDecisionReceiptHmac,\n} from \"./evidenceEngine.js\";\nimport type {\n DecisionReceipt,\n DecisionReceiptAlgorithm,\n} from \"./evidenceEngine.js\";\n\n/** Input to {@link protect}. Same shape as `EvaluateRequest`. */\nexport interface ProtectRequest {\n agent: string;\n action: string;\n context?: Record<string, unknown>;\n}\n\n/**\n * Success return from {@link protect}. The action is authorized\n * end-to-end — evaluation allowed AND the resulting permit verified.\n */\nexport interface Permit {\n /** Opaque permit / decision identifier. */\n permitId: string;\n /** Verification hash bound to the permit. */\n permitHash: string;\n /** Audit-trail entry associated with the decision (hash-chained). */\n auditHash: string;\n /** Human-readable reason from the policy engine. */\n reason: string;\n /** ISO 8601 timestamp of the verification. */\n timestamp: string;\n /** ISO-8601 expiration timestamp of the permit. null on pre-rollout servers. */\n permitExpiresAt: string | null;\n}\n\n/** Configuration for the process-wide singleton used by {@link protect}. */\nexport interface ConfigureOptions {\n /** Overrides `ATLASENT_API_KEY` env var. */\n apiKey?: string;\n /** Overrides the default `https://api.atlasent.io`. */\n baseUrl?: string;\n /** Per-request timeout in ms. */\n timeoutMs?: number;\n /** Inject a custom fetch (primarily for tests). */\n fetch?: typeof fetch;\n /** Override the retry policy. Pass `{ maxAttempts: 1 }` to disable retries. */\n retryPolicy?: import(\"./retry.js\").RetryPolicy;\n}\n\nlet sharedClient: AtlaSentClient | null = null;\nlet overrides: ConfigureOptions = {};\n\n/**\n * Configure the singleton client used by {@link protect}. Optional —\n * if `ATLASENT_API_KEY` is set in the environment, `protect` works\n * without any configuration. Calling `configure` again replaces the\n * singleton; subsequent `protect` calls use the new settings.\n */\nexport function configure(options: ConfigureOptions): void {\n overrides = { ...overrides, ...options };\n sharedClient = null;\n}\n\n/**\n * Run the canonical Deploy Gate V1 helper using the process-wide client.\n * Defaults to action `production.deploy`; execution is allowed only after\n * server-side `/v1-evaluate` and `/v1-verify-permit` both pass.\n */\nexport async function deployGate(\n request: DeployGateRequest = {},\n): Promise<DeployGateResponse> {\n return getClient().deployGate(request);\n}\n\n/** Reset the singleton. Exported for tests; not part of the public API. */\nexport function __resetSharedClientForTests(): void {\n sharedClient = null;\n overrides = {};\n}\n\nfunction getClient(): AtlaSentClient {\n if (sharedClient) return sharedClient;\n\n // Guard process.env access so this module is safe in browser and\n // edge-runtime environments where `process` is not defined as a global.\n const envApiKey =\n typeof process !== \"undefined\" && process.env\n ? process.env.ATLASENT_API_KEY\n : undefined;\n\n const apiKey = overrides.apiKey ?? envApiKey;\n if (!apiKey) {\n throw new AtlaSentError(\n \"AtlaSent is not configured. Set ATLASENT_API_KEY in the environment, or call atlasent.configure({ apiKey }).\",\n { code: \"invalid_api_key\" },\n );\n }\n const options: AtlaSentClientOptions = { apiKey };\n if (overrides.baseUrl !== undefined) options.baseUrl = overrides.baseUrl;\n if (overrides.timeoutMs !== undefined)\n options.timeoutMs = overrides.timeoutMs;\n if (overrides.fetch !== undefined) options.fetch = overrides.fetch;\n if (overrides.retryPolicy !== undefined)\n options.retryPolicy = overrides.retryPolicy;\n sharedClient = new AtlaSentClient(options);\n return sharedClient;\n}\n\n// Mirrors the server-side ACTION_TYPE_RE in v1-evaluate/handler.ts.\nconst ACTION_TYPE_RE = /^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$/;\n\nfunction wireDecisionToDenied(serverDecision: string): AtlaSentDecision {\n // Normalise to lowercase before matching — the decision field is now\n // always lowercase from evaluate(), but defensive lower-casing here\n // handles any edge case where an older code path sends uppercase.\n const lower = serverDecision.toLowerCase();\n if (lower === \"hold\" || lower === \"escalate\") return lower;\n return \"deny\";\n}\n\n// ── Execution-hash helpers ────────────────────────────────────────────────────\n\n/**\n * Sort all object keys recursively so the JSON serialization is\n * deterministic (RFC-8785-style canonical form). Arrays are preserved\n * in insertion order; only object keys are sorted.\n */\nfunction sortKeysDeep(val: unknown): unknown {\n if (Array.isArray(val)) return val.map(sortKeysDeep);\n if (val !== null && typeof val === \"object\") {\n return Object.keys(val as object)\n .sort()\n .reduce<Record<string, unknown>>((acc, k) => {\n acc[k] = sortKeysDeep((val as Record<string, unknown>)[k]);\n return acc;\n }, {});\n }\n return val;\n}\n\n/**\n * Compute a SHA-256 hex digest of the recursively key-sorted canonical\n * JSON of `payload`. Used as `execution_hash` on the permit-consume\n * (verify) request so the server can validate the evaluate payload\n * was not tampered with between evaluate and consume.\n *\n * Falls back to `node:crypto` when `crypto.subtle` is unavailable\n * (Node < 20 without the Web Crypto global).\n */\nasync function computeExecutionHash(payload: unknown): Promise<string> {\n const sorted = sortKeysDeep(payload);\n const canonical = JSON.stringify(sorted);\n\n // Prefer the Web Crypto API (available in browsers, Node 20+,\n // Cloudflare Workers, Deno, etc.).\n if (\n typeof globalThis !== \"undefined\" &&\n globalThis.crypto?.subtle?.digest\n ) {\n const bytes = new TextEncoder().encode(canonical);\n const buf = await globalThis.crypto.subtle.digest(\"SHA-256\", bytes);\n return Array.from(new Uint8Array(buf))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n // Fallback: node:crypto (Node < 20 or environments without crypto.subtle).\n try {\n // Dynamic import so bundlers that target browsers don't pull in\n // node internals. The `node:` prefix avoids any user-land shim.\n const { createHash } =\n await import(/* @vite-ignore */ /* webpackIgnore: true */ \"node:crypto\");\n return createHash(\"sha256\").update(canonical, \"utf8\").digest(\"hex\");\n } catch {\n // Last-resort: if neither crypto.subtle nor node:crypto is available\n // (very old Node, restricted runtime), return an empty string so the\n // verify call still proceeds — the server will reject if execution_hash\n // is required for production permits.\n // eslint-disable-next-line no-console\n console.warn(\n \"[atlasent] Could not compute execution_hash: neither crypto.subtle \" +\n \"nor node:crypto is available in this runtime.\",\n );\n return \"\";\n }\n}\n\nfunction generateReceiptId(): string {\n if (\n typeof globalThis !== \"undefined\" &&\n typeof globalThis.crypto?.randomUUID === \"function\"\n ) {\n return globalThis.crypto.randomUUID();\n }\n return `rcpt_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/**\n * Authorize an action end-to-end. On allow, returns a verified\n * {@link Permit}. On anything else, throws:\n *\n * - {@link AtlaSentDeniedError} — policy denied, or the permit\n * failed verification. Fail-closed: if this throws, the action\n * MUST NOT proceed.\n * - {@link AtlaSentError} — transport, timeout, auth, rate-limit,\n * or server error. Same fail-closed contract: do not proceed.\n */\nexport async function protect(request: ProtectRequest): Promise<Permit> {\n if (!ACTION_TYPE_RE.test(request.action)) {\n throw new AtlaSentError(\n `action must be in dot-notation format (e.g. \"production.deploy\"). Got: ${JSON.stringify(request.action)}`,\n { code: \"bad_request\" },\n );\n }\n // ADR-005 D3: fail-closed on expired trust snapshot. checkExpiry() also\n // emits the one-time half-life warning if >50% of validity window has elapsed.\n const trustMgr = getGlobalTrustRootManager({ disableRefresh: false });\n if (trustMgr.checkExpiry() === \"expired\") {\n const snap = trustMgr.getSnapshot();\n throw new BundleVerificationError({\n reason: \"trust_snapshot_expired\",\n snapshotValidUntil: snap.valid_until,\n snapshotFetchedAt: snap.issued_at,\n });\n }\n const client = getClient();\n const evaluation = await client.evaluate(request);\n\n // decision is now canonical lowercase: \"allow\" | \"deny\" | \"hold\" | \"escalate\"\n if (evaluation.decision !== \"allow\") {\n throw new AtlaSentDeniedError({\n decision: wireDecisionToDenied(evaluation.decision),\n evaluationId: evaluation.permitId,\n reason: evaluation.reason,\n auditHash: evaluation.auditHash,\n });\n }\n\n const environment = request.context?.environment as string | undefined;\n if (!environment) {\n throw new AtlaSentError(\n 'context.environment is required. Pass the environment where this action executes (e.g. \"production\", \"staging\").',\n { code: \"bad_request\" },\n );\n }\n\n // Compute execution_hash over the original evaluate payload so\n // the server can validate integrity on permit consume.\n const evaluatePayload = {\n action_type: request.action,\n actor_id: request.agent,\n context: request.context ?? {},\n };\n const execution_hash = await computeExecutionHash(evaluatePayload);\n\n const verifyRequest: {\n permitId: string;\n agent: string;\n action: string;\n context?: Record<string, unknown>;\n environment: string;\n execution_hash?: string;\n } = {\n permitId: evaluation.permitId,\n agent: request.agent,\n action: request.action,\n environment,\n ...(execution_hash ? { execution_hash } : {}),\n };\n if (request.context !== undefined) verifyRequest.context = request.context;\n const verification = await client.verifyPermit(verifyRequest);\n\n if (!verification.verified) {\n const outcome = normalizePermitOutcome(verification.outcome);\n throw new AtlaSentDeniedError({\n decision: \"deny\",\n evaluationId: evaluation.permitId,\n reason: `Permit failed verification (${verification.outcome})`,\n auditHash: evaluation.auditHash,\n ...(outcome !== undefined && { outcome }),\n });\n }\n\n return {\n permitId: evaluation.permitId,\n permitHash: verification.permitHash,\n auditHash: evaluation.auditHash,\n reason: evaluation.reason,\n timestamp: verification.timestamp,\n permitExpiresAt: verification.expiresAt ?? null,\n };\n}\n\n// ── Evidence-enhanced protect ─────────────────────────────────────────────────\n\n/**\n * A verified {@link Permit} with an embedded signed {@link DecisionReceipt}.\n *\n * Returned by {@link protectWithEvidence}. Store `receipt` alongside\n * your action record (deploy logs, payment records, close workflows)\n * to give auditors a self-contained proof of authorization.\n */\nexport interface PermitWithEvidence extends Permit {\n /** Signed per-decision receipt. `algorithm: \"none\"` when no signing secret was supplied. */\n receipt: DecisionReceipt;\n}\n\n/** Options for {@link protectWithEvidence}. */\nexport interface ProtectWithEvidenceOptions {\n /**\n * HMAC-SHA256 signing secret. When provided, the receipt is signed\n * and can be verified offline with `verifyDecisionReceiptHmac`.\n * Recommend `process.env.ATLASENT_RECEIPT_SIGNING_SECRET`.\n */\n signingSecret?: string;\n /**\n * Registry key ID recorded on the receipt, paired with `signingSecret`.\n * Used for key rotation: store the ID alongside the receipt so\n * verifiers know which key to use.\n */\n signingKeyId?: string;\n /**\n * If you have already called `client.evaluatePreflight()` for this\n * request, pass `constraintTrace` here to populate\n * `receipt.why_trace` with the full stage-by-stage \"why\" trace.\n * When omitted, `why_trace` is `null` on the receipt.\n */\n constraintTrace?: ConstraintTrace | null;\n}\n\n/**\n * Authorize an action end-to-end and mint a signed {@link DecisionReceipt}.\n *\n * Same fail-closed contract as {@link protect} — throws\n * {@link AtlaSentDeniedError} on deny, {@link AtlaSentError} on\n * transport failure. The action MUST NOT proceed if this throws.\n *\n * On allow, returns the verified `Permit` plus a signed `DecisionReceipt`\n * that captures:\n * - The evaluation ID and decision\n * - Human-readable reasons\n * - Permit ID and hash\n * - Audit-trail hash (hash-chain link)\n * - SHA-256 of the evaluate context (tamper-evidence for the inputs)\n * - Optional \"why\" trace (pass `constraintTrace` from `evaluatePreflight`)\n *\n * ```ts\n * const { permit, receipt } = await protectWithEvidence(\n * { agent: \"deploy-bot\", action: \"production.deploy\", context },\n * {\n * signingSecret: process.env.ATLASENT_RECEIPT_SIGNING_SECRET,\n * signingKeyId: \"key-v1\",\n * },\n * );\n * // Store alongside the deployment record.\n * await db.deployments.create({ commitSha, permit, receipt });\n * ```\n */\nexport async function protectWithEvidence(\n request: ProtectRequest,\n opts: ProtectWithEvidenceOptions = {},\n): Promise<PermitWithEvidence> {\n if (!ACTION_TYPE_RE.test(request.action)) {\n throw new AtlaSentError(\n `action must be in dot-notation format (e.g. \"production.deploy\"). Got: ${JSON.stringify(request.action)}`,\n { code: \"bad_request\" },\n );\n }\n const client = getClient();\n\n // 1. Evaluate (same logic as protect()).\n const evaluation = await client.evaluate(request);\n\n if (evaluation.decision !== \"allow\") {\n throw new AtlaSentDeniedError({\n decision: wireDecisionToDenied(evaluation.decision),\n evaluationId: evaluation.permitId,\n reason: evaluation.reason,\n auditHash: evaluation.auditHash,\n });\n }\n\n // 2. Extract environment, compute execution_hash, verify permit.\n const environment = request.context?.environment as string | undefined;\n if (!environment) {\n throw new AtlaSentError(\n 'context.environment is required. Pass the environment where this action executes (e.g. \"production\", \"staging\").',\n { code: \"bad_request\" },\n );\n }\n\n const evaluatePayload = {\n action_type: request.action,\n actor_id: request.agent,\n context: request.context ?? {},\n };\n const execution_hash = await computeExecutionHash(evaluatePayload);\n\n const verifyRequest: {\n permitId: string;\n agent: string;\n action: string;\n context?: Record<string, unknown>;\n environment: string;\n execution_hash?: string;\n } = {\n permitId: evaluation.permitId,\n agent: request.agent,\n action: request.action,\n environment,\n ...(execution_hash ? { execution_hash } : {}),\n };\n if (request.context !== undefined) verifyRequest.context = request.context;\n const verification = await client.verifyPermit(verifyRequest);\n\n if (!verification.verified) {\n const outcome = normalizePermitOutcome(verification.outcome);\n throw new AtlaSentDeniedError({\n decision: \"deny\",\n evaluationId: evaluation.permitId,\n reason: `Permit failed verification (${verification.outcome})`,\n auditHash: evaluation.auditHash,\n ...(outcome !== undefined && { outcome }),\n });\n }\n\n // 3. Build the receipt.\n const contextHash = await computeContextHash(request.context ?? {});\n\n const whyTrace = buildWhyTrace(\n \"allow\",\n evaluation.reasons,\n opts.constraintTrace ?? null,\n );\n\n const issuedAt = new Date().toISOString();\n const receiptId = generateReceiptId();\n const orgId = evaluation.permit?.orgId ?? \"\";\n\n const payload = buildDecisionReceiptPayload({\n receipt_id: receiptId,\n evaluation_id: evaluation.evaluationId,\n org_id: orgId,\n decision: \"allow\",\n action: request.action,\n actor: request.agent,\n resource_type:\n (request.context?.resource_type as string | undefined) ?? null,\n resource_id:\n (request.context?.resource_id as string | undefined) ?? null,\n reasons: evaluation.reasons,\n why_summary: whyTrace.summary,\n permit_id: evaluation.permitId,\n permit_hash: verification.permitHash,\n audit_hash: evaluation.auditHash,\n context_hash: contextHash,\n issued_at: issuedAt,\n });\n\n // 4. Sign if secret is provided.\n let signature: string | null = null;\n let algorithm: DecisionReceiptAlgorithm = \"none\";\n\n if (opts.signingSecret) {\n signature = await signDecisionReceiptHmac(payload, opts.signingSecret);\n algorithm = \"hmac-sha256\";\n }\n\n const receipt: DecisionReceipt = {\n receipt_id: receiptId,\n evaluation_id: evaluation.evaluationId,\n org_id: orgId,\n decision: \"allow\",\n action: request.action,\n actor: request.agent,\n resource_type:\n (request.context?.resource_type as string | undefined) ?? null,\n resource_id:\n (request.context?.resource_id as string | undefined) ?? null,\n reasons: evaluation.reasons,\n why_trace:\n opts.constraintTrace !== undefined ? whyTrace : null,\n permit_id: evaluation.permitId,\n permit_hash: verification.permitHash,\n audit_hash: evaluation.auditHash,\n context_hash: contextHash,\n issued_at: issuedAt,\n expires_at: null,\n algorithm,\n signature,\n signing_key_id: opts.signingKeyId ?? null,\n payload,\n };\n\n return {\n permitId: evaluation.permitId,\n permitHash: verification.permitHash,\n auditHash: evaluation.auditHash,\n reason: evaluation.reason,\n timestamp: verification.timestamp,\n permitExpiresAt: verification.expiresAt ?? null,\n receipt,\n };\n}\n","/**\n * `requirePermit` — higher-order execution gate for dangerous operations.\n *\n * Wraps any dangerous operation so it can only run after AtlaSent\n * authorizes it end-to-end (evaluate + verifyPermit). If authorization\n * is denied or the transport fails, the executor is never called.\n *\n * ```ts\n * import atlasent from \"@atlasent/sdk\";\n *\n * await atlasent.requirePermit(\n * {\n * action_type: \"database.table.drop\",\n * actor_id: \"agent:code-agent\",\n * resource_id: \"prod-db.users\",\n * environment: \"production\",\n * context: { reversibility: \"irreversible\", blast_radius: \"customer_data\" },\n * },\n * async () => {\n * await db.raw(\"DROP TABLE users\");\n * },\n * );\n * ```\n *\n * Unlike calling the executor directly, dangerous code cannot bypass\n * this gate: if `requirePermit` throws, the executor never runs.\n */\n\nimport { protect } from \"./protect.js\";\n\n/**\n * Catalog of built-in protected action types, mirroring `CanonicalProtectedActionType`\n * in the OpenAPI spec. Use these constants as `action_type` values in\n * {@link requirePermit} calls instead of bare strings.\n *\n * ```ts\n * await requirePermit(\n * { action_type: CanonicalProtectedActionType.DATABASE_TABLE_DELETE, ... },\n * () => db.raw(\"DELETE FROM users\"),\n * );\n * ```\n */\nexport const CanonicalProtectedActionType = {\n PRODUCTION_DEPLOY: \"production.deploy\",\n HR_EMPLOYEE_OFFBOARD: \"hr.employee.offboard\",\n HR_ACCESS_REVOKE: \"hr.access.revoke\",\n HR_ROLE_ESCALATE: \"hr.role.escalate\",\n ML_MODEL_PROMOTE: \"ml.model.promote\",\n ML_MODEL_RETIRE: \"ml.model.retire\",\n ML_MODEL_FINE_TUNE: \"ml.model.fine_tune\",\n CUSTOMER_DATA_DELETE: \"customer.data.delete\",\n CONTRACT_EXECUTE: \"contract.execute\",\n CONTRACT_AMEND: \"contract.amend\",\n PRICING_RULE_PUBLISH: \"pricing.rule.publish\",\n PRICING_DISCOUNT_APPROVE: \"pricing.discount.approve\",\n SECURITY_INCIDENT_ESCALATE: \"security.incident.escalate\",\n SECURITY_ACCESS_QUARANTINE: \"security.access.quarantine\",\n ACCESS_CERT_REVOKE: \"access.cert.revoke\",\n PERIOD_CLOSE_CERTIFY: \"period.close.certify\",\n DATABASE_MIGRATION_APPLY: \"database.migration.apply\",\n DATABASE_SCHEMA_DROP: \"database.schema.drop\",\n DATABASE_TABLE_DELETE: \"database.table.delete\",\n} as const;\n\nexport type CanonicalProtectedActionType =\n (typeof CanonicalProtectedActionType)[keyof typeof CanonicalProtectedActionType];\n\n/**\n * Describes a potentially dangerous action to be authorized before\n * the executor runs. Passed as the first argument to {@link requirePermit}.\n */\nexport type ProtectedAction = {\n /** Namespaced action type — e.g. \"database.table.drop\". */\n action_type: string;\n /** Agent or user requesting the action — e.g. \"agent:deploy-bot\". */\n actor_id: string;\n /** Resource being acted upon — e.g. \"prod-db.users\". */\n resource_id: string;\n /** Target deployment environment. Controls policy strictness. */\n environment: \"development\" | \"staging\" | \"production\";\n /** Arbitrary risk context forwarded to the policy engine. */\n context: Record<string, unknown>;\n};\n\n/**\n * Authorize a dangerous operation before running it.\n *\n * Calls `protect` (evaluate + verifyPermit) with the {@link ProtectedAction}\n * descriptor. If authorization succeeds, calls `execute` and returns its\n * result. On any failure — policy deny, invalid permit, transport error —\n * `execute` is never called and the error propagates to the caller.\n *\n * This is the pattern primitive: dangerous code should be callable\n * **only** through this wrapper. In code review, any operation in the list\n * below is illegal unless it appears inside `requirePermit(...)`:\n *\n * - `db.raw(...)` / `DROP TABLE` / `DELETE FROM` / `TRUNCATE TABLE`\n * - `exec(...)` / `rm -rf` / `kubectl delete` / `terraform destroy`\n * - `stripe.transfers.create(...)` / `github.deployments.create(...)`\n * - `railway.volumes.delete(...)` / `supabase.from(...).delete()`\n */\nexport async function requirePermit<T>(\n action: ProtectedAction,\n execute: () => Promise<T>,\n): Promise<T> {\n await protect({\n agent: action.actor_id,\n action: action.action_type,\n context: {\n resource_id: action.resource_id,\n environment: action.environment,\n ...action.context,\n },\n });\n return execute();\n}\n\n/**\n * Patterns for shell / database commands that are dangerous and must\n * be wrapped in {@link requirePermit} before execution.\n */\nconst DESTRUCTIVE_PATTERNS: ReadonlyArray<RegExp> = [\n /rm\\s+-rf/,\n /DROP\\s+TABLE/i,\n /DROP\\s+DATABASE/i,\n /DELETE\\s+FROM/i,\n /TRUNCATE\\s+TABLE/i,\n /railway\\s+volume\\s+delete/i,\n /kubectl\\s+delete/i,\n /terraform\\s+destroy/i,\n];\n\n/**\n * Classify a shell or database command as destructive.\n *\n * Returns the namespaced action type (e.g. `\"destructive.command\"`) when the\n * command matches a known dangerous pattern, or `null` when it appears safe.\n * Use the return value as `action_type` in a {@link requirePermit} call before\n * executing the command:\n *\n * ```ts\n * async function runCommand(command: string, actorId: string) {\n * const actionType = classifyCommand(command);\n * if (actionType) {\n * return requirePermit(\n * { action_type: actionType, actor_id: actorId, resource_id: command,\n * environment: \"production\", context: { command } },\n * () => exec(command),\n * );\n * }\n * return exec(command);\n * }\n * ```\n */\nexport function classifyCommand(command: string): string | null {\n return DESTRUCTIVE_PATTERNS.some((p) => p.test(command))\n ? \"destructive.command\"\n : null;\n}\n","/**\n * `atlasent.withPermit(...)` — the lexically-scoped form of\n * {@link protect}. TypeScript mirror of the Python SDK's\n * ``atlasent.with_permit(...)``.\n *\n * Same execution-boundary contract as {@link protect}: evaluate +\n * verifyPermit run end-to-end before the executor is invoked, and the\n * executor cannot run unless a verified {@link Permit} was returned.\n * The difference is purely lexical — `withPermit` binds the execution\n * to the permit's lifetime via a callback, so the call site reads as\n * \"execute this body under a permit\" rather than \"fetch a permit and\n * run code under it manually.\"\n *\n * ```ts\n * import atlasent from \"@atlasent/sdk\";\n *\n * const ok = await atlasent.withPermit(\n * {\n * agent: \"deploy-bot\",\n * action: \"production.deploy\",\n * context: { commit, approver },\n * },\n * async (permit) => {\n * const result = await runDeploy(commit);\n * return { ok: true, permitId: permit.permitId, result };\n * },\n * );\n * ```\n *\n * Pick the form that fits the call site:\n *\n * - {@link protect} when the caller wants the verified permit as a\n * value (e.g. to pass it across a process boundary, persist it\n * alongside their own record, or interleave it with non-trivial\n * control flow).\n * - {@link withPermit} when the action body is a single lexical scope\n * and \"no permit, no execution\" is the only thing the call site\n * needs to express.\n *\n * Both surfaces use the same underlying primitive and produce the\n * same audit-chain entry.\n */\n\nimport { protect, type Permit, type ProtectRequest } from \"./protect.js\";\n\n/**\n * Authorize a request end-to-end and invoke `fn` only on a verified\n * permit.\n *\n * @param request Same shape as {@link ProtectRequest}.\n * @param fn Invoked with the verified {@link Permit}. Its return\n * value (awaited if it is a promise) is propagated to the caller.\n *\n * @returns Whatever `fn` returns.\n *\n * @throws {AtlaSentDeniedError} Policy denied, hold/escalate, or\n * permit failed verification. `fn` is never invoked.\n * @throws {AtlaSentError} Transport, timeout, auth, rate-limit, or\n * server error. `fn` is never invoked.\n *\n * Errors thrown inside `fn` propagate untouched — the permit is\n * already consumed by the verify step in v1, so there is no\n * compensating revoke.\n */\nexport async function withPermit<T>(\n request: ProtectRequest,\n fn: (permit: Permit) => Promise<T> | T,\n): Promise<T> {\n const permit = await protect(request);\n return await fn(permit);\n}\n","/**\n * Approval/Override Runtime — fail-closed bridge between policy `hold`/`escalate`\n * outcomes and human approval.\n *\n * `protectOrEscalate()` — like `protect()` but handles hold/escalate by:\n * 1. Creating an HITL escalation via POST /v1/hitl\n * 2. Polling until approved, rejected, or timed out\n * 3. Returning an `ApprovalPermit` on approval; throwing on rejection/timeout\n *\n * `createEscalation()` — create an HITL escalation request (lower-level)\n * `waitForEscalationApproval()` — poll until the escalation resolves\n * `requestOverride()` — request a post-hoc override for a denied evaluation\n * `configureApprovalRuntime()` — set API key / base URL once\n */\n\nimport { AtlaSentDeniedError, AtlaSentError } from \"./errors.js\";\nimport type {\n HitlCreateRequest,\n HitlEscalation,\n HitlFallbackDecision,\n HitlQuorumTier,\n} from \"./hitl.js\";\nimport type { CreateOverrideRequest, OverrideV1 } from \"./overrides.js\";\nimport { protect, type Permit, type ProtectRequest } from \"./protect.js\";\n\n// ── Module-level configuration singleton ────────────────────────────────────\n\nexport interface ApprovalRuntimeConfig {\n apiKey?: string;\n baseUrl?: string;\n /** Per-request HTTP timeout in ms. Default 30_000. */\n timeoutMs?: number;\n}\n\nlet _runtimeConfig: ApprovalRuntimeConfig = {};\n\n/**\n * Configure the Approval Runtime singleton. Optional — if `ATLASENT_API_KEY` is\n * set in the environment, the runtime works without configuration. Calling this\n * again merges into the existing config.\n */\nexport function configureApprovalRuntime(config: ApprovalRuntimeConfig): void {\n _runtimeConfig = { ..._runtimeConfig, ...config };\n}\n\nfunction resolveConfig(overrides?: { apiKey?: string; baseUrl?: string }): {\n apiKey: string;\n baseUrl: string;\n requestTimeoutMs: number;\n} {\n const apiKey =\n overrides?.apiKey ??\n _runtimeConfig.apiKey ??\n (typeof process !== \"undefined\" && process.env\n ? process.env[\"ATLASENT_API_KEY\"]\n : undefined);\n\n if (!apiKey) {\n throw new AtlaSentError(\n \"ApprovalRuntime: no API key configured. Set ATLASENT_API_KEY or call configureApprovalRuntime({ apiKey }).\",\n { code: \"invalid_api_key\" },\n );\n }\n\n return {\n apiKey,\n baseUrl:\n overrides?.baseUrl ??\n _runtimeConfig.baseUrl ??\n \"https://api.atlasent.io\",\n requestTimeoutMs: _runtimeConfig.timeoutMs ?? 30_000,\n };\n}\n\n// ── Thin HTTP helpers (avoids importing the full AtlaSentClient) ─────────────\n\ninterface ResolvedConfig {\n apiKey: string;\n baseUrl: string;\n requestTimeoutMs: number;\n}\n\nasync function apiPost<T>(\n path: string,\n body: unknown,\n cfg: ResolvedConfig,\n): Promise<T> {\n const url = `${cfg.baseUrl}${path}`;\n let resp: Response;\n try {\n resp = await fetch(url, {\n method: \"POST\",\n headers: {\n Accept: \"application/json\",\n Authorization: `Bearer ${cfg.apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(cfg.requestTimeoutMs),\n });\n } catch (err) {\n throw new AtlaSentError(\n `ApprovalRuntime: network error calling ${path}`,\n { code: \"network\", cause: err },\n );\n }\n\n if (!resp.ok) {\n const text = await resp.text().catch(() => \"\");\n const code =\n resp.status === 401\n ? \"invalid_api_key\"\n : resp.status === 403\n ? \"forbidden\"\n : resp.status === 429\n ? \"rate_limited\"\n : \"server_error\";\n throw new AtlaSentError(\n `ApprovalRuntime: API error ${resp.status} at ${path}: ${text.slice(0, 200)}`,\n { code, status: resp.status },\n );\n }\n return resp.json() as Promise<T>;\n}\n\nasync function apiGet<T>(path: string, cfg: ResolvedConfig): Promise<T> {\n const url = `${cfg.baseUrl}${path}`;\n let resp: Response;\n try {\n resp = await fetch(url, {\n method: \"GET\",\n headers: {\n Accept: \"application/json\",\n Authorization: `Bearer ${cfg.apiKey}`,\n },\n signal: AbortSignal.timeout(cfg.requestTimeoutMs),\n });\n } catch (err) {\n throw new AtlaSentError(\n `ApprovalRuntime: network error calling ${path}`,\n { code: \"network\", cause: err },\n );\n }\n\n if (!resp.ok) {\n const text = await resp.text().catch(() => \"\");\n const code =\n resp.status === 401\n ? \"invalid_api_key\"\n : resp.status === 403\n ? \"forbidden\"\n : resp.status === 429\n ? \"rate_limited\"\n : \"server_error\";\n throw new AtlaSentError(\n `ApprovalRuntime: API error ${resp.status} at ${path}: ${text.slice(0, 200)}`,\n { code, status: resp.status },\n );\n }\n return resp.json() as Promise<T>;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// ── Core types ────────────────────────────────────────────────────────────────\n\n/** Opaque handle returned when an escalation is created. */\nexport interface EscalationHandle {\n readonly escalationId: string;\n readonly createdAt: string;\n readonly timeoutAt: string | null;\n readonly assignedToRole: string | null;\n}\n\n/** Terminal resolution status of an escalation. */\nexport type ApprovalStatus = \"approved\" | \"rejected\" | \"timed_out\";\n\n/** Full outcome returned when an escalation resolves. */\nexport interface EscalationOutcome {\n readonly status: ApprovalStatus;\n readonly escalation: HitlEscalation;\n readonly resolvedBy: string | null;\n readonly resolutionNote: string | null;\n readonly resolvedAt: string | null;\n}\n\n/**\n * Thrown by `protectOrEscalate` / `waitForEscalationApproval` when the\n * human reviewer rejects the escalation.\n */\nexport class EscalationDeniedError extends Error {\n override readonly name = \"EscalationDeniedError\" as const;\n readonly escalationId: string;\n readonly outcome: EscalationOutcome;\n\n constructor(outcome: EscalationOutcome) {\n super(\n `Escalation ${outcome.escalation.id} was rejected` +\n (outcome.resolutionNote ? `: ${outcome.resolutionNote}` : \"\"),\n );\n this.escalationId = outcome.escalation.id;\n this.outcome = outcome;\n }\n}\n\n/**\n * Thrown by `protectOrEscalate` / `waitForEscalationApproval` when the\n * client-side wait window expires before the escalation resolves.\n */\nexport class EscalationTimeoutError extends Error {\n override readonly name = \"EscalationTimeoutError\" as const;\n readonly escalationId: string;\n readonly outcome: EscalationOutcome;\n\n constructor(outcome: EscalationOutcome) {\n super(\n `Escalation ${outcome.escalation.id} timed out waiting for approval`,\n );\n this.escalationId = outcome.escalation.id;\n this.outcome = outcome;\n }\n}\n\n// ── createEscalation ──────────────────────────────────────────────────────────\n\n/**\n * Options for creating an HITL escalation. Extends `HitlCreateRequest` with\n * API-key and base-URL overrides for per-call credential injection.\n */\nexport interface CreateEscalationOptions extends Partial<HitlCreateRequest> {\n apiKey?: string;\n baseUrl?: string;\n}\n\n/**\n * Create an HITL escalation via POST /v1/hitl.\n *\n * The escalation is placed in `pending` status; a reviewer must approve or\n * reject it before the original action can proceed. Use\n * `waitForEscalationApproval()` to poll until the escalation resolves.\n */\nexport async function createEscalation(\n opts: CreateEscalationOptions,\n): Promise<EscalationHandle> {\n const { apiKey, baseUrl, ...hitlBody } = opts;\n const cfg = resolveConfig({\n ...(apiKey !== undefined ? { apiKey } : {}),\n ...(baseUrl !== undefined ? { baseUrl } : {}),\n });\n\n const body: HitlCreateRequest = {\n agent_id: hitlBody.agent_id ?? \"unknown\",\n escalation_reason:\n hitlBody.escalation_reason ?? \"Policy hold — awaiting human approval\",\n ...hitlBody,\n };\n\n const escalation = await apiPost<HitlEscalation>(\"/v1/hitl\", body, cfg);\n return {\n escalationId: escalation.id,\n createdAt: escalation.created_at,\n timeoutAt: escalation.timeout_at ?? null,\n assignedToRole: escalation.assigned_to_role ?? null,\n };\n}\n\n// ── waitForEscalationApproval ─────────────────────────────────────────────────\n\nexport interface WaitForApprovalOptions {\n escalationId: string;\n /** Max milliseconds to wait for a human to respond. Default 600_000 (10 min). */\n waitMs?: number;\n /** How often to poll the API. Default 5000ms. Minimum 1000ms. */\n pollIntervalMs?: number;\n apiKey?: string;\n baseUrl?: string;\n}\n\n/**\n * Poll GET /v1/escalations/:id until the escalation reaches a terminal status\n * (`approved`, `auto_approved`, `rejected`, or `timed_out`).\n *\n * Returns the resolved outcome regardless of approval/rejection — the caller\n * decides whether to throw. Use `protectOrEscalate()` for the opinionated flow.\n */\nexport async function waitForEscalationApproval(\n opts: WaitForApprovalOptions,\n): Promise<EscalationOutcome> {\n const cfg = resolveConfig({\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n const waitMs = opts.waitMs ?? 600_000;\n const pollIntervalMs = Math.max(opts.pollIntervalMs ?? 5_000, 1_000);\n const deadline = Date.now() + waitMs;\n\n const toOutcome = (escalation: HitlEscalation): EscalationOutcome | null => {\n const terminal =\n escalation.status === \"approved\" ||\n escalation.status === \"rejected\" ||\n escalation.status === \"auto_approved\" ||\n escalation.status === \"timed_out\";\n\n if (!terminal) return null;\n\n const status: ApprovalStatus =\n escalation.status === \"approved\" || escalation.status === \"auto_approved\"\n ? \"approved\"\n : escalation.status === \"timed_out\"\n ? \"timed_out\"\n : \"rejected\";\n\n return {\n status,\n escalation,\n resolvedBy: escalation.resolved_by ?? null,\n resolutionNote: escalation.resolution_note ?? null,\n resolvedAt: escalation.resolved_at ?? null,\n };\n };\n\n while (Date.now() < deadline) {\n const escalation = await apiGet<HitlEscalation>(\n `/v1/escalations/${opts.escalationId}`,\n cfg,\n );\n const outcome = toOutcome(escalation);\n if (outcome) return outcome;\n\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n await sleep(Math.min(pollIntervalMs, remaining));\n }\n\n // Final fetch at deadline\n const escalation = await apiGet<HitlEscalation>(\n `/v1/escalations/${opts.escalationId}`,\n cfg,\n );\n const outcome = toOutcome(escalation);\n if (outcome) return outcome;\n\n return {\n status: \"timed_out\",\n escalation,\n resolvedBy: null,\n resolutionNote: \"Client-side wait timeout elapsed\",\n resolvedAt: null,\n };\n}\n\n// ── protectOrEscalate ─────────────────────────────────────────────────────────\n\n/**\n * A verified Permit granted via human approval of an HITL escalation.\n * Extends {@link Permit} with escalation provenance fields.\n *\n * `approvalBasis: \"direct_policy\"` — action was allowed directly by policy;\n * no escalation was created.\n *\n * `approvalBasis: \"human_approval\"` — the policy returned `hold`/`escalate`;\n * a human reviewer approved the escalation.\n *\n * Guards and enforcement adapters should treat both as equivalent authorization\n * proof; auditors can distinguish them via `escalationId`.\n */\nexport interface ApprovalPermit extends Permit {\n /**\n * The HITL escalation ID that authorized this action. Empty string when\n * the action was directly allowed by policy (no escalation needed).\n */\n readonly escalationId: string;\n /** Identity of the reviewer who approved, or `null` for `auto_approved`. */\n readonly resolvedBy: string | null;\n readonly resolutionNote: string | null;\n readonly resolvedAt: string;\n readonly approvalBasis: \"direct_policy\" | \"human_approval\";\n}\n\nexport interface ProtectOrEscalateOptions {\n /** Agent ID recorded on the escalation. Defaults to `request.agent`. */\n agentId?: string;\n /** Human-readable reason surfaced in the reviewer's queue. */\n escalationReason?: string;\n /** The proposed action payload shown to reviewers. Defaults to `request.context`. */\n proposedAction?: Record<string, unknown>;\n riskScore?: number;\n assignedToRole?: string;\n quorumRequired?: HitlQuorumTier;\n fallbackDecision?: HitlFallbackDecision;\n /** ISO-8601 — when the escalation should auto-resolve per server policy. */\n timeoutAt?: string;\n metadata?: Record<string, unknown>;\n /** Max ms to wait for a human decision. Default 600_000 (10 min). */\n waitMs?: number;\n /** How often to poll. Default 5000ms. */\n pollIntervalMs?: number;\n apiKey?: string;\n baseUrl?: string;\n /** Called with the EscalationHandle immediately after it is created. */\n onEscalationCreated?: (handle: EscalationHandle) => void;\n}\n\n/**\n * Authorize an action end-to-end, automatically escalating to human review\n * when the policy returns `hold` or `escalate`.\n *\n * **Directly allowed** → returns `ApprovalPermit` with\n * `approvalBasis: \"direct_policy\"` (same semantics as `protect()`).\n *\n * **Hold / escalate** → creates an HITL escalation, polls for a human\n * decision, and returns `ApprovalPermit` with\n * `approvalBasis: \"human_approval\"` on approval.\n *\n * **Throws**:\n * - {@link EscalationDeniedError} — reviewer rejected the escalation\n * - {@link EscalationTimeoutError} — wait window elapsed without a decision\n * - {@link AtlaSentDeniedError} — hard deny (not hold/escalate); fail-closed\n * - {@link AtlaSentError} — transport / auth / server failure; fail-closed\n */\nexport async function protectOrEscalate(\n request: ProtectRequest,\n opts: ProtectOrEscalateOptions = {},\n): Promise<ApprovalPermit> {\n try {\n const permit = await protect(request);\n return {\n ...permit,\n escalationId: \"\",\n resolvedBy: null,\n resolutionNote: null,\n resolvedAt: permit.timestamp,\n approvalBasis: \"direct_policy\",\n };\n } catch (err) {\n if (\n !(err instanceof AtlaSentDeniedError) ||\n (err.decision !== \"hold\" && err.decision !== \"escalate\")\n ) {\n throw err;\n }\n }\n\n // Create HITL escalation\n const proposedAction =\n opts.proposedAction ?? (request.context as Record<string, unknown> | undefined);\n const handle = await createEscalation({\n agent_id: opts.agentId ?? request.agent,\n escalation_reason:\n opts.escalationReason ??\n `Policy hold for \"${request.action}\" by \"${request.agent}\"`,\n ...(proposedAction !== undefined ? { proposed_action: proposedAction } : {}),\n ...(opts.riskScore !== undefined ? { risk_score: opts.riskScore } : {}),\n ...(opts.assignedToRole !== undefined ? { assigned_to_role: opts.assignedToRole } : {}),\n ...(opts.quorumRequired !== undefined ? { quorum_required: opts.quorumRequired } : {}),\n ...(opts.fallbackDecision !== undefined ? { fallback_decision: opts.fallbackDecision } : {}),\n ...(opts.timeoutAt !== undefined ? { timeout_at: opts.timeoutAt } : {}),\n ...(opts.metadata !== undefined ? { metadata: opts.metadata } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n\n opts.onEscalationCreated?.(handle);\n\n // Wait for human decision\n const outcome = await waitForEscalationApproval({\n escalationId: handle.escalationId,\n ...(opts.waitMs !== undefined ? { waitMs: opts.waitMs } : {}),\n ...(opts.pollIntervalMs !== undefined ? { pollIntervalMs: opts.pollIntervalMs } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n\n if (outcome.status === \"rejected\") throw new EscalationDeniedError(outcome);\n if (outcome.status === \"timed_out\") throw new EscalationTimeoutError(outcome);\n\n // Approved — return ApprovalPermit\n return {\n permitId: `escl_${handle.escalationId}`,\n permitHash: \"\",\n auditHash: outcome.escalation.id,\n reason: outcome.resolutionNote ?? \"Approved by human reviewer\",\n timestamp: outcome.resolvedAt ?? new Date().toISOString(),\n permitExpiresAt: null,\n escalationId: handle.escalationId,\n resolvedBy: outcome.resolvedBy,\n resolutionNote: outcome.resolutionNote,\n resolvedAt: outcome.resolvedAt ?? new Date().toISOString(),\n approvalBasis: \"human_approval\",\n };\n}\n\n// ── requestOverride ────────────────────────────────────────────────────────────\n\nexport interface RequestOverrideOptions {\n /** Human-readable justification. Required; max 2000 characters. */\n reason: string;\n /** The evaluation ID that was denied and should be overridden. */\n evaluationId: string;\n /** How long this override is valid, in seconds. Max 604800 (7 days). */\n ttlSeconds?: number;\n /** Arbitrary metadata to attach (e.g. liability attribution context). */\n metadata?: Record<string, unknown>;\n apiKey?: string;\n baseUrl?: string;\n}\n\n/**\n * Request a post-hoc override for a denied evaluation via POST /v1/overrides.\n *\n * The override starts in `pending` status and takes effect only after an\n * authorized actor approves it. Subsequent evaluations for the same action\n * will return `allow` while the override is `approved` and within its TTL.\n *\n * Attach `metadata.requested_by` for liability attribution.\n */\nexport async function requestOverride(\n opts: RequestOverrideOptions,\n): Promise<OverrideV1> {\n const cfg = resolveConfig({\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n\n const body: CreateOverrideRequest = {\n reason: opts.reason,\n evaluationId: opts.evaluationId,\n ...(opts.ttlSeconds !== undefined && { ttlSeconds: opts.ttlSeconds }),\n ...(opts.metadata !== undefined && { metadata: opts.metadata }),\n };\n\n return apiPost<OverrideV1>(\"/v1/overrides\", body, cfg);\n}\n","/**\n * Context Layer — typed, validated, redaction-aware context for AtlaSent\n * evaluations.\n *\n * The current `protect()` / `evaluate()` API accepts\n * `context?: Record<string, unknown>` — a black box the policy engine\n * treats as an opaque blob. This module provides:\n *\n * 1. **Typed sub-schemas** — `ActorContext`, `ResourceContext`,\n * `EnvironmentContext`, `ActionMetaContext`, `HistoricalContext`, and\n * `ActionContext` (the union of all five).\n *\n * 2. **`buildActionContext()`** — a structured constructor that normalises\n * flat shorthands and validates at build time.\n *\n * 3. **`validateActionContext()`** — non-throwing validation that returns\n * typed `ContextValidationError[]` and `ContextValidationWarning[]`.\n *\n * 4. **`redactContext()`** — strips / masks sensitive fields before\n * logging or storing in receipts / evidence bundles.\n *\n * 5. **`flattenActionContext()`** — converts a typed `ActionContext` to the\n * flat `Record<string, unknown>` that `protect()` / `evaluate()` accept.\n *\n * ### Usage\n *\n * ```ts\n * import atlasent, { buildActionContext, redactContext } from \"@atlasent/sdk\";\n *\n * const ctx = buildActionContext({\n * actor: { id: \"user:alice\", type: \"human\", roles: [\"deploy_engineer\"] },\n * environment: { name: \"production\", region: \"us-east-1\" },\n * resource: { type: \"service\", id: \"api-gateway\", sensitivity: \"restricted\" },\n * org_id: \"org_acme\",\n * environment_id: \"env_prod_us_east\",\n * });\n *\n * const permit = await atlasent.protect({\n * agent: \"deploy-bot\",\n * action: \"production.deploy\",\n * context: flattenActionContext(ctx),\n * });\n *\n * // Store the redacted context alongside the permit — no PII in evidence.\n * const safe = redactContext(ctx);\n * await db.permits.create({ permitId: permit.permitId, context: safe });\n * ```\n */\n\n// ── Typed sub-schemas ──────────────────────────────────────────────────────────────\n\n/**\n * Identity of the actor requesting the action.\n *\n * `id` is the only required field; all others are policy-engine hints.\n * Omitting optional fields may cause deny on policies that gate on role\n * membership, trust level, or session binding.\n */\nexport interface ActorContext {\n /** Stable, opaque actor identifier (e.g. `\"user:alice\"`, `\"agent:deploy-bot\"`). */\n id: string;\n /** Human-readable label for audit trails and reviewer UIs. */\n label?: string;\n /** Discriminates human vs. AI agent vs. service account. */\n type?: \"human\" | \"agent\" | \"service_account\" | \"system\";\n /** Roles the actor holds at evaluation time. */\n roles?: string[];\n /** Trust tier. Policy rules can gate on this value. */\n trust_level?: \"high\" | \"medium\" | \"low\" | \"untrusted\" | string;\n /** Actor email — required for human-approval escalation UIs. */\n email?: string;\n /** Observed client IP — used in geo-restriction and rate-limit rules. */\n ip?: string;\n /** Session or OAuth token ID for replay-detection rules. */\n session_id?: string;\n /**\n * Organization this actor belongs to. Populated from\n * `BuildActionContextInput.org_id` when the actor has no explicit org_id.\n * Used by cross-tenant policy checks and usage metering.\n */\n org_id?: string;\n}\n\n/**\n * The resource the action targets.\n *\n * `type` is a stable string like `\"database.table\"`, `\"repository\"`,\n * or `\"payment\"`. `sensitivity` drives redaction rules in evidence\n * bundles — `\"restricted\"` fields are masked even in signed receipts.\n */\nexport interface ResourceContext {\n /** Stable resource type slug (e.g. `\"database.table\"`, `\"service\"`, `\"payment\"`). */\n type?: string;\n /** Opaque resource identifier (e.g. table name, repo name, payment ID). */\n id?: string;\n /** Human-readable name for reviewer UIs. */\n name?: string;\n /** Data-sensitivity classification — drives receipt redaction. */\n sensitivity?: \"public\" | \"internal\" | \"confidential\" | \"restricted\";\n /** Owner org or tenant of the resource. */\n owner?: string;\n /** Cloud or datacenter region where the resource lives. */\n region?: string;\n}\n\n/**\n * Deployment environment and infrastructure context.\n *\n * `name` is the field protect() reads to set the `environment` field\n * on the verify-permit request. Set it explicitly in runtime contexts\n * so verification is bound to the executing environment.\n */\nexport interface EnvironmentContext {\n /** Deployment tier (for example, `\"production\"` or `\"staging\"`). */\n name?: \"production\" | \"staging\" | \"development\" | \"test\" | string;\n /** Cloud or datacenter region (e.g. `\"us-east-1\"`, `\"eu-west-1\"`). */\n region?: string;\n /** CI/CD pipeline name (e.g. `\"github_actions\"`, `\"jenkins\"`). */\n pipeline?: string;\n /** Git SHA, image tag, or artifact version being deployed. */\n version?: string;\n}\n\n/**\n * Action-specific metadata that shapes policy decisions.\n *\n * `risk_level` and `reversibility` are the two fields most commonly\n * referenced by policy rules. Financial policies additionally gate on\n * `estimated_amount` and `currency`.\n */\nexport interface ActionMetaContext {\n /** Caller-assessed risk level of this specific invocation. */\n risk_level?: \"critical\" | \"high\" | \"medium\" | \"low\";\n /** Whether the action can be undone after execution. */\n reversibility?: \"reversible\" | \"irreversible\" | \"partial\";\n /** Free-text description shown to human reviewers in the HITL UI. */\n description?: string;\n /** Estimated monetary amount for financial actions. */\n estimated_amount?: number;\n /** ISO 4217 currency code (e.g. `\"USD\"`, `\"EUR\"`). */\n currency?: string;\n}\n\n/**\n * Historical and behavioral signals about the actor.\n *\n * These are caller-computed signals from the caller's own systems —\n * AtlaSent does not maintain the source-of-truth; it only evaluates\n * policy against the values provided here.\n */\nexport interface HistoricalContext {\n /** Number of times this actor performed this action in the past 24h. */\n recent_action_count?: number;\n /** ISO-8601 timestamp of the actor's most recent action of this type. */\n last_action_at?: string;\n /** True when the actor has unresolved policy violations on record. */\n has_violations?: boolean;\n /** Arbitrary caller-defined risk signals from upstream systems. */\n risk_signals?: Record<string, unknown>;\n}\n\n/**\n * The canonical typed context for AtlaSent evaluations.\n *\n * All sub-schemas are optional at the TypeScript level; policy rules\n * determine which fields are effectively required. Missing fields that\n * a policy expects will typically result in a `deny` decision.\n *\n * Flat shorthands (`resource_type`, `resource_id`, `environment_name`)\n * are supported for backward compatibility with existing\n * `Record<string, unknown>` call sites. `buildActionContext()` merges\n * them into the nested sub-schemas automatically.\n *\n * The `[key: string]: unknown` index signature allows arbitrary\n * custom fields to pass through to the policy engine unchanged.\n */\nexport interface ActionContext {\n actor?: ActorContext;\n resource?: ResourceContext;\n environment?: EnvironmentContext;\n action_meta?: ActionMetaContext;\n history?: HistoricalContext;\n\n /**\n * Organization ID — scopes the evaluation to this org's policies and\n * usage meters. Propagated from `BuildActionContextInput.org_id` and\n * also set on `actor.org_id` when the actor has no explicit org.\n */\n org_id?: string;\n\n /**\n * ID of the registered `org_environments` row.\n * Future billing dimension: usage will be metered per environment tier.\n * Optional and additive — existing call sites that pass `environment.name`\n * continue to work without providing this field.\n */\n environment_id?: string;\n\n // ── Flat shorthands for backward compat ───────────────────────────\n // These alias the most common nested fields so existing Record<string, unknown>\n // usage continues to work without refactoring. Both the flat and nested\n // forms are sent in flattenActionContext() output so policy rules written\n // against either form continue to work.\n\n /** Alias for `environment.name`. Merged into `environment` by buildActionContext. */\n environment_name?: string;\n /** Alias for `resource.type`. Merged into `resource` by buildActionContext. */\n resource_type?: string;\n /** Alias for `resource.id`. Merged into `resource` by buildActionContext. */\n resource_id?: string;\n\n [key: string]: unknown;\n}\n\n// ── buildActionContext ────────────────────────────────────────────────────────────\n\n/** Input for `buildActionContext()`. Mirrors `ActionContext` with `actor` required. */\nexport interface BuildActionContextInput {\n actor: ActorContext;\n resource?: ResourceContext;\n environment?: EnvironmentContext | string;\n action_meta?: ActionMetaContext;\n history?: HistoricalContext;\n /**\n * Organization ID — scopes the evaluation to this org's policies and\n * usage meters. Propagated to `actor.org_id` when the actor has no\n * explicit org_id, and also set as a top-level `org_id` on the context\n * so policy rules can reference it at `context.org_id`.\n */\n org_id?: string;\n /**\n * ID of the registered `org_environments` row (future billing dimension).\n * Passed through to the flat context as `environment_id`. Optional —\n * callers that pass only `environment.name` continue to work unchanged.\n */\n environment_id?: string;\n /** Arbitrary additional fields to pass through to the policy engine. */\n extra?: Record<string, unknown>;\n}\n\n/**\n * Construct a normalized `ActionContext`.\n *\n * - Accepts `environment` as a string shorthand for `{ name: environment }`.\n * - Populates flat shorthands (`resource_type`, `resource_id`,\n * `environment_name`) from the nested sub-schemas so both the nested and\n * flat forms are present in the output.\n * - Propagates `org_id` to `actor.org_id` when the actor has no explicit org.\n * - Propagates `environment_id` as a top-level context field for billing.\n * - Never throws — validation is a separate step via `validateActionContext()`.\n *\n * ```ts\n * const ctx = buildActionContext({\n * actor: { id: \"agent:deploy-bot\", type: \"agent\" },\n * environment: \"production\",\n * resource: { type: \"service\", id: \"checkout-api\" },\n * org_id: \"org_acme\",\n * environment_id: \"env_prod_us_east\",\n * });\n * ```\n */\nexport function buildActionContext(\n input: BuildActionContextInput,\n): ActionContext {\n const env: EnvironmentContext | undefined =\n typeof input.environment === \"string\"\n ? { name: input.environment }\n : input.environment;\n\n // Propagate org_id to actor when actor has no explicit org_id.\n const actor: ActorContext =\n input.org_id !== undefined && !input.actor.org_id\n ? { ...input.actor, org_id: input.org_id }\n : input.actor;\n\n const ctx: ActionContext = {\n actor,\n ...(input.resource !== undefined && { resource: input.resource }),\n ...(env !== undefined && { environment: env }),\n ...(input.action_meta !== undefined && { action_meta: input.action_meta }),\n ...(input.history !== undefined && { history: input.history }),\n ...(input.org_id !== undefined && { org_id: input.org_id }),\n ...(input.environment_id !== undefined && { environment_id: input.environment_id }),\n ...(input.extra ?? {}),\n };\n\n // Populate flat shorthands from nested sub-schemas\n if (env?.name !== undefined) ctx.environment_name = env.name;\n if (input.resource?.type !== undefined)\n ctx.resource_type = input.resource.type;\n if (input.resource?.id !== undefined) ctx.resource_id = input.resource.id;\n\n return ctx;\n}\n\n// ── validateActionContext ────────────────────────────────────────────────────────\n\n/** A field-level error from `validateActionContext()`. */\nexport interface ContextValidationError {\n /** Dot-delimited field path (e.g. `\"actor.id\"`, `\"action_meta.currency\"`). */\n field: string;\n /** Machine-readable error code. */\n code:\n | \"required\"\n | \"invalid_type\"\n | \"invalid_value\"\n | \"cross_field\"\n | \"sensitive_field\";\n /** Human-readable explanation. */\n message: string;\n}\n\n/** A non-blocking advisory from `validateActionContext()`. */\nexport interface ContextValidationWarning {\n field: string;\n code: \"recommended\" | \"deprecated\" | \"performance\";\n message: string;\n}\n\n/** Result of `validateActionContext()`. */\nexport interface ContextValidationResult {\n valid: boolean;\n errors: ContextValidationError[];\n warnings: ContextValidationWarning[];\n}\n\n/** Options for `validateActionContext()`. */\nexport interface ValidateContextOptions {\n /**\n * Extra fields to treat as required. Dot-delimited paths are supported\n * (e.g. `[\"actor.roles\", \"resource.id\"]`).\n */\n requiredFields?: string[];\n /**\n * When true, skip the built-in cross-field checks (e.g.\n * estimated_amount → currency). Useful for partial contexts.\n */\n skipCrossFieldChecks?: boolean;\n}\n\nfunction getNestedValue(\n obj: Record<string, unknown>,\n path: string,\n): unknown {\n return path.split(\".\").reduce<unknown>((cur, key) => {\n if (cur !== null && typeof cur === \"object\") {\n return (cur as Record<string, unknown>)[key];\n }\n return undefined;\n }, obj);\n}\n\n/**\n * Validate an `ActionContext` without throwing.\n *\n * Returns a `ContextValidationResult` with `valid: false` and a list of\n * typed `errors` / `warnings` when the context is malformed or missing\n * fields. Does not throw — the caller decides what to do with errors.\n *\n * Built-in checks:\n * - `actor.id` is required when `actor` is present\n * - `environment.name` is recommended (warns if absent)\n * - `action_meta.currency` is required when `action_meta.estimated_amount > 0`\n * - ISO 4217 format check for `action_meta.currency`\n * - `history.last_action_at` must be a valid ISO-8601 string\n * - `resource.sensitivity` must be a known value when present\n *\n * ```ts\n * const { valid, errors, warnings } = validateActionContext(ctx, {\n * requiredFields: [\"resource.id\", \"actor.roles\"],\n * });\n * if (!valid) logger.warn(\"Context validation failed\", { errors });\n * ```\n */\nexport function validateActionContext(\n ctx: ActionContext,\n opts: ValidateContextOptions = {},\n): ContextValidationResult {\n const errors: ContextValidationError[] = [];\n const warnings: ContextValidationWarning[] = [];\n\n const ctxObj = ctx as Record<string, unknown>;\n\n // ── actor.id required when actor is provided ────────────────────────\n if (ctx.actor !== undefined) {\n if (!ctx.actor.id || typeof ctx.actor.id !== \"string\") {\n errors.push({\n field: \"actor.id\",\n code: \"required\",\n message: \"actor.id is required when actor is provided\",\n });\n }\n }\n\n // ── environment.name recommended ────────────────────────────────────\n const hasEnvName =\n ctx.environment?.name !== undefined ||\n ctx.environment_name !== undefined;\n if (!hasEnvName) {\n warnings.push({\n field: \"environment.name\",\n code: \"recommended\",\n message:\n \"environment.name is not set; provide it so verify-permit can bind to the execution environment\",\n });\n }\n\n // ── cross-field: estimated_amount requires currency ─────────────────\n if (!opts.skipCrossFieldChecks) {\n const amount = ctx.action_meta?.estimated_amount;\n if (typeof amount === \"number\" && amount > 0) {\n if (!ctx.action_meta?.currency) {\n errors.push({\n field: \"action_meta.currency\",\n code: \"cross_field\",\n message:\n \"action_meta.currency is required when action_meta.estimated_amount > 0\",\n });\n } else if (!/^[A-Z]{3}$/.test(ctx.action_meta.currency)) {\n errors.push({\n field: \"action_meta.currency\",\n code: \"invalid_value\",\n message:\n `action_meta.currency '${ctx.action_meta.currency}' is not a valid ISO 4217 code (expected 3 uppercase letters)`,\n });\n }\n }\n }\n\n // ── history.last_action_at must be ISO-8601 ─────────────────────────\n if (ctx.history?.last_action_at !== undefined) {\n const ts = new Date(ctx.history.last_action_at);\n if (isNaN(ts.getTime())) {\n errors.push({\n field: \"history.last_action_at\",\n code: \"invalid_type\",\n message: `history.last_action_at '${ctx.history.last_action_at}' is not a valid ISO-8601 timestamp`,\n });\n }\n }\n\n // ── resource.sensitivity must be a known value ──────────────────────\n const knownSensitivities = new Set([\n \"public\",\n \"internal\",\n \"confidential\",\n \"restricted\",\n ]);\n if (\n ctx.resource?.sensitivity !== undefined &&\n !knownSensitivities.has(ctx.resource.sensitivity)\n ) {\n errors.push({\n field: \"resource.sensitivity\",\n code: \"invalid_value\",\n message: `resource.sensitivity '${ctx.resource.sensitivity}' is not one of: public, internal, confidential, restricted`,\n });\n }\n\n // ── caller-specified required fields ────────────────────────────────\n for (const fieldPath of opts.requiredFields ?? []) {\n const value = getNestedValue(ctxObj, fieldPath);\n if (value === undefined || value === null || value === \"\") {\n errors.push({\n field: fieldPath,\n code: \"required\",\n message: `${fieldPath} is required by the caller's validation rules`,\n });\n }\n }\n\n return { valid: errors.length === 0, errors, warnings };\n}\n\n// ── redactContext ────────────────────────────────────────────────────────────────\n\n/** Redaction mode applied to a matched field. */\nexport type RedactionMode = \"remove\" | \"mask\" | \"hash\";\n\n/**\n * A single redaction rule. `field` is matched against every key at\n * every nesting level in the context object.\n *\n * `path` narrows the match to a specific dot-delimited location\n * (e.g. `\"actor.email\"` to only mask email inside the actor sub-object,\n * not top-level email fields).\n */\nexport interface RedactionRule {\n /** Key name or regex applied to every key in the context tree. */\n field: string | RegExp;\n /** What to do with the matched value. */\n mode: RedactionMode;\n /**\n * Optional dot-delimited path constraint. When set, the rule only\n * applies to a key at this exact path (e.g. `\"actor.session_id\"`).\n */\n path?: string;\n}\n\n/**\n * Built-in redaction rules covering OWASP Top 10 sensitive field\n * name patterns. Matched case-insensitively against every key name\n * at every nesting level.\n *\n * Callers can extend this list or pass a custom rule set to\n * `redactContext()`.\n */\nexport const DEFAULT_REDACTION_RULES: readonly RedactionRule[] = [\n {\n field: /password|passwd|passphrase/i,\n mode: \"remove\",\n },\n {\n field: /secret|private_key|client_secret|signing_secret/i,\n mode: \"remove\",\n },\n {\n field: /api_key|apikey|access_key|access_token/i,\n mode: \"remove\",\n },\n {\n field: /\\btoken\\b|auth_token|bearer/i,\n mode: \"mask\",\n },\n {\n field: /\\bssn\\b|social_security|tax_id|\\bsin\\b/i,\n mode: \"remove\",\n },\n {\n field: /credit_card|card_number|pan\\b|cvv|cvc|expiry/i,\n mode: \"remove\",\n },\n {\n field: /\\bemail\\b/i,\n mode: \"mask\",\n },\n {\n field: /phone|mobile|cell\\b/i,\n mode: \"mask\",\n },\n {\n field: /\\bip\\b|ip_address|remote_addr/i,\n mode: \"mask\",\n },\n {\n field: /dob|date_of_birth|birth_date|birthdate/i,\n mode: \"remove\",\n },\n];\n\nconst MASK_PLACEHOLDER = \"[REDACTED]\";\n\nfunction matchesRule(key: string, rule: RedactionRule): boolean {\n if (typeof rule.field === \"string\") {\n return key.toLowerCase() === rule.field.toLowerCase();\n }\n return rule.field.test(key);\n}\n\nfunction redactValue(\n value: unknown,\n mode: RedactionMode,\n): unknown {\n if (mode === \"remove\") return undefined;\n if (mode === \"mask\") return MASK_PLACEHOLDER;\n // \"hash\" — return a stable placeholder; callers that want actual hashing\n // can post-process the \"[HASHED]\" sentinel.\n return \"[HASHED]\";\n}\n\nfunction redactObject(\n obj: Record<string, unknown>,\n rules: readonly RedactionRule[],\n currentPath: string,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const fieldPath = currentPath ? `${currentPath}.${key}` : key;\n\n // Find the first matching rule (path-constrained rules take priority)\n const matchingRule = rules.find(\n (r) =>\n matchesRule(key, r) && (r.path === undefined || r.path === fieldPath),\n );\n\n if (matchingRule) {\n const redacted = redactValue(value, matchingRule.mode);\n if (redacted !== undefined) result[key] = redacted;\n // If mode === \"remove\", the key is omitted (undefined not assigned)\n } else if (Array.isArray(value)) {\n result[key] = value.map((item) =>\n item !== null && typeof item === \"object\" && !Array.isArray(item)\n ? redactObject(item as Record<string, unknown>, rules, fieldPath)\n : item,\n );\n } else if (value !== null && typeof value === \"object\") {\n result[key] = redactObject(\n value as Record<string, unknown>,\n rules,\n fieldPath,\n );\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/**\n * Return a redacted copy of `ctx` with sensitive fields removed or masked.\n *\n * Uses `DEFAULT_REDACTION_RULES` when `rules` is omitted. Callers can\n * extend or replace the default rules:\n *\n * ```ts\n * import { DEFAULT_REDACTION_RULES, redactContext } from \"@atlasent/sdk\";\n *\n * const safe = redactContext(ctx, [\n * ...DEFAULT_REDACTION_RULES,\n * { field: /internal_id/, mode: \"hash\" },\n * ]);\n * ```\n *\n * Never mutates the input; returns a shallow-to-deep copy.\n */\nexport function redactContext(\n ctx: ActionContext,\n rules: readonly RedactionRule[] = DEFAULT_REDACTION_RULES,\n): ActionContext {\n return redactObject(\n ctx as Record<string, unknown>,\n rules,\n \"\",\n ) as ActionContext;\n}\n\n// ── flattenActionContext ──────────────────────────────────────────────────────────\n\n/**\n * Convert a typed `ActionContext` to the flat `Record<string, unknown>`\n * that `protect()` / `evaluate()` / `verifyPermit()` accept.\n *\n * The output merges:\n * 1. All top-level scalar fields from `ActionContext` (including flat\n * shorthands like `environment_name`, and billing dimensions like\n * `org_id` and `environment_id`).\n * 2. Nested sub-schemas (`actor`, `resource`, `environment`, etc.) preserved\n * as nested objects so policy rules written against either the nested or\n * flat form work correctly.\n *\n * The nested form is always present in the output; the flat shorthands\n * (`resource_type`, `resource_id`, `environment_name`, `environment`) are\n * duplicated at the top level for policy rules that use the flat path.\n *\n * ```ts\n * const permit = await protect({\n * agent: \"deploy-bot\",\n * action: \"production.deploy\",\n * context: flattenActionContext(ctx),\n * });\n * ```\n */\nexport function flattenActionContext(\n ctx: ActionContext,\n): Record<string, unknown> {\n const flat: Record<string, unknown> = {};\n\n // Copy all top-level fields (both structured sub-schemas and extra fields)\n for (const [key, value] of Object.entries(ctx)) {\n flat[key] = value;\n }\n\n // Expose a flat string shorthand for environment name alongside the full\n // nested object. Using a separate key preserves nested fields (region,\n // pipeline, etc.) that were already copied above.\n const envName = ctx.environment?.name ?? ctx.environment_name;\n if (envName !== undefined) {\n flat[\"environment_name\"] = envName;\n }\n\n return flat;\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type DeployEnvironment = \"production\" | \"staging\" | \"development\" | string;\n\nexport interface DeployGateOptions {\n service: string;\n resourceType?: string;\n sha?: string;\n workflow?: string;\n actorId?: string;\n actorLabel?: string;\n environment?: DeployEnvironment;\n description?: string;\n requireApproval?: boolean;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n /** Slack Incoming Webhook URL. When set, an informational message is posted\n * when the gate returns deny or escalate. Best-effort; never throws. */\n notifySlackWebhook?: string;\n}\n\nfunction resolveEnvActor(): string | undefined {\n return (\n process.env[\"GITHUB_ACTOR\"] ??\n process.env[\"GITLAB_USER_LOGIN\"] ??\n process.env[\"CIRCLE_USERNAME\"] ??\n process.env[\"BITBUCKET_STEP_TRIGGERER_UUID\"] ??\n undefined\n );\n}\n\nfunction resolveEnvSha(): string | undefined {\n return (\n process.env[\"GITHUB_SHA\"] ??\n process.env[\"CI_COMMIT_SHA\"] ??\n process.env[\"CIRCLE_SHA1\"] ??\n process.env[\"BITBUCKET_COMMIT\"] ??\n undefined\n );\n}\n\nfunction resolveEnvWorkflow(): string | undefined {\n return (\n process.env[\"GITHUB_WORKFLOW\"] ??\n process.env[\"CI_PIPELINE_NAME\"] ??\n process.env[\"CIRCLE_WORKFLOW_NAME\"] ??\n undefined\n );\n}\n\nexport async function protectDeploy(\n opts: DeployGateOptions,\n): Promise<ApprovalPermit | Permit> {\n const actorId = opts.actorId ?? resolveEnvActor() ?? \"ci-system\";\n const sha = opts.sha ?? resolveEnvSha();\n const workflow = opts.workflow ?? resolveEnvWorkflow();\n const environment = opts.environment ?? \"production\";\n const isProduction = environment === \"production\";\n\n const ctx = buildActionContext({\n actor: {\n id: actorId,\n type: \"service_account\",\n ...(opts.actorLabel !== undefined ? { label: opts.actorLabel } : {}),\n },\n resource: {\n id: opts.service,\n type: opts.resourceType ?? \"service\",\n },\n environment,\n action_meta: {\n risk_level: isProduction ? \"critical\" : \"medium\",\n reversibility: \"partial\",\n ...(opts.description !== undefined\n ? { description: opts.description }\n : sha !== undefined\n ? { description: `Deploy ${sha.slice(0, 8)} to ${environment}` }\n : {}),\n },\n extra: {\n sha,\n workflow,\n },\n });\n\n const request = {\n action: \"production.deploy\",\n agent: actorId,\n context: flattenActionContext(ctx),\n };\n\n const notifyDenied = async (reason: string): Promise<void> => {\n if (!opts.notifySlackWebhook) return;\n try {\n await fetch(opts.notifySlackWebhook, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n text: `:no_entry: AtlaSent Deploy Gate DENIED: ${request.action} (${environment})`,\n blocks: [\n {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: `*:no_entry: AtlaSent Deploy Gate DENIED*\\n*Action:* \\`${request.action}\\`\\n*Service:* ${opts.service}\\n*Environment:* ${environment}\\n*Actor:* ${actorId}\\n*Reason:* ${reason}`,\n },\n },\n ],\n }),\n });\n } catch {\n // notification errors are always swallowed\n }\n };\n\n try {\n if (opts.requireApproval || isProduction) {\n return await protectOrEscalate(request, {\n escalationReason: `Production deployment of ${opts.service} requires human approval`,\n assignedToRole: opts.assignedToRole ?? \"release-manager\",\n waitMs: opts.waitMs ?? 30 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n }\n return await protect(request);\n } catch (err: unknown) {\n const reason =\n err instanceof Error ? err.message : \"authorization denied\";\n await notifyDenied(reason);\n throw err;\n }\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\n// data export actions use protectDataExport() from verticals/dataExport.ts\nexport type CloseActionType = \"period.close\" | \"period.reopen\" | \"reconciliation.lock\" | \"reconciliation.certify\";\n\nexport interface CloseGovernanceOptions {\n action: CloseActionType;\n periodLabel: string;\n closedBy: string;\n entityId: string;\n entityName?: string;\n dataClassification?: \"internal\" | \"confidential\" | \"restricted\";\n assignedToRole?: string;\n requireDualApproval?: boolean;\n waitMs?: number;\n description?: string;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nconst ACTION_RISK: Record<CloseActionType, \"critical\" | \"high\" | \"medium\" | \"low\"> = {\n \"period.close\": \"critical\",\n \"period.reopen\": \"critical\",\n \"reconciliation.lock\": \"high\",\n \"reconciliation.certify\": \"high\",\n};\n\nconst ACTION_REVERSIBILITY: Record<CloseActionType, \"reversible\" | \"irreversible\" | \"partial\"> = {\n \"period.close\": \"partial\",\n \"period.reopen\": \"partial\",\n \"reconciliation.lock\": \"reversible\",\n \"reconciliation.certify\": \"irreversible\",\n};\n\nexport interface ReconciliationCertifyOptions {\n accountId: string;\n period: string;\n certifiedBy: string;\n balanceDifference: number;\n dualApprovalRequired: boolean;\n secondApprover?: string;\n supportingEvidenceUri?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectReconciliationCertify(\n opts: ReconciliationCertifyOptions,\n): Promise<ApprovalPermit> {\n return protectCloseAction({\n action: \"reconciliation.certify\",\n periodLabel: opts.period,\n closedBy: opts.certifiedBy,\n entityId: opts.accountId,\n requireDualApproval: opts.dualApprovalRequired,\n description: `Reconciliation certify for account ${opts.accountId} period ${opts.period} by ${opts.certifiedBy}`,\n ...(opts.assignedToRole !== undefined ? { assignedToRole: opts.assignedToRole } : {}),\n ...(opts.waitMs !== undefined ? { waitMs: opts.waitMs } : {}),\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n}\n\nexport async function protectCloseAction(\n opts: CloseGovernanceOptions,\n): Promise<ApprovalPermit> {\n const ctx = buildActionContext({\n actor: {\n id: opts.closedBy,\n type: \"human\",\n trust_level: \"medium\",\n },\n resource: {\n id: opts.entityId,\n type: \"accounting_entity\",\n sensitivity: opts.dataClassification ?? \"confidential\",\n ...(opts.entityName !== undefined ? { name: opts.entityName } : {}),\n },\n environment: \"production\",\n action_meta: {\n risk_level: ACTION_RISK[opts.action],\n reversibility: ACTION_REVERSIBILITY[opts.action],\n description: opts.description ?? `${opts.action} for period ${opts.periodLabel} on entity ${opts.entityId}`,\n },\n extra: {\n period_label: opts.periodLabel,\n close_action: opts.action,\n },\n });\n\n return protectOrEscalate(\n {\n action: opts.action,\n agent: opts.closedBy,\n context: flattenActionContext(ctx),\n },\n {\n escalationReason: `Accounting ${opts.action} for period '${opts.periodLabel}' requires approval`,\n assignedToRole: opts.assignedToRole ?? \"controller\",\n quorumRequired: (opts.requireDualApproval ?? opts.action === \"period.close\") ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 24 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n },\n );\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport const VENDOR_PAYMENT_ACTION = \"vendor.payment.release\" as const;\n\nexport interface PaymentReleaseOptions {\n amount: number;\n currency: string;\n vendorId: string;\n vendorName?: string;\n authorizedBy: string;\n reference?: string;\n description?: string;\n autoEscalateAbove?: number;\n requireDualApprovalAbove?: number;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nconst ISO_4217 = /^[A-Z]{3}$/;\n\nexport async function protectPaymentRelease(\n opts: PaymentReleaseOptions,\n): Promise<ApprovalPermit | Permit> {\n if (!ISO_4217.test(opts.currency)) {\n throw new TypeError(\n `Invalid currency code '${opts.currency}': must be a 3-letter ISO 4217 code (e.g. USD, EUR, GBP)`,\n );\n }\n\n if (opts.amount <= 0) {\n throw new RangeError(`Payment amount must be greater than 0, got ${opts.amount}`);\n }\n\n const escalateThreshold = opts.autoEscalateAbove ?? 10_000;\n const dualThreshold = opts.requireDualApprovalAbove ?? 100_000;\n const needsEscalation = opts.amount > escalateThreshold;\n const needsDual = opts.amount > dualThreshold;\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: opts.vendorId,\n type: \"vendor\",\n ...(opts.vendorName !== undefined ? { name: opts.vendorName } : {}),\n },\n environment: \"production\",\n action_meta: {\n risk_level: opts.amount > dualThreshold ? \"critical\" : opts.amount > escalateThreshold ? \"high\" : \"medium\",\n reversibility: \"irreversible\",\n estimated_amount: opts.amount,\n currency: opts.currency,\n description: opts.description ?? `Release ${opts.currency} ${opts.amount.toLocaleString()} to ${opts.vendorName ?? opts.vendorId}`,\n },\n extra: {\n reference: opts.reference,\n },\n });\n\n const request = {\n action: VENDOR_PAYMENT_ACTION,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n };\n\n if (needsEscalation) {\n return protectOrEscalate(request, {\n escalationReason: `Payment of ${opts.currency} ${opts.amount.toLocaleString()} to ${opts.vendorName ?? opts.vendorId} exceeds auto-approval threshold of ${opts.currency} ${escalateThreshold.toLocaleString()}`,\n assignedToRole: opts.assignedToRole ?? \"finance-approver\",\n quorumRequired: needsDual ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 4 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n }\n return protect(request);\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport const CUSTOMER_DATA_EXPORT_ACTION = \"customer.data.export\" as const;\n\nexport interface DataExportOptions {\n dataset: string;\n destination: string;\n containsPii: boolean;\n rowCount: number;\n dataClassification: \"public\" | \"internal\" | \"confidential\" | \"restricted\";\n purpose: string;\n dpaReference?: string;\n encryption?: string;\n authorizedBy: string;\n rowCap?: number;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nfunction classifyExportRisk(opts: DataExportOptions): \"low\" | \"medium\" | \"high\" | \"critical\" {\n if (opts.containsPii && opts.rowCount > 10000) return \"critical\";\n if (opts.containsPii) return \"high\";\n if (opts.dataClassification === \"confidential\" || opts.dataClassification === \"restricted\") return \"high\";\n return \"medium\";\n}\n\nexport async function protectDataExport(\n opts: DataExportOptions,\n): Promise<ApprovalPermit | Permit> {\n const riskLevel = classifyExportRisk(opts);\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: opts.dataset,\n type: \"dataset\",\n sensitivity: opts.dataClassification,\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: \"irreversible\",\n description: `Export dataset '${opts.dataset}' to '${opts.destination}' (${opts.rowCount} rows, PII: ${opts.containsPii})`,\n },\n extra: {\n destination: opts.destination,\n row_count: opts.rowCount,\n contains_pii: opts.containsPii,\n data_classification: opts.dataClassification,\n purpose: opts.purpose,\n dpa_reference: opts.dpaReference,\n encryption: opts.encryption,\n row_cap: opts.rowCap,\n },\n });\n\n const request = {\n action: CUSTOMER_DATA_EXPORT_ACTION,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n };\n\n if (riskLevel === \"critical\" || riskLevel === \"high\") {\n return protectOrEscalate(request, {\n escalationReason: `Data export of '${opts.dataset}' to '${opts.destination}' requires approval (risk: ${riskLevel})`,\n assignedToRole: opts.assignedToRole ?? \"data-governance\",\n waitMs: opts.waitMs ?? 4 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n }\n return protect(request);\n}\n","import { protect } from \"./protect.js\";\nimport { AtlaSentDeniedError } from \"./errors.js\";\nimport type { ProtectRequest, Permit } from \"./protect.js\";\n\nexport type ShadowMode = \"observe\" | \"warn\" | \"enforce\";\n\nexport interface ShadowOutcome {\n readonly decision: \"permit\" | \"deny\" | \"hold\" | \"escalate\";\n readonly permit: Permit | null;\n readonly error: AtlaSentDeniedError | null;\n readonly would_have_blocked: boolean;\n readonly latencyMs: number;\n readonly evaluationId: string | null;\n readonly request: ProtectRequest;\n readonly mode: ShadowMode;\n}\n\nexport interface ShadowConfig {\n mode?: ShadowMode;\n onOutcome?: (outcome: ShadowOutcome) => void | Promise<void>;\n reportToApi?: boolean;\n apiKey?: string;\n baseUrl?: string;\n}\n\nlet _defaultConfig: ShadowConfig = {};\n\nexport function configureShadow(config: ShadowConfig): void {\n _defaultConfig = { ..._defaultConfig, ...config };\n}\n\nexport interface ShadowOptions extends ShadowConfig {}\n\nexport async function protectShadow(\n request: ProtectRequest,\n opts?: ShadowOptions,\n): Promise<ShadowOutcome> {\n const merged: ShadowConfig = { ..._defaultConfig, ...opts };\n const mode = merged.mode ?? \"observe\";\n\n if (mode === \"enforce\") {\n const start = Date.now();\n const permit = await protect(request);\n const outcome: ShadowOutcome = {\n decision: \"permit\",\n permit,\n error: null,\n would_have_blocked: false,\n latencyMs: Date.now() - start,\n evaluationId: permit.permitId,\n request,\n mode,\n };\n await _notify(outcome, merged);\n return outcome;\n }\n\n const start = Date.now();\n try {\n const permit = await protect(request);\n const outcome: ShadowOutcome = {\n decision: \"permit\",\n permit,\n error: null,\n would_have_blocked: false,\n latencyMs: Date.now() - start,\n evaluationId: permit.permitId,\n request,\n mode,\n };\n await _notify(outcome, merged);\n if (merged.reportToApi) {\n void reportShadowEvent(outcome, merged).catch(() => undefined);\n }\n return outcome;\n } catch (err) {\n if (err instanceof AtlaSentDeniedError) {\n const outcome: ShadowOutcome = {\n decision: err.decision as \"deny\" | \"hold\" | \"escalate\",\n permit: null,\n error: err,\n would_have_blocked: true,\n latencyMs: Date.now() - start,\n evaluationId: err.evaluationId ?? null,\n request,\n mode,\n };\n if (mode === \"warn\") {\n // eslint-disable-next-line no-console\n console.warn(\n `[AtlaSent shadow:warn] Action '${request.action}' would have been blocked (decision=${err.decision}, evaluationId=${err.evaluationId ?? \"unknown\"})`,\n );\n }\n await _notify(outcome, merged);\n if (merged.reportToApi) {\n void reportShadowEvent(outcome, merged).catch(() => undefined);\n }\n return outcome;\n }\n throw err;\n }\n}\n\nasync function _notify(\n outcome: ShadowOutcome,\n config: ShadowConfig,\n): Promise<void> {\n if (config.onOutcome) {\n try {\n await config.onOutcome(outcome);\n } catch {\n // onOutcome errors must never propagate\n }\n }\n}\n\nexport interface ShadowEventPayload {\n action: string;\n agentId: string | null;\n decision: ShadowOutcome[\"decision\"];\n would_have_blocked: boolean;\n latencyMs: number;\n evaluationId: string | null;\n mode: ShadowMode;\n deniedReason?: string;\n timestamp: string;\n}\n\nexport async function reportShadowEvent(\n outcome: ShadowOutcome,\n opts?: Pick<ShadowConfig, \"apiKey\" | \"baseUrl\">,\n): Promise<void> {\n const apiKey =\n opts?.apiKey ?? _defaultConfig.apiKey ?? process.env[\"ATLASENT_API_KEY\"] ?? \"\";\n const baseUrl =\n opts?.baseUrl ?? _defaultConfig.baseUrl ?? process.env[\"ATLASENT_BASE_URL\"] ?? \"https://api.atlasent.ai\";\n\n const payload: ShadowEventPayload = {\n action: outcome.request.action,\n agentId: outcome.request.agent ?? null,\n decision: outcome.decision,\n would_have_blocked: outcome.would_have_blocked,\n latencyMs: outcome.latencyMs,\n evaluationId: outcome.evaluationId,\n mode: outcome.mode,\n ...(outcome.error ? { deniedReason: outcome.error.message } : {}),\n timestamp: new Date().toISOString(),\n };\n\n const response = await fetch(`${baseUrl}/v1/shadow-events`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok && response.status >= 500) {\n throw new Error(`Shadow event reporting failed: ${response.status}`);\n }\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { protectShadow } from \"../shadow.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { ShadowOutcome } from \"../shadow.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type AgentToolMode = \"observe\" | \"enforce\" | \"escalate\";\n\nexport interface AgentToolOptions {\n toolName: string;\n toolArgs: Record<string, unknown>;\n agentId: string;\n sessionId?: string;\n riskLevel?: \"critical\" | \"high\" | \"medium\" | \"low\";\n mode?: AgentToolMode;\n assignedToRole?: string;\n waitMs?: number;\n description?: string;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nconst HIGH_RISK_TOOLS = new Set([\n \"bash\", \"shell\", \"exec\", \"execute_code\", \"run_command\",\n \"write_file\", \"delete_file\", \"overwrite_file\",\n \"sql_execute\", \"db_write\", \"db_delete\",\n \"send_email\", \"send_message\", \"post_to_slack\",\n \"create_pr\", \"merge_pr\", \"push_code\",\n \"deploy\", \"release\",\n \"make_payment\", \"transfer_funds\",\n \"create_user\", \"delete_user\", \"modify_permissions\",\n \"aws_cli\", \"gcloud\", \"kubectl\",\n]);\n\nconst CRITICAL_TOOLS = new Set([\n \"bash\", \"shell\", \"exec\", \"execute_code\", \"run_command\",\n \"delete_file\", \"db_delete\",\n \"make_payment\", \"transfer_funds\",\n \"delete_user\", \"modify_permissions\",\n \"deploy\", \"release\",\n]);\n\nexport function classifyToolRisk(\n toolName: string,\n): \"critical\" | \"high\" | \"medium\" | \"low\" {\n const normalized = toolName.toLowerCase().replace(/[^a-z0-9_]/g, \"_\");\n if (CRITICAL_TOOLS.has(normalized)) return \"critical\";\n if (HIGH_RISK_TOOLS.has(normalized)) return \"high\";\n if (normalized.includes(\"write\") || normalized.includes(\"create\") || normalized.includes(\"update\")) return \"medium\";\n return \"low\";\n}\n\nexport async function protectToolCall(\n opts: AgentToolOptions,\n): Promise<ApprovalPermit | Permit | ShadowOutcome> {\n const inferredRisk = opts.riskLevel ?? classifyToolRisk(opts.toolName);\n const mode = opts.mode ?? (inferredRisk === \"low\" ? \"enforce\" : \"escalate\");\n\n const ctx = buildActionContext({\n actor: {\n id: opts.agentId,\n type: \"agent\",\n ...(opts.sessionId !== undefined ? { session_id: opts.sessionId } : {}),\n },\n resource: {\n type: \"agent_tool\",\n id: opts.toolName,\n },\n environment: \"production\",\n action_meta: {\n risk_level: inferredRisk,\n reversibility: inferredRisk === \"critical\" || inferredRisk === \"high\" ? \"irreversible\" : \"reversible\",\n description: opts.description ?? `Agent ${opts.agentId} calling tool '${opts.toolName}'`,\n },\n extra: {\n tool_args_keys: Object.keys(opts.toolArgs),\n session_id: opts.sessionId,\n },\n });\n\n const request = {\n action: `agent_tool.${opts.toolName}`,\n agent: opts.agentId,\n context: flattenActionContext(ctx),\n };\n\n if (mode === \"observe\") {\n return protectShadow(request, { mode: \"observe\" });\n }\n\n if (mode === \"escalate\" || inferredRisk === \"critical\") {\n return protectOrEscalate(request, {\n escalationReason: `Agent '${opts.agentId}' is calling ${inferredRisk}-risk tool '${opts.toolName}'`,\n assignedToRole: opts.assignedToRole ?? \"agent-supervisor\",\n riskScore: inferredRisk === \"critical\" ? 1.0 : inferredRisk === \"high\" ? 0.75 : 0.5,\n waitMs: opts.waitMs ?? 15 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n }\n\n return protect(request);\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type GxpActionType =\n | \"manufacturing.batch_record.release\"\n | \"clinical.tmf.record.modify\"\n | \"clinical.data.access\"\n | \"clinical.source_data.read\"\n | \"clinical.signature.apply\"\n | \"clinical.deviation.report\"\n | \"clinical.consent.update\"\n | \"quality.capa.initiate\"\n | \"quality.capa.assign\"\n | \"quality.capa.progress\"\n | \"quality.capa.effectiveness_check\"\n | \"quality.capa.close\"\n | \"quality.deviation.detect\"\n | \"quality.deviation.classify\"\n | \"quality.deviation.escalate\"\n | \"quality.deviation.investigate\"\n | \"quality.deviation.close\"\n | \"quality.change_control.initiate\"\n | \"quality.change_control.classify\"\n | \"quality.change_control.approve\"\n | \"quality.change_control.implement\"\n | \"quality.change_control.close\";\n\nconst GXP_ACTION_RISK: Record<GxpActionType, \"high\" | \"critical\"> = {\n \"manufacturing.batch_record.release\": \"critical\",\n \"clinical.tmf.record.modify\": \"high\",\n \"clinical.data.access\": \"high\",\n \"clinical.source_data.read\": \"high\",\n \"clinical.signature.apply\": \"high\",\n \"clinical.deviation.report\": \"high\",\n \"clinical.consent.update\": \"high\",\n \"quality.capa.initiate\": \"high\",\n \"quality.capa.assign\": \"high\",\n \"quality.capa.progress\": \"high\",\n \"quality.capa.effectiveness_check\": \"high\",\n \"quality.capa.close\": \"high\",\n \"quality.deviation.detect\": \"high\",\n \"quality.deviation.classify\": \"high\",\n \"quality.deviation.escalate\": \"high\",\n \"quality.deviation.investigate\": \"high\",\n \"quality.deviation.close\": \"high\",\n \"quality.change_control.initiate\": \"high\",\n \"quality.change_control.classify\": \"high\",\n \"quality.change_control.approve\": \"high\",\n \"quality.change_control.implement\": \"high\",\n \"quality.change_control.close\": \"high\",\n};\n\nexport interface BatchRecordReleaseOptions {\n batchId: string;\n productCode: string;\n lotNumber: string;\n certifiedBy: string;\n qaSignoffBy: string;\n batchRecordComplete: boolean;\n deviationCount: number;\n regulatoryRegion: string;\n action: \"manufacturing.batch_record.release\";\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport interface ClinicalDataAccessOptions {\n subjectId: string;\n dataCategory: string;\n accessedBy: string;\n purpose: string;\n aiAgent: boolean;\n consentVerified: boolean;\n trialId: string;\n action: \"clinical.data.access\";\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport interface CAPAOptions {\n capaId: string;\n action: GxpActionType & `quality.capa.${string}`;\n initiatedBy?: string;\n closedBy?: string;\n secondClosedBy?: string;\n severity?: \"minor\" | \"major\" | \"critical\";\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n [key: string]: unknown;\n}\n\nexport type GxpActionOptions =\n | BatchRecordReleaseOptions\n | ClinicalDataAccessOptions\n | CAPAOptions\n | { action: GxpActionType; assignedToRole?: string; waitMs?: number; onEscalationCreated?: (handle: EscalationHandle) => void; apiKey?: string; baseUrl?: string; [key: string]: unknown };\n\nexport async function protectGxpAction(\n opts: GxpActionOptions,\n): Promise<ApprovalPermit> {\n const action = opts.action as GxpActionType;\n const riskLevel = GXP_ACTION_RISK[action] ?? \"high\";\n\n const actorId =\n (\"certifiedBy\" in opts && opts.certifiedBy) ||\n (\"accessedBy\" in opts && opts.accessedBy) ||\n (\"initiatedBy\" in opts && opts.initiatedBy) ||\n (\"closedBy\" in opts && opts.closedBy) ||\n \"gxp-agent\";\n\n const resourceId =\n (\"batchId\" in opts && opts.batchId) ||\n (\"capaId\" in opts && opts.capaId) ||\n (\"subjectId\" in opts && opts.subjectId) ||\n action;\n\n const ctx = buildActionContext({\n actor: {\n id: actorId as string,\n type: \"human\",\n },\n resource: {\n id: resourceId as string,\n type: \"gxp_record\",\n sensitivity: \"restricted\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: \"irreversible\",\n description: `GxP action '${action}' on resource '${resourceId}'`,\n },\n extra: {\n gxp_action: action,\n machine_executable: false,\n fail_closed: true,\n ...Object.fromEntries(\n Object.entries(opts).filter(([k]) => ![\"action\", \"assignedToRole\", \"waitMs\", \"onEscalationCreated\", \"apiKey\", \"baseUrl\"].includes(k)),\n ),\n },\n });\n\n return protectOrEscalate(\n {\n action,\n agent: actorId as string,\n context: flattenActionContext(ctx),\n },\n {\n escalationReason: `GxP action '${action}' requires human review — machine_executable: false`,\n assignedToRole: opts.assignedToRole ?? (riskLevel === \"critical\" ? \"qa-director\" : \"qa-reviewer\"),\n quorumRequired: action === \"quality.capa.close\" || action === \"manufacturing.batch_record.release\" ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 24 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n },\n );\n}\n\nexport async function protectBatchRecordRelease(\n opts: Omit<BatchRecordReleaseOptions, \"action\">,\n): Promise<ApprovalPermit> {\n return protectGxpAction({ ...opts, action: \"manufacturing.batch_record.release\" });\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type PaymentOperationActionType =\n | \"payment.approval.approve\"\n | \"payment.approval.deny\"\n | \"payment.execute.approved\"\n | \"payment.execute.held\"\n | \"payment.execute.denied\"\n | \"payment.execute.policy_error\"\n | \"qb.transaction.approve\";\n\nconst PAYMENT_ACTION_RISK: Record<PaymentOperationActionType, \"critical\" | \"high\" | \"medium\"> = {\n \"payment.approval.approve\": \"high\",\n \"payment.approval.deny\": \"medium\",\n \"payment.execute.approved\": \"critical\",\n \"payment.execute.held\": \"high\",\n \"payment.execute.denied\": \"medium\",\n \"payment.execute.policy_error\": \"high\",\n \"qb.transaction.approve\": \"high\",\n};\n\nconst ESCALATE_ACTIONS = new Set<PaymentOperationActionType>([\n \"payment.approval.approve\",\n \"payment.execute.approved\",\n \"payment.execute.held\",\n \"payment.execute.policy_error\",\n \"qb.transaction.approve\",\n]);\n\nexport interface PaymentOperationOptions {\n paymentId: string;\n action: PaymentOperationActionType;\n amount?: number;\n currency?: string;\n approvedBy?: string;\n deniedBy?: string;\n executedBy?: string;\n heldBy?: string;\n holdReason?: string;\n policyRule?: string;\n errorCode?: string;\n bankReference?: string;\n invoiceId?: string;\n vendorId?: string;\n accountCode?: string;\n transactionId?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectPaymentOperation(\n opts: PaymentOperationOptions,\n): Promise<ApprovalPermit | Permit> {\n const riskLevel = PAYMENT_ACTION_RISK[opts.action] ?? \"high\";\n\n const actorId =\n opts.approvedBy ??\n opts.executedBy ??\n opts.deniedBy ??\n opts.heldBy ??\n \"payment-system\";\n\n const ctx = buildActionContext({\n actor: {\n id: actorId,\n type: \"human\",\n },\n resource: {\n id: opts.paymentId,\n type: \"payment\",\n ...(opts.vendorId !== undefined ? { vendor_id: opts.vendorId } : {}),\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: opts.action.includes(\"execute\") ? \"irreversible\" : \"reversible\",\n description: `Payment operation '${opts.action}' on payment '${opts.paymentId}'`,\n ...(opts.amount !== undefined ? { estimated_amount: opts.amount } : {}),\n ...(opts.currency !== undefined ? { currency: opts.currency } : {}),\n },\n extra: {\n payment_action: opts.action,\n ...(opts.invoiceId !== undefined ? { invoice_id: opts.invoiceId } : {}),\n ...(opts.holdReason !== undefined ? { hold_reason: opts.holdReason } : {}),\n ...(opts.policyRule !== undefined ? { policy_rule: opts.policyRule } : {}),\n ...(opts.errorCode !== undefined ? { error_code: opts.errorCode } : {}),\n ...(opts.bankReference !== undefined ? { bank_reference: opts.bankReference } : {}),\n ...(opts.accountCode !== undefined ? { account_code: opts.accountCode } : {}),\n ...(opts.transactionId !== undefined ? { transaction_id: opts.transactionId } : {}),\n },\n });\n\n const request = {\n action: opts.action,\n agent: actorId,\n context: flattenActionContext(ctx),\n };\n\n if (ESCALATE_ACTIONS.has(opts.action) || riskLevel === \"critical\") {\n return protectOrEscalate(request, {\n escalationReason: `Payment operation '${opts.action}' on payment '${opts.paymentId}' requires approval`,\n assignedToRole: opts.assignedToRole ?? \"finance-approver\",\n quorumRequired: riskLevel === \"critical\" ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 4 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n }\n\n return protect(request);\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type DeploymentActionType =\n | \"deployment.production.execute\"\n | \"deployment.staging.execute\"\n | \"deployment.rollback.execute\";\n\n/**\n * V1 backward-compatibility constant. The original `production.deploy`\n * action string from deployGate.ts is still supported by the server.\n * Use `DeploymentActionType` values for new V2 integrations.\n */\nexport const DEPLOY_V1_ACTION = \"production.deploy\" as const;\n\nconst DEPLOYMENT_ACTION_RISK: Record<DeploymentActionType, \"critical\" | \"high\"> = {\n \"deployment.production.execute\": \"critical\",\n \"deployment.staging.execute\": \"high\",\n \"deployment.rollback.execute\": \"critical\",\n};\n\nexport interface DeploymentV2Options {\n action: DeploymentActionType;\n deploymentId: string;\n buildSha: string;\n environment: \"production\" | \"staging\";\n approvedBy?: string;\n rollbackPlan?: string;\n changeTicket?: string;\n incidentId?: string;\n rollbackTarget?: string;\n authorizedBy?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectDeploymentV2(\n opts: DeploymentV2Options,\n): Promise<ApprovalPermit> {\n if (opts.action === \"deployment.rollback.execute\") {\n if (!opts.incidentId) {\n throw new TypeError(\n `deployment.rollback.execute requires 'incidentId' to be set`,\n );\n }\n if (!opts.rollbackTarget) {\n throw new TypeError(\n `deployment.rollback.execute requires 'rollbackTarget' to be set`,\n );\n }\n }\n\n const riskLevel = DEPLOYMENT_ACTION_RISK[opts.action] ?? \"high\";\n const actorId = opts.authorizedBy ?? opts.approvedBy ?? \"deploy-system\";\n\n const ctx = buildActionContext({\n actor: {\n id: actorId,\n type: \"service_account\",\n },\n resource: {\n id: opts.deploymentId,\n type: \"deployment\",\n },\n environment: opts.environment,\n action_meta: {\n risk_level: riskLevel,\n reversibility: opts.action === \"deployment.rollback.execute\" ? \"partial\" : \"irreversible\",\n description: `Deployment V2 '${opts.action}' for '${opts.deploymentId}' at sha '${opts.buildSha.slice(0, 8)}'`,\n },\n extra: {\n build_sha: opts.buildSha,\n ...(opts.changeTicket !== undefined ? { change_ticket: opts.changeTicket } : {}),\n ...(opts.rollbackPlan !== undefined ? { rollback_plan: opts.rollbackPlan } : {}),\n ...(opts.incidentId !== undefined ? { incident_id: opts.incidentId } : {}),\n ...(opts.rollbackTarget !== undefined ? { rollback_target: opts.rollbackTarget } : {}),\n },\n });\n\n return protectOrEscalate(\n {\n action: opts.action,\n agent: actorId,\n context: flattenActionContext(ctx),\n },\n {\n escalationReason: `Deployment V2 '${opts.action}' of '${opts.deploymentId}' requires human approval`,\n assignedToRole: opts.assignedToRole ?? \"release-manager\",\n quorumRequired: riskLevel === \"critical\" ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 30 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n },\n );\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type BehaviorEventCategory =\n | \"general\"\n | \"health.mental\"\n | \"health.adherence\"\n | \"financial\"\n | \"minor\";\n\nexport const BEHAVIOR_SENSITIVE_CATEGORIES: BehaviorEventCategory[] = [\n \"health.mental\",\n \"health.adherence\",\n \"financial\",\n \"minor\",\n];\n\nexport interface BehaviorEventOptions {\n action: \"behavior.event.share\";\n subjectId: string;\n eventCategory: BehaviorEventCategory;\n destination: string;\n purpose: string;\n consentVerified: boolean;\n dataMinimized: boolean;\n subjectIsMinor?: boolean;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nfunction isSensitive(opts: BehaviorEventOptions): boolean {\n return (\n BEHAVIOR_SENSITIVE_CATEGORIES.includes(opts.eventCategory) ||\n (opts.subjectIsMinor === true)\n );\n}\n\nfunction classifyBehaviorRisk(opts: BehaviorEventOptions): \"critical\" | \"high\" | \"medium\" {\n if (opts.subjectIsMinor === true) return \"critical\";\n if (opts.eventCategory === \"health.mental\") return \"critical\";\n if (BEHAVIOR_SENSITIVE_CATEGORIES.includes(opts.eventCategory)) return \"high\";\n return \"medium\";\n}\n\nexport async function protectBehaviorEvent(\n opts: BehaviorEventOptions,\n): Promise<ApprovalPermit> {\n const riskLevel = classifyBehaviorRisk(opts);\n const sensitive = isSensitive(opts);\n\n const ctx = buildActionContext({\n actor: {\n id: opts.subjectId,\n type: \"human\",\n },\n resource: {\n id: opts.subjectId,\n type: \"behavior_event\",\n sensitivity: sensitive ? \"restricted\" : \"confidential\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: \"irreversible\",\n description: `Behavior event share for subject '${opts.subjectId}' category '${opts.eventCategory}' to '${opts.destination}'`,\n },\n extra: {\n behavior_event_category: opts.eventCategory,\n destination: opts.destination,\n purpose: opts.purpose,\n consent_verified: opts.consentVerified,\n data_minimized: opts.dataMinimized,\n machine_executable: !sensitive,\n subject_is_minor: opts.subjectIsMinor ?? false,\n hold_reason: opts.subjectIsMinor ? \"HOLD_HUMAN_REVIEW_REQUIRED\" : undefined,\n },\n });\n\n return protectOrEscalate(\n {\n action: opts.action,\n agent: opts.subjectId,\n context: flattenActionContext(ctx),\n },\n {\n escalationReason: opts.subjectIsMinor\n ? `HOLD_HUMAN_REVIEW_REQUIRED: behavior event share for minor subject '${opts.subjectId}'`\n : `Behavior event share for sensitive category '${opts.eventCategory}' requires human review`,\n assignedToRole: opts.assignedToRole ?? (opts.subjectIsMinor ? \"safeguarding-officer\" : \"privacy-reviewer\"),\n quorumRequired: opts.subjectIsMinor || riskLevel === \"critical\" ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 4 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n },\n );\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type InfraActionType =\n | \"aws.ec2.stop_instance\"\n | \"aws.ec2.terminate_instance\"\n | \"github.repos.delete\"\n | \"database.table.drop\"\n | \"database.volume.delete\"\n | \"db.table.delete\"\n | \"infra.volume.delete\";\n\nconst INFRA_ACTION_RISK: Record<InfraActionType, \"critical\" | \"high\"> = {\n \"aws.ec2.stop_instance\": \"high\",\n \"aws.ec2.terminate_instance\": \"critical\",\n \"github.repos.delete\": \"critical\",\n \"database.table.drop\": \"critical\",\n \"database.volume.delete\": \"critical\",\n \"db.table.delete\": \"critical\",\n \"infra.volume.delete\": \"critical\",\n};\n\nconst MACHINE_EXECUTABLE_ACTIONS = new Set<InfraActionType>([\n \"aws.ec2.stop_instance\",\n]);\n\nconst DATA_DESTRUCTIVE_ACTIONS = new Set<InfraActionType>([\n \"database.table.drop\",\n \"database.volume.delete\",\n \"db.table.delete\",\n \"infra.volume.delete\",\n]);\n\nexport interface InfraActionOptions {\n action: InfraActionType;\n resourceId: string;\n authorizedBy: string;\n reason: string;\n changeTicket?: string;\n incidentId?: string;\n backupVerified?: boolean;\n region?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectInfraAction(\n opts: InfraActionOptions,\n): Promise<ApprovalPermit | Permit> {\n if (!opts.changeTicket && !opts.incidentId) {\n throw new TypeError(\n `Infrastructure action '${opts.action}' requires either 'changeTicket' or 'incidentId'`,\n );\n }\n\n if (DATA_DESTRUCTIVE_ACTIONS.has(opts.action) && opts.backupVerified !== true) {\n throw new TypeError(\n `Data-destructive action '${opts.action}' requires 'backupVerified: true'`,\n );\n }\n\n const riskLevel = INFRA_ACTION_RISK[opts.action] ?? \"high\";\n const machineExecutable = MACHINE_EXECUTABLE_ACTIONS.has(opts.action);\n const isDestructive = !machineExecutable;\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: opts.resourceId,\n type: \"infrastructure_resource\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: DATA_DESTRUCTIVE_ACTIONS.has(opts.action) ? \"irreversible\" : opts.action === \"aws.ec2.terminate_instance\" ? \"irreversible\" : \"reversible\",\n description: `Infrastructure action '${opts.action}' on resource '${opts.resourceId}': ${opts.reason}`,\n },\n extra: {\n infra_action: opts.action,\n machine_executable: machineExecutable,\n reason: opts.reason,\n ...(opts.changeTicket !== undefined ? { change_ticket: opts.changeTicket } : {}),\n ...(opts.incidentId !== undefined ? { incident_id: opts.incidentId } : {}),\n ...(opts.backupVerified !== undefined ? { backup_verified: opts.backupVerified } : {}),\n ...(opts.region !== undefined ? { region: opts.region } : {}),\n },\n });\n\n const request = {\n action: opts.action,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n };\n\n if (isDestructive || riskLevel === \"critical\") {\n return protectOrEscalate(request, {\n escalationReason: `Infrastructure action '${opts.action}' on '${opts.resourceId}' requires human approval (machine_executable: false)`,\n assignedToRole: opts.assignedToRole ?? (DATA_DESTRUCTIVE_ACTIONS.has(opts.action) ? \"dba-approver\" : \"infra-approver\"),\n quorumRequired: riskLevel === \"critical\" ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 30 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n }\n\n return protect(request);\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type HrActionType =\n | \"hr.employee.offboard\"\n | \"hr.access.revoke\"\n | \"hr.role.escalate\";\n\nconst HR_ACTION_RISK: Record<HrActionType, \"critical\" | \"high\"> = {\n \"hr.employee.offboard\": \"high\",\n \"hr.access.revoke\": \"high\",\n \"hr.role.escalate\": \"critical\",\n};\n\nconst MACHINE_EXECUTABLE_ACTIONS = new Set<HrActionType>([\n \"hr.access.revoke\",\n]);\n\nexport interface HrActionOptions {\n action: HrActionType;\n employeeId: string;\n authorizedBy: string;\n // offboard-specific\n effectiveDate?: string;\n offboardingReason?: string;\n // role-escalate-specific\n requestedRole?: string;\n businessJustification?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectHrAction(\n opts: HrActionOptions,\n): Promise<ApprovalPermit | Permit> {\n if (opts.action === \"hr.employee.offboard\") {\n if (!opts.effectiveDate) {\n throw new TypeError(\n `HR action 'hr.employee.offboard' requires 'effectiveDate'`,\n );\n }\n if (!opts.offboardingReason) {\n throw new TypeError(\n `HR action 'hr.employee.offboard' requires 'offboardingReason'`,\n );\n }\n }\n\n if (opts.action === \"hr.role.escalate\") {\n if (!opts.requestedRole) {\n throw new TypeError(\n `HR action 'hr.role.escalate' requires 'requestedRole'`,\n );\n }\n if (!opts.businessJustification) {\n throw new TypeError(\n `HR action 'hr.role.escalate' requires 'businessJustification'`,\n );\n }\n }\n\n const riskLevel = HR_ACTION_RISK[opts.action] ?? \"high\";\n const machineExecutable = MACHINE_EXECUTABLE_ACTIONS.has(opts.action);\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: opts.employeeId,\n type: \"hr_employee_record\",\n sensitivity: \"restricted\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: opts.action === \"hr.employee.offboard\" ? \"irreversible\" : \"reversible\",\n description: `HR action '${opts.action}' on employee '${opts.employeeId}'`,\n },\n extra: {\n hr_action: opts.action,\n machine_executable: machineExecutable,\n ...(opts.effectiveDate !== undefined ? { effective_date: opts.effectiveDate } : {}),\n ...(opts.offboardingReason !== undefined ? { offboarding_reason: opts.offboardingReason } : {}),\n ...(opts.requestedRole !== undefined ? { requested_role: opts.requestedRole } : {}),\n ...(opts.businessJustification !== undefined ? { business_justification: opts.businessJustification } : {}),\n },\n });\n\n const request = {\n action: opts.action,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n };\n\n if (!machineExecutable || riskLevel === \"critical\") {\n return protectOrEscalate(request, {\n escalationReason: `HR action '${opts.action}' on employee '${opts.employeeId}' requires human review (machine_executable: false)`,\n assignedToRole: opts.assignedToRole ?? (riskLevel === \"critical\" ? \"security-approver\" : \"hr-approver\"),\n quorumRequired: riskLevel === \"critical\" ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 24 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n }\n\n return protect(request);\n}\n\nexport async function protectHrOffboard(\n opts: Omit<HrActionOptions, \"action\"> & { effectiveDate: string; offboardingReason: string },\n): Promise<ApprovalPermit | Permit> {\n return protectHrAction({ ...opts, action: \"hr.employee.offboard\" });\n}\n\nexport async function protectHrRoleEscalate(\n opts: Omit<HrActionOptions, \"action\"> & { requestedRole: string; businessJustification: string },\n): Promise<ApprovalPermit | Permit> {\n return protectHrAction({ ...opts, action: \"hr.role.escalate\" });\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type ModelGovernanceActionType =\n | \"ml.model.promote\"\n | \"ml.model.retire\"\n | \"ml.model.fine_tune\";\n\nconst MODEL_ACTION_RISK: Record<ModelGovernanceActionType, \"critical\" | \"high\"> = {\n \"ml.model.promote\": \"critical\",\n \"ml.model.retire\": \"high\",\n \"ml.model.fine_tune\": \"high\",\n};\n\nexport interface ModelGovernanceOptions {\n action: ModelGovernanceActionType;\n modelId: string;\n authorizedBy: string;\n reason: string;\n safetyReviewId?: string;\n serviceImpactAssessed?: boolean;\n alignmentVerified?: boolean;\n targetEnvironment?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectModelGovernance(\n opts: ModelGovernanceOptions,\n): Promise<ApprovalPermit> {\n const riskLevel = MODEL_ACTION_RISK[opts.action] ?? \"high\";\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: opts.modelId,\n type: \"ml_model\",\n sensitivity: \"restricted\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: opts.action === \"ml.model.retire\" ? \"irreversible\" : \"reversible\",\n description: `Model governance action '${opts.action}' on model '${opts.modelId}': ${opts.reason}`,\n },\n extra: {\n model_action: opts.action,\n machine_executable: false,\n fail_closed: true,\n reason: opts.reason,\n ...(opts.safetyReviewId !== undefined ? { safety_review_id: opts.safetyReviewId } : {}),\n ...(opts.serviceImpactAssessed !== undefined ? { service_impact_assessed: opts.serviceImpactAssessed } : {}),\n ...(opts.alignmentVerified !== undefined ? { alignment_verified: opts.alignmentVerified } : {}),\n ...(opts.targetEnvironment !== undefined ? { target_environment: opts.targetEnvironment } : {}),\n },\n });\n\n return protectOrEscalate(\n {\n action: opts.action,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n },\n {\n escalationReason: `Model governance action '${opts.action}' on '${opts.modelId}' requires human review — machine_executable: false`,\n assignedToRole: opts.assignedToRole ?? (riskLevel === \"critical\" ? \"ml-safety-director\" : \"ml-reviewer\"),\n quorumRequired: riskLevel === \"critical\" ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 48 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n },\n );\n}\n\nexport async function protectModelPromotion(\n opts: Omit<ModelGovernanceOptions, \"action\">,\n): Promise<ApprovalPermit> {\n return protectModelGovernance({ ...opts, action: \"ml.model.promote\" });\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type DataDeleteActionType = \"customer.data.delete\";\n\nexport type GdprLegalBasis =\n | \"erasure_request\"\n | \"retention_expired\"\n | \"consent_withdrawn\"\n | \"controller_instruction\";\n\nexport interface DataDeleteOptions {\n action: DataDeleteActionType;\n dataSubjectId: string;\n verifiedBy: string;\n gdprBasis: GdprLegalBasis;\n dpaReference?: string;\n dataCategories?: string[];\n retentionEndDate?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectCustomerDataDelete(\n opts: DataDeleteOptions,\n): Promise<ApprovalPermit> {\n const ctx = buildActionContext({\n actor: {\n id: opts.verifiedBy,\n type: \"human\",\n },\n resource: {\n id: opts.dataSubjectId,\n type: \"customer_data\",\n sensitivity: \"restricted\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: \"critical\",\n reversibility: \"irreversible\",\n description: `Customer data deletion for data subject '${opts.dataSubjectId}' under GDPR/CCPA basis '${opts.gdprBasis}'`,\n },\n extra: {\n data_delete_action: opts.action,\n machine_executable: false,\n fail_closed: true,\n gdpr_basis: opts.gdprBasis,\n verified_by: opts.verifiedBy,\n data_subject_id: opts.dataSubjectId,\n ...(opts.dpaReference !== undefined ? { dpa_reference: opts.dpaReference } : {}),\n ...(opts.dataCategories !== undefined ? { data_categories: opts.dataCategories } : {}),\n ...(opts.retentionEndDate !== undefined ? { retention_end_date: opts.retentionEndDate } : {}),\n },\n });\n\n return protectOrEscalate(\n {\n action: opts.action,\n agent: opts.verifiedBy,\n context: flattenActionContext(ctx),\n },\n {\n escalationReason: `Customer data deletion for '${opts.dataSubjectId}' is irreversible and requires compliance officer sign-off — machine_executable: false, fail_closed: true`,\n assignedToRole: opts.assignedToRole ?? \"compliance-officer\",\n quorumRequired: \"simple_majority\",\n waitMs: opts.waitMs ?? 72 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n },\n );\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type ContractActionType =\n | \"contract.execute\"\n | \"contract.amend\";\n\nconst CONTRACT_ACTION_RISK: Record<ContractActionType, \"critical\" | \"high\"> = {\n \"contract.execute\": \"critical\",\n \"contract.amend\": \"high\",\n};\n\nexport interface ContractActionOptions {\n action: ContractActionType;\n contractId: string;\n authorizedBy: string;\n counterparty: string;\n legalReviewId?: string;\n estimatedValue?: number;\n currency?: string;\n effectiveDate?: string;\n amendmentDescription?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectContractAction(\n opts: ContractActionOptions,\n): Promise<ApprovalPermit> {\n if (opts.action === \"contract.amend\" && !opts.amendmentDescription) {\n throw new TypeError(\n `Contract action 'contract.amend' requires 'amendmentDescription'`,\n );\n }\n\n const riskLevel = CONTRACT_ACTION_RISK[opts.action] ?? \"high\";\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: opts.contractId,\n type: \"contract\",\n sensitivity: \"restricted\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: opts.action === \"contract.execute\" ? \"irreversible\" : \"partial\",\n description: `Contract action '${opts.action}' on contract '${opts.contractId}' with counterparty '${opts.counterparty}'`,\n ...(opts.estimatedValue !== undefined ? { estimated_amount: opts.estimatedValue } : {}),\n ...(opts.currency !== undefined ? { currency: opts.currency } : {}),\n },\n extra: {\n contract_action: opts.action,\n machine_executable: false,\n fail_closed: true,\n counterparty: opts.counterparty,\n ...(opts.legalReviewId !== undefined ? { legal_review_id: opts.legalReviewId } : {}),\n ...(opts.effectiveDate !== undefined ? { effective_date: opts.effectiveDate } : {}),\n ...(opts.amendmentDescription !== undefined ? { amendment_description: opts.amendmentDescription } : {}),\n },\n });\n\n return protectOrEscalate(\n {\n action: opts.action,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n },\n {\n escalationReason: `Contract action '${opts.action}' on '${opts.contractId}' requires legal review — machine_executable: false`,\n assignedToRole: opts.assignedToRole ?? (riskLevel === \"critical\" ? \"legal-director\" : \"legal-reviewer\"),\n quorumRequired: riskLevel === \"critical\" ? \"simple_majority\" : \"single_approver\",\n waitMs: opts.waitMs ?? 48 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n },\n );\n}\n\nexport async function protectContractExecution(\n opts: Omit<ContractActionOptions, \"action\">,\n): Promise<ApprovalPermit> {\n return protectContractAction({ ...opts, action: \"contract.execute\" });\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type PricingActionType =\n | \"pricing.rule.publish\"\n | \"pricing.discount.approve\";\n\nfunction classifyPricingRisk(opts: PricingActionOptions): \"high\" | \"medium\" {\n if (opts.action === \"pricing.rule.publish\") {\n return \"high\";\n }\n // pricing.discount.approve: medium for <10%, high for >=10%\n const pct = opts.discountPercent ?? 0;\n return pct >= 10 ? \"high\" : \"medium\";\n}\n\nfunction isPricingMachineExecutable(opts: PricingActionOptions): boolean {\n if (opts.action === \"pricing.rule.publish\") {\n // machine_executable: true for changes <5%, false for >=5%\n const pct = opts.priceChangePct ?? 0;\n return pct < 5;\n }\n // pricing.discount.approve: machine_executable: true for small (<10%) discounts\n const pct = opts.discountPercent ?? 0;\n return pct < 10;\n}\n\nexport interface PricingActionOptions {\n action: PricingActionType;\n ruleId: string;\n authorizedBy: string;\n // pricing.rule.publish\n priceChangePct?: number;\n affectedSkus?: string[];\n effectiveDate?: string;\n // pricing.discount.approve\n discountPercent?: number;\n customerId?: string;\n discountReason?: string;\n assignedToRole?: string;\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectPricingAction(\n opts: PricingActionOptions,\n): Promise<ApprovalPermit | Permit> {\n const riskLevel = classifyPricingRisk(opts);\n const machineExecutable = isPricingMachineExecutable(opts);\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: opts.ruleId,\n type: \"pricing_rule\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: \"reversible\",\n description: `Pricing action '${opts.action}' on rule '${opts.ruleId}'`,\n },\n extra: {\n pricing_action: opts.action,\n machine_executable: machineExecutable,\n ...(opts.priceChangePct !== undefined ? { price_change_pct: opts.priceChangePct } : {}),\n ...(opts.affectedSkus !== undefined ? { affected_skus: opts.affectedSkus } : {}),\n ...(opts.effectiveDate !== undefined ? { effective_date: opts.effectiveDate } : {}),\n ...(opts.discountPercent !== undefined ? { discount_percent: opts.discountPercent } : {}),\n ...(opts.customerId !== undefined ? { customer_id: opts.customerId } : {}),\n ...(opts.discountReason !== undefined ? { discount_reason: opts.discountReason } : {}),\n },\n });\n\n const request = {\n action: opts.action,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n };\n\n if (!machineExecutable || riskLevel === \"high\") {\n return protectOrEscalate(request, {\n escalationReason: `Pricing action '${opts.action}' on '${opts.ruleId}' requires human approval (machine_executable: false)`,\n assignedToRole: opts.assignedToRole ?? \"pricing-approver\",\n quorumRequired: \"single_approver\",\n waitMs: opts.waitMs ?? 4 * 60 * 60 * 1000,\n ...(opts.onEscalationCreated !== undefined ? { onEscalationCreated: opts.onEscalationCreated } : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n }\n\n return protect(request);\n}\n\nexport async function protectPricingRule(\n opts: Omit<PricingActionOptions, \"action\">,\n): Promise<ApprovalPermit | Permit> {\n return protectPricingAction({ ...opts, action: \"pricing.rule.publish\" });\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type SecurityActionType =\n | \"security.incident.escalate\"\n | \"security.access.quarantine\";\n\nconst SECURITY_ACTION_RISK: Record<SecurityActionType, \"critical\"> = {\n \"security.incident.escalate\": \"critical\",\n \"security.access.quarantine\": \"critical\",\n};\n\n// All security actions are non-machine-executable and fail-closed.\nconst MACHINE_EXECUTABLE_ACTIONS = new Set<SecurityActionType>();\n\nexport interface SecurityActionOptions {\n action: SecurityActionType;\n authorizedBy: string;\n // security.incident.escalate — required\n incidentId?: string;\n severity?: \"low\" | \"medium\" | \"high\" | \"critical\";\n // security.access.quarantine — required\n targetId?: string;\n quarantineReason?: string;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectSecurityAction(\n opts: SecurityActionOptions,\n): Promise<ApprovalPermit> {\n if (opts.action === \"security.incident.escalate\") {\n if (!opts.incidentId) {\n throw new TypeError(\n `Security action 'security.incident.escalate' requires 'incidentId'`,\n );\n }\n if (!opts.severity) {\n throw new TypeError(\n `Security action 'security.incident.escalate' requires 'severity'`,\n );\n }\n }\n\n if (opts.action === \"security.access.quarantine\") {\n if (!opts.targetId) {\n throw new TypeError(\n `Security action 'security.access.quarantine' requires 'targetId'`,\n );\n }\n if (!opts.quarantineReason) {\n throw new TypeError(\n `Security action 'security.access.quarantine' requires 'quarantineReason'`,\n );\n }\n }\n\n const riskLevel = SECURITY_ACTION_RISK[opts.action];\n\n const resourceId =\n opts.action === \"security.incident.escalate\"\n ? opts.incidentId!\n : opts.targetId!;\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: resourceId,\n type:\n opts.action === \"security.incident.escalate\"\n ? \"security_incident\"\n : \"access_principal\",\n sensitivity: \"restricted\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: \"irreversible\",\n description: `Security action '${opts.action}' on resource '${resourceId}'`,\n },\n extra: {\n security_action: opts.action,\n machine_executable: false,\n fail_closed: true,\n ...(opts.incidentId !== undefined ? { incident_id: opts.incidentId } : {}),\n ...(opts.severity !== undefined ? { severity: opts.severity } : {}),\n ...(opts.targetId !== undefined ? { target_id: opts.targetId } : {}),\n ...(opts.quarantineReason !== undefined\n ? { quarantine_reason: opts.quarantineReason }\n : {}),\n },\n });\n\n const request = {\n action: opts.action,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n };\n\n return protectOrEscalate(request, {\n escalationReason: `Security action '${opts.action}' on '${resourceId}' requires human review (machine_executable: false, fail_closed: true)`,\n assignedToRole: \"security-approver\",\n quorumRequired: \"simple_majority\",\n waitMs: 3_600_000,\n ...(opts.onEscalationCreated !== undefined\n ? { onEscalationCreated: opts.onEscalationCreated }\n : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n}\n\nexport async function protectSecurityIncidentEscalate(\n opts: Omit<SecurityActionOptions, \"action\"> & {\n incidentId: string;\n severity: \"low\" | \"medium\" | \"high\" | \"critical\";\n },\n): Promise<ApprovalPermit> {\n return protectSecurityAction({\n ...opts,\n action: \"security.incident.escalate\",\n });\n}\n\nexport async function protectSecurityAccessQuarantine(\n opts: Omit<SecurityActionOptions, \"action\"> & {\n targetId: string;\n quarantineReason: string;\n },\n): Promise<ApprovalPermit> {\n return protectSecurityAction({\n ...opts,\n action: \"security.access.quarantine\",\n });\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type AccessCertActionType = \"access.cert.revoke\";\n\nconst ACCESS_CERT_ACTION_RISK: Record<AccessCertActionType, \"high\"> = {\n \"access.cert.revoke\": \"high\",\n};\n\n// access.cert.revoke is non-machine-executable.\nconst MACHINE_EXECUTABLE_ACTIONS = new Set<AccessCertActionType>();\n\nexport interface AccessCertOptions {\n action: AccessCertActionType;\n certId: string;\n revocationReason: string;\n authorizedBy?: string;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectAccessCertAction(\n opts: AccessCertOptions,\n): Promise<ApprovalPermit> {\n if (!opts.certId) {\n throw new TypeError(\n `Access cert action 'access.cert.revoke' requires 'certId'`,\n );\n }\n if (!opts.revocationReason) {\n throw new TypeError(\n `Access cert action 'access.cert.revoke' requires 'revocationReason'`,\n );\n }\n\n const riskLevel = ACCESS_CERT_ACTION_RISK[opts.action];\n const actor = opts.authorizedBy ?? \"system\";\n\n const ctx = buildActionContext({\n actor: {\n id: actor,\n type: \"human\",\n },\n resource: {\n id: opts.certId,\n type: \"access_certificate\",\n sensitivity: \"restricted\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: \"irreversible\",\n description: `Access cert action '${opts.action}' on cert '${opts.certId}'`,\n },\n extra: {\n access_cert_action: opts.action,\n machine_executable: false,\n cert_id: opts.certId,\n revocation_reason: opts.revocationReason,\n },\n });\n\n const request = {\n action: opts.action,\n agent: actor,\n context: flattenActionContext(ctx),\n };\n\n return protectOrEscalate(request, {\n escalationReason: `Access cert action '${opts.action}' on cert '${opts.certId}' requires human review (machine_executable: false)`,\n assignedToRole: \"security-approver\",\n quorumRequired: \"single_approver\",\n waitMs: 86_400_000,\n ...(opts.onEscalationCreated !== undefined\n ? { onEscalationCreated: opts.onEscalationCreated }\n : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n}\n\nexport async function protectAccessCertRevoke(\n opts: Omit<AccessCertOptions, \"action\">,\n): Promise<ApprovalPermit> {\n return protectAccessCertAction({ ...opts, action: \"access.cert.revoke\" });\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type FinancialCloseActionType = \"period.close.certify\";\n\nconst FINANCIAL_CLOSE_ACTION_RISK: Record<\n FinancialCloseActionType,\n \"critical\"\n> = {\n \"period.close.certify\": \"critical\",\n};\n\n// period.close.certify is non-machine-executable and fail-closed.\nconst MACHINE_EXECUTABLE_ACTIONS = new Set<FinancialCloseActionType>();\n\nexport interface FinancialCloseOptions {\n action: FinancialCloseActionType;\n periodId: string;\n certifiedBy: string;\n financialController: string;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectFinancialCloseAction(\n opts: FinancialCloseOptions,\n): Promise<ApprovalPermit> {\n if (!opts.periodId) {\n throw new TypeError(\n `Financial close action 'period.close.certify' requires 'periodId'`,\n );\n }\n if (!opts.certifiedBy) {\n throw new TypeError(\n `Financial close action 'period.close.certify' requires 'certifiedBy'`,\n );\n }\n if (!opts.financialController) {\n throw new TypeError(\n `Financial close action 'period.close.certify' requires 'financialController'`,\n );\n }\n\n const riskLevel = FINANCIAL_CLOSE_ACTION_RISK[opts.action];\n\n const ctx = buildActionContext({\n actor: {\n id: opts.certifiedBy,\n type: \"human\",\n },\n resource: {\n id: opts.periodId,\n type: \"financial_period\",\n sensitivity: \"restricted\",\n },\n environment: \"production\",\n action_meta: {\n risk_level: riskLevel,\n reversibility: \"irreversible\",\n description: `Financial close action '${opts.action}' for period '${opts.periodId}'`,\n },\n extra: {\n financial_close_action: opts.action,\n machine_executable: false,\n fail_closed: true,\n period_id: opts.periodId,\n certified_by: opts.certifiedBy,\n financial_controller: opts.financialController,\n },\n });\n\n const request = {\n action: opts.action,\n agent: opts.certifiedBy,\n context: flattenActionContext(ctx),\n };\n\n return protectOrEscalate(request, {\n escalationReason: `Financial close action '${opts.action}' for period '${opts.periodId}' requires human review (machine_executable: false, fail_closed: true)`,\n assignedToRole: \"financial-controller\",\n quorumRequired: \"simple_majority\",\n waitMs: 172_800_000,\n ...(opts.onEscalationCreated !== undefined\n ? { onEscalationCreated: opts.onEscalationCreated }\n : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n });\n}\n\nexport async function protectPeriodCloseCertify(\n opts: Omit<FinancialCloseOptions, \"action\">,\n): Promise<ApprovalPermit> {\n return protectFinancialCloseAction({\n ...opts,\n action: \"period.close.certify\",\n });\n}\n","import { protectOrEscalate } from \"../approvalRuntime.js\";\nimport { protect } from \"../protect.js\";\nimport { buildActionContext, flattenActionContext } from \"../actionContext.js\";\nimport { AtlaSentDeniedError } from \"../errors.js\";\nimport type { ApprovalPermit } from \"../approvalRuntime.js\";\nimport type { Permit } from \"../protect.js\";\nimport type { EscalationHandle } from \"../approvalRuntime.js\";\n\nexport type DatabaseMigrationActionType = \"database.migration.apply\";\nexport type DatabaseDestructiveActionType =\n | \"database.schema.drop\"\n | \"database.table.delete\";\nexport type DatabaseActionType =\n | DatabaseMigrationActionType\n | DatabaseDestructiveActionType;\n\nexport interface PermitEvidence {\n action: DatabaseActionType;\n databaseId: string;\n authorizedBy: string;\n permitToken: string;\n timestamp: string;\n context: Record<string, unknown>;\n}\n\nexport interface DenialEvidence {\n action: DatabaseActionType;\n databaseId: string;\n authorizedBy: string;\n denialReason: string;\n evaluationId?: string;\n timestamp: string;\n context: Record<string, unknown>;\n}\n\nexport interface DatabaseActionOptions {\n action: DatabaseActionType;\n databaseId: string;\n authorizedBy: string;\n environment: \"production\" | \"staging\" | \"development\";\n // migration-specific\n migrationId?: string;\n migrationChecksum?: string;\n rollbackPlan?: string;\n // destructive-specific (schema.drop / table.delete)\n schemaName?: string;\n tableName?: string;\n backupVerified?: boolean;\n recoveryPointId?: string;\n // evidence callbacks — called after the gate resolves\n onPermitEvidence?: (evidence: PermitEvidence) => void | Promise<void>;\n onDenialEvidence?: (evidence: DenialEvidence) => void | Promise<void>;\n // escalation overrides\n waitMs?: number;\n onEscalationCreated?: (handle: EscalationHandle) => void;\n apiKey?: string;\n baseUrl?: string;\n}\n\nexport async function protectDatabaseAction(\n opts: DatabaseActionOptions,\n): Promise<ApprovalPermit | Permit> {\n // ── Validate required fields ─────────────────────────────────────────────\n\n if (opts.action === \"database.migration.apply\") {\n if (!opts.migrationId) {\n throw new TypeError(\n `Database action 'database.migration.apply' requires 'migrationId'`,\n );\n }\n if (!opts.migrationChecksum) {\n throw new TypeError(\n `Database action 'database.migration.apply' requires 'migrationChecksum'`,\n );\n }\n if (opts.environment === \"production\" && !opts.rollbackPlan) {\n throw new TypeError(\n `Database action 'database.migration.apply' in production requires 'rollbackPlan'`,\n );\n }\n }\n\n if (opts.action === \"database.schema.drop\") {\n if (!opts.schemaName) {\n throw new TypeError(\n `Database action 'database.schema.drop' requires 'schemaName'`,\n );\n }\n if (!opts.backupVerified) {\n throw new TypeError(\n `Database action 'database.schema.drop' requires 'backupVerified: true'`,\n );\n }\n if (!opts.recoveryPointId) {\n throw new TypeError(\n `Database action 'database.schema.drop' requires 'recoveryPointId'`,\n );\n }\n }\n\n if (opts.action === \"database.table.delete\") {\n if (!opts.tableName) {\n throw new TypeError(\n `Database action 'database.table.delete' requires 'tableName'`,\n );\n }\n if (!opts.backupVerified) {\n throw new TypeError(\n `Database action 'database.table.delete' requires 'backupVerified: true'`,\n );\n }\n if (!opts.recoveryPointId) {\n throw new TypeError(\n `Database action 'database.table.delete' requires 'recoveryPointId'`,\n );\n }\n }\n\n // ── Determine risk profile ────────────────────────────────────────────────\n\n const isDestructive =\n opts.action === \"database.schema.drop\" ||\n opts.action === \"database.table.delete\";\n const riskLevel = isDestructive ? \"critical\" : \"high\";\n\n // migration in production is not machine-executable; destructive never is\n const machineExecutable =\n opts.action === \"database.migration.apply\" &&\n opts.environment !== \"production\";\n\n // ── Build context ─────────────────────────────────────────────────────────\n\n const ctx = buildActionContext({\n actor: {\n id: opts.authorizedBy,\n type: \"human\",\n },\n resource: {\n id: opts.databaseId,\n type: \"database\",\n sensitivity: \"restricted\",\n },\n environment: opts.environment,\n action_meta: {\n risk_level: riskLevel,\n reversibility: isDestructive ? \"irreversible\" : \"reversible\",\n description: `Database action '${opts.action}' on database '${opts.databaseId}'`,\n },\n extra: {\n database_action: opts.action,\n database_id: opts.databaseId,\n machine_executable: machineExecutable,\n ...(isDestructive ? { deny_by_default: true } : {}),\n ...(opts.migrationId !== undefined\n ? { migration_id: opts.migrationId }\n : {}),\n ...(opts.migrationChecksum !== undefined\n ? { migration_checksum: opts.migrationChecksum }\n : {}),\n ...(opts.rollbackPlan !== undefined\n ? { rollback_plan: opts.rollbackPlan }\n : {}),\n ...(opts.schemaName !== undefined\n ? { schema_name: opts.schemaName }\n : {}),\n ...(opts.tableName !== undefined ? { table_name: opts.tableName } : {}),\n ...(opts.backupVerified !== undefined\n ? { backup_verified: opts.backupVerified }\n : {}),\n ...(opts.recoveryPointId !== undefined\n ? { recovery_point_id: opts.recoveryPointId }\n : {}),\n },\n });\n\n const request = {\n action: opts.action,\n agent: opts.authorizedBy,\n context: flattenActionContext(ctx),\n };\n\n // ── Route through gate ────────────────────────────────────────────────────\n\n if (machineExecutable) {\n // staging/development migration: direct protect()\n try {\n const result = await protect(request);\n if (opts.onPermitEvidence) {\n const permitToken = result.permitId;\n await opts.onPermitEvidence({\n action: opts.action,\n databaseId: opts.databaseId,\n authorizedBy: opts.authorizedBy,\n permitToken,\n timestamp: new Date().toISOString(),\n context: request.context as Record<string, unknown>,\n });\n }\n return result;\n } catch (err) {\n if (err instanceof AtlaSentDeniedError && opts.onDenialEvidence) {\n await opts.onDenialEvidence({\n action: opts.action,\n databaseId: opts.databaseId,\n authorizedBy: opts.authorizedBy,\n denialReason: err.reason ?? \"denied\",\n evaluationId: err.evaluationId,\n timestamp: new Date().toISOString(),\n context: request.context as Record<string, unknown>,\n });\n }\n throw err;\n }\n }\n\n // non-machine-executable: escalation required\n const quorum = isDestructive ? \"two_thirds\" : \"single_approver\";\n const defaultWaitMs = isDestructive\n ? 24 * 60 * 60 * 1000 // 24h for destructive\n : 4 * 60 * 60 * 1000; // 4h for production migration\n\n const escalationOpts = {\n escalationReason: `Database action '${opts.action}' on '${opts.databaseId}' requires human review (machine_executable: false)`,\n assignedToRole: \"database-admin\",\n quorumRequired: quorum as \"single_approver\" | \"two_thirds\",\n waitMs: opts.waitMs ?? defaultWaitMs,\n ...(opts.onEscalationCreated !== undefined\n ? { onEscalationCreated: opts.onEscalationCreated }\n : {}),\n ...(opts.apiKey !== undefined ? { apiKey: opts.apiKey } : {}),\n ...(opts.baseUrl !== undefined ? { baseUrl: opts.baseUrl } : {}),\n };\n\n try {\n const result = await protectOrEscalate(request, escalationOpts);\n if (opts.onPermitEvidence) {\n const permitToken =\n \"permit_token\" in result\n ? (result as { permit_token: string }).permit_token\n : result.escalationId || result.permitId;\n await opts.onPermitEvidence({\n action: opts.action,\n databaseId: opts.databaseId,\n authorizedBy: opts.authorizedBy,\n permitToken,\n timestamp: new Date().toISOString(),\n context: request.context as Record<string, unknown>,\n });\n }\n return result;\n } catch (err) {\n if (err instanceof AtlaSentDeniedError && opts.onDenialEvidence) {\n await opts.onDenialEvidence({\n action: opts.action,\n databaseId: opts.databaseId,\n authorizedBy: opts.authorizedBy,\n denialReason: err.reason ?? \"denied\",\n evaluationId: err.evaluationId,\n timestamp: new Date().toISOString(),\n context: request.context as Record<string, unknown>,\n });\n }\n throw err;\n }\n}\n\nexport async function protectDatabaseMigration(\n opts: Omit<DatabaseActionOptions, \"action\"> & {\n migrationId: string;\n migrationChecksum: string;\n },\n): Promise<ApprovalPermit | Permit> {\n return protectDatabaseAction({ ...opts, action: \"database.migration.apply\" });\n}\n\nexport async function protectDatabaseSchemaDrop(\n opts: Omit<DatabaseActionOptions, \"action\"> & {\n schemaName: string;\n backupVerified: true;\n recoveryPointId: string;\n },\n): Promise<ApprovalPermit | Permit> {\n return protectDatabaseAction({ ...opts, action: \"database.schema.drop\" });\n}\n\nexport async function protectDatabaseTableDelete(\n opts: Omit<DatabaseActionOptions, \"action\"> & {\n tableName: string;\n backupVerified: true;\n recoveryPointId: string;\n },\n): Promise<ApprovalPermit | Permit> {\n return protectDatabaseAction({ ...opts, action: \"database.table.delete\" });\n}\n","/**\n * Wire types for `POST /v1-decisions-replay/:id/replay`.\n *\n * Re-evaluates a recorded decision against its originally-pinned policy\n * bundle and engine version, then reports whether the result agrees with\n * what was recorded. Side-effect-free: no audit chain row is written and\n * no permit is issued (see ADR-016).\n *\n * Mirrors `_handleReplayPost` in atlasent-api's\n * `supabase/functions/v1-decisions-replay/handler.ts`. Variance kinds and\n * envelope-verification states are pinned to the API contract — keep this\n * file aligned with `_shared/decision-replay.ts` if the surface evolves.\n *\n * Per AtlaSent's versioning doctrine `/v1/decisions/:id/replay` is an\n * **alpha** endpoint; shapes can change without a deprecation cycle until\n * it graduates to stable v1 (see atlasent-api `docs/STABLE_V2_PROMOTION.md`).\n */\n\n/**\n * Replay variance — superset covering both the raw wire values used by\n * `replayDecision()` and the SDK-canonical values used by `replay()`.\n *\n * Raw wire values (replayDecision): NONE, DECISION_CHANGED, ENVELOPE_DRIFT\n * SDK-canonical values (replay): NONE, POLICY_DRIFT, ENVELOPE_DRIFT,\n * ENGINE_DRIFT, CHAIN_TAMPER, BUNDLE_MISSING\n */\nexport type ReplayVarianceKind =\n | \"NONE\"\n | \"DECISION_CHANGED\"\n | \"POLICY_DRIFT\"\n | \"ENVELOPE_DRIFT\"\n | \"ENGINE_DRIFT\"\n | \"CHAIN_TAMPER\"\n | \"BUNDLE_MISSING\";\n\n/** Engine-version registry classification (ADR-017). `unknown` covers\n * NULL engine_version (pre-replay-era rows) and registry-misses. */\nexport type EngineVersionKind =\n | \"active\"\n | \"retired\"\n | \"archival\"\n | \"unknown\";\n\n/** Envelope hash verification outcome for the recorded request envelope.\n * `verified` = recomputed hash matched; `drift` = mismatch; `envelope_missing`\n * = recorded hash points at a content_envelopes row that no longer exists;\n * `absent` = the original evaluation predates envelope_hash capture. */\nexport type EnvelopeVerification =\n | \"verified\"\n | \"drift\"\n | \"absent\"\n | \"envelope_missing\";\n\n/** Mirror of `decision` enum on the original evaluation. */\nexport type ReplayDecisionValue = \"allow\" | \"deny\" | \"hold\" | \"escalate\";\n\n/** Envelope-drift diagnostic. Present only when `variance === \"ENVELOPE_DRIFT\"`. */\nexport interface EnvelopeDriftDetail {\n recorded_hash: string;\n recomputed_hash: string;\n}\n\n/**\n * Successful POST /v1-decisions-replay/:id/replay response. The shape is\n * additive — additional fields may appear in future API versions.\n */\nexport interface ReplayDecisionResponse {\n decision_id: string;\n /** What the original decision was at evaluate time. */\n original_decision: ReplayDecisionValue;\n /** Recorded deny code from the original decision, if any. */\n original_deny_code?: string;\n /** Re-evaluated decision. Absent when replay short-circuits on\n * ENVELOPE_DRIFT — in that case the original decision is the only\n * authoritative value and no replay was run. */\n replay_decision?: ReplayDecisionValue;\n replay_deny_code?: string;\n /** Engine version string recorded with the original decision, or\n * `undefined` for pre-replay-era rows. */\n engine_version?: string;\n engine_version_kind: EngineVersionKind;\n /** Always `true` on a 200 — the handler refuses replay (409) when the\n * engine version does not accept replay. */\n accepts_replay: boolean;\n variance: ReplayVarianceKind;\n envelope_verification: EnvelopeVerification;\n envelope_drift_detail?: EnvelopeDriftDetail;\n replayed_at: string;\n}\n\n// ── ADR-015 Phase C — SDK-canonical replay surface ────────────────────────────\n\n/** Input to {@link AtlaSentClient.replay}. */\nexport interface ReplayRequest {\n /** The evaluation/decision ID to replay. */\n evaluationId: string;\n}\n\nimport { createHash } from \"node:crypto\";\nimport type { RateLimitState } from \"./types.js\";\nimport type { DecisionCanonical } from \"./types.js\";\n\n/**\n * Result of {@link AtlaSentClient.replay}.\n *\n * Uses SDK-canonical variance kinds (see {@link ReplayVarianceKind}).\n * `DECISION_CHANGED` on the wire maps to `POLICY_DRIFT` here.\n * 409 responses map to `ENGINE_DRIFT` or `BUNDLE_MISSING` and are never\n * thrown — callers can always switch on `varianceKind`.\n */\nexport interface ReplayResponse {\n /** The decision/evaluation ID that was replayed. */\n decisionId: string;\n /** SDK-canonical variance outcome. */\n varianceKind: ReplayVarianceKind;\n /** The original recorded decision. */\n originalDecision: DecisionCanonical;\n /** Original deny code, if any. */\n originalDenyCode?: string;\n /** Re-evaluated decision. Absent when `varianceKind === \"ENVELOPE_DRIFT\"`. */\n replayedDecision?: DecisionCanonical;\n replayedDenyCode?: string;\n engineVersion?: string;\n engineVersionKind?: string;\n /** Whether the evaluation was eligible for replay. `false` for 409 responses. */\n acceptsReplay: boolean;\n envelopeVerification?: string;\n /** ISO-8601 timestamp of the replay. */\n replayedAt: string;\n /** Rate-limit state from response headers. */\n rateLimit: RateLimitState | null;\n}\n\n// ── Phase 3 offline bundle verification ───────────────────────────────────────\n\n/**\n * Result of offline evidence bundle verification via {@link verifyEvidenceBundle}.\n *\n * Named distinctly from {@link BundleVerificationResult} in `auditBundle.ts`\n * which carries chain-integrity and signature fields for audit export bundles.\n * This result covers the lighter-weight structural + hash-integrity check used\n * by the Phase 3 replay client.\n */\nexport interface EvidenceBundleVerifyResult {\n /** `true` when all checks passed. */\n valid: boolean;\n /** The `bundle_id` from the top-level bundle object, if present. */\n bundleId: string | undefined;\n /** The first `permit_id` found in the permits array (convenience). */\n permitId: string | undefined;\n /** Human-readable failure description; `undefined` when `valid` is `true`. */\n reason: string | undefined;\n}\n\n/**\n * Offline shape of an evidence bundle as returned by\n * `GET /v1/evidence-bundles/:id` and downloaded for replay verification.\n */\nexport interface OfflineEvidenceBundleData {\n bundle_id?: string;\n org_id?: string;\n status?: string;\n permits?: Array<{ permit_id?: string; evaluation_id?: string }>;\n hash_chain?: { root_hash?: string; entry_count?: number };\n [key: string]: unknown;\n}\n\n/**\n * Verify an evidence bundle offline without a backend round-trip.\n *\n * Checks:\n * 1. Bundle has required fields (`bundle_id`, `org_id`, `status`).\n * 2. `status` is `\"ready\"`.\n * 3. Root hash integrity if `hash_chain` is present (SHA-256 via Node crypto).\n *\n * Does **not** require `AtlaSentClient` or network access.\n *\n * @example\n * ```ts\n * import { verifyEvidenceBundle } from \"@atlasent/sdk\";\n *\n * const result = verifyEvidenceBundle(bundleJson);\n * if (result.valid) {\n * console.log(\"verified, first permit:\", result.permitId);\n * } else {\n * console.error(\"verification failed:\", result.reason);\n * }\n * ```\n */\nexport function verifyEvidenceBundle(\n bundle: OfflineEvidenceBundleData,\n): EvidenceBundleVerifyResult {\n if (!bundle || typeof bundle !== \"object\" || Array.isArray(bundle)) {\n return {\n valid: false,\n bundleId: undefined,\n permitId: undefined,\n reason: \"bundle must be a non-null object\",\n };\n }\n\n for (const field of [\"bundle_id\", \"org_id\", \"status\"] as const) {\n if (!(field in bundle)) {\n return {\n valid: false,\n bundleId: bundle.bundle_id,\n permitId: undefined,\n reason: `missing required field: ${field}`,\n };\n }\n }\n\n if (bundle.status !== \"ready\") {\n return {\n valid: false,\n bundleId: bundle.bundle_id,\n permitId: undefined,\n reason: `bundle status is '${bundle.status}', expected 'ready'`,\n };\n }\n\n const permits = bundle.permits ?? [];\n\n if (bundle.hash_chain?.root_hash !== undefined) {\n const computed = _computeEvidenceRootHash(permits);\n if (computed !== bundle.hash_chain.root_hash) {\n return {\n valid: false,\n bundleId: bundle.bundle_id,\n permitId: undefined,\n reason: \"root hash mismatch — bundle may have been tampered\",\n };\n }\n }\n\n return {\n valid: true,\n bundleId: bundle.bundle_id,\n permitId: permits[0]?.permit_id,\n reason: undefined,\n };\n}\n\n/**\n * Compute a deterministic SHA-256 root hash over the permits list.\n * Uses `JSON.stringify` with sorted keys via a replacer for canonical form.\n *\n * @internal\n */\nexport function _computeEvidenceRootHash(\n permits: OfflineEvidenceBundleData[\"permits\"],\n): string {\n const list = permits ?? [];\n // Sort keys deterministically at every depth using JSON + replacer pattern\n const canonical = JSON.stringify(list, (_, value) => {\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).sort(([a], [b]) =>\n a < b ? -1 : a > b ? 1 : 0,\n ),\n );\n }\n return value;\n });\n return createHash(\"sha256\").update(canonical).digest(\"hex\");\n}\n","/**\n * Human-in-the-loop (HITL) types — wire shape for `/v1/hitl/*`.\n *\n * Mirrors `supabase/functions/_shared/hitl-policy.ts` and the\n * `hitl_escalations` row shape after migration 20260507060000.\n * Treat as wire-types only: do not embed business logic that the\n * server-side resolver owns (quorum math, status transitions).\n */\n\nexport type HitlQuorumTier =\n | \"single_approver\"\n | \"simple_majority\"\n | \"two_thirds\"\n | \"unanimous\";\n\nexport type HitlStatus =\n | \"pending\"\n | \"escalated\"\n | \"approved\"\n | \"rejected\"\n | \"auto_approved\"\n | \"timed_out\";\n\nexport type HitlFallbackDecision = \"reject\" | \"approve\";\n\nexport interface HitlQuorumProgress {\n required: number;\n approved: number;\n rejected: number;\n remaining: number;\n satisfied: boolean;\n rejected_terminal: boolean;\n}\n\nexport interface HitlEscalation {\n id: string;\n org_id: string;\n agent_id: string;\n sandbox_run_id: string | null;\n status: HitlStatus;\n escalation_reason: string;\n proposed_action: Record<string, unknown> | null;\n risk_score: number | null;\n assigned_to_user_id: string | null;\n assigned_to_role: string | null;\n resolved_by: string | null;\n resolution_note: string | null;\n auto_approved_reason: string | null;\n resolved_at: string | null;\n timeout_at: string | null;\n created_at: string;\n\n quorum_required: HitlQuorumTier;\n min_approvers: number;\n approver_pool_size: number;\n escalation_depth: number;\n max_escalation_depth: number;\n fallback_decision: HitlFallbackDecision;\n governance_advisory_id: string | null;\n expired_reason: \"sla_expired\" | \"escalation_chain_exhausted\" | \"manual_expire\" | null;\n\n /**\n * Arbitrary key/value metadata attached at creation time.\n * `null` when none was provided.\n */\n metadata: Record<string, unknown> | null;\n\n quorum_progress?: HitlQuorumProgress;\n\n // Heterogeneous N-of-M extension. Empty `approver_pool` means the\n // legacy single-pool path applies (server-side resolver decides).\n approver_pool?: HitlApproverPoolEntry[];\n quorum_threshold?: number | null;\n ai_unavailable_fallback?: HitlAiUnavailableFallback;\n fallback_human_role?: string | null;\n pool_unavailable_at?: string | null;\n\n /** Populated when the server attaches a heterogeneous-quorum tally. */\n heterogeneous_tally?: HitlHeterogeneousQuorumTally;\n}\n\nexport interface HitlApprovalRecord {\n id: string;\n user_id: string | null;\n actor_label: string | null;\n decision: \"approve\" | \"reject\";\n note: string | null;\n quorum_at_vote: HitlQuorumTier;\n created_at: string;\n /** Which kind of approver cast this vote (default `\"human\"`). */\n approver_type?: HitlApproverType;\n}\n\nexport interface HitlChainHop {\n id: string;\n depth: number;\n from_user_id: string | null;\n from_role: string | null;\n to_user_id: string | null;\n to_role: string | null;\n escalated_by: string | null;\n reason: string | null;\n created_at: string;\n}\n\nexport interface ListHitlEscalationsRequest {\n status?: HitlStatus;\n agentId?: string;\n assignedToUserId?: string;\n limit?: number;\n cursor?: string;\n}\n\nexport interface ListHitlEscalationsResponse {\n escalations: HitlEscalation[];\n total: number;\n next_cursor?: string;\n}\n\n/**\n * Wire shape for `POST /v1/hitl` — open a new escalation.\n *\n * The agent-side bridge between a `hold` outcome from `protect()`\n * and the approval queue. Only `agent_id` and `escalation_reason`\n * are required; the rest map to defaults configured on the\n * server-side policy. Pass `approver_pool` to use the heterogeneous\n * N-of-M extension instead of the homogeneous quorum tier.\n */\nexport interface HitlCreateRequest {\n agent_id: string;\n escalation_reason: string;\n\n sandbox_run_id?: string;\n proposed_action?: Record<string, unknown>;\n risk_score?: number;\n assigned_to_user_id?: string;\n assigned_to_role?: string;\n\n quorum_required?: HitlQuorumTier;\n min_approvers?: number;\n approver_pool_size?: number;\n max_escalation_depth?: number;\n fallback_decision?: HitlFallbackDecision;\n timeout_at?: string;\n governance_advisory_id?: string;\n\n approver_pool?: HitlApproverPoolEntry[];\n quorum_threshold?: number;\n ai_unavailable_fallback?: HitlAiUnavailableFallback;\n fallback_human_role?: string;\n\n /** Arbitrary key/value metadata to attach to the escalation record. */\n metadata?: Record<string, unknown>;\n}\n\nexport interface HitlApproveRequest {\n note?: string;\n}\n\nexport interface HitlRejectRequest {\n note?: string;\n}\n\nexport interface HitlEscalateRequest {\n to_role?: string;\n to_user_id?: string;\n reason?: string;\n}\n\n/**\n * Wire shape for `POST /v1/escalations/:id/respond` — cast a vote on an\n * existing escalation. Mirrors the `RespondBody` schema in\n * atlasent-control-plane `api/src/routes/hitl.ts`.\n */\nexport interface HitlRespondRequest {\n /** The approver's decision. */\n decision: \"approve\" | \"reject\";\n /** Optional human-readable note attached to the approval record. */\n note?: string;\n}\n\n/**\n * Translate a quorum tier and approver-pool size to the minimum\n * number of `approve` votes required to resolve the escalation.\n *\n * Mirrors the canonical `requiredApproverCount()` in\n * atlasent-api `_shared/hitl-policy.ts` and the SQL\n * `public.hitl_required_approver_count()` helper. Provided here so\n * SDK consumers can render a \"you are the Nth of M approvers\" hint\n * without a server round-trip; the authoritative count still comes\n * from the server's `quorum_progress` payload.\n */\nexport function hitlRequiredApproverCount(\n quorum: HitlQuorumTier,\n poolSize: number,\n): number {\n const n = Number.isFinite(poolSize) && poolSize >= 1 ? Math.floor(poolSize) : 1;\n switch (quorum) {\n case \"single_approver\":\n return 1;\n case \"simple_majority\":\n return Math.floor(n / 2) + 1;\n case \"two_thirds\":\n return Math.ceil((2 * n) / 3);\n case \"unanimous\":\n return n;\n }\n}\n\n// ── Heterogeneous N-of-M quorum (migration 20260509120002) ───────────\n//\n// Mirrors the SQL `approver_pool` jsonb shape and\n// `evaluate_heterogeneous_quorum()` row shape. The legacy\n// homogeneous path (`approver_pool_size` + `quorum_required` tier) is\n// still authoritative when `approver_pool` is empty; these types\n// describe the new path only.\n\nexport type HitlApproverType =\n | \"human\"\n | \"ai_supervisor\"\n | \"automated_compliance\"\n | \"hardware_signer\"\n | \"service_account\";\n\nexport type HitlAiUnavailableFallback =\n | \"escalate_to_human\"\n | \"reduce_pool\"\n | \"fail_closed\";\n\nexport interface HitlApproverPoolEntry {\n type: HitlApproverType;\n principal_id: string;\n role?: string;\n weight?: number;\n required?: boolean;\n /** Marker for slots inserted by the AI-unavailable fallback. */\n origin?: string;\n}\n\nexport interface HitlHeterogeneousQuorumExtension {\n approver_pool: HitlApproverPoolEntry[];\n quorum_threshold: number | null;\n ai_unavailable_fallback: HitlAiUnavailableFallback;\n fallback_human_role: string | null;\n pool_unavailable_at: string | null;\n}\n\nexport interface HitlHeterogeneousQuorumTally {\n pool_size: number;\n effective_pool_size: number;\n required_threshold: number;\n approve_count: number;\n reject_count: number;\n unavailable_count: number;\n /** Per-approver-type breakdown: `{ ai_supervisor: { approve: 1, reject: 0 } }` */\n by_type: Record<HitlApproverType, { approve: number; reject: number }>;\n meets_threshold: boolean;\n any_required_reject: boolean;\n any_required_missing: boolean;\n}\n\n/**\n * Detail response returned by `GET /v1/escalations/:id`.\n *\n * Mirrors `HitlDetailResponse` in atlasent-control-plane\n * `api/src/schemas/hitl.ts`.\n */\nexport interface HitlDetailResponse {\n escalation: HitlEscalation;\n approval_records: HitlApprovalRecord[];\n}\n\n/**\n * Paginated list response returned by `GET /v1/escalations`.\n *\n * Mirrors `HitlListResponse` in atlasent-control-plane\n * `api/src/schemas/hitl.ts`.\n */\nexport interface HitlListResponse {\n escalations: HitlEscalation[];\n total: number;\n next_cursor: string | null;\n}\n","/**\n * Sandbox simulation diff — wire shape for `GET /v1/agent-sandbox/:id/diff`.\n *\n * Mirrors the `export_sandbox_diff()` SQL function added in migration\n * 20260509120000. Lets a caller render a sandbox-vs-live preview\n * before promoting a simulation to a real execution. Once a sandbox\n * run reaches a terminal status it is auto-torn-down; a follow-up\n * call returns the {@link SandboxDiffEmpty} shape so the UI can\n * surface \"this run has been finalised\" without a 404.\n */\n\nexport type SandboxRunMode =\n | \"dry_run\"\n | \"simulation\"\n | \"constrained_execution\"\n | \"production_execution\";\n\nexport type SandboxRunStatus =\n | \"pending\"\n | \"running\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\"\n | \"timed_out\";\n\nexport type SandboxWriteOp = \"insert\" | \"update\" | \"delete\";\n\nexport interface SandboxRunWrite {\n sequence: number;\n live_table: string;\n live_pk: string | null;\n op: SandboxWriteOp;\n payload_before: Record<string, unknown> | null;\n payload_after: Record<string, unknown> | null;\n metadata: Record<string, unknown>;\n created_at: string;\n}\n\nexport interface SandboxDiffPerTable {\n total: number;\n insert: number;\n update: number;\n delete: number;\n}\n\n/** Returned when staging rows are still present for the run. */\nexport interface SandboxDiff {\n simulation_run_id: string;\n org_id: string;\n final_status: SandboxRunStatus;\n mode: SandboxRunMode;\n total_writes: number;\n /** Keyed by live table name. */\n summary: Record<string, SandboxDiffPerTable>;\n writes: SandboxRunWrite[];\n}\n\n/**\n * Returned when the run has been torn down — staging rows are gone\n * and the audit-log `agent_sandbox.teardown` event is the only\n * post-mortem record.\n */\nexport interface SandboxDiffEmpty {\n simulation_run_id: string;\n status: SandboxRunStatus;\n mode: SandboxRunMode;\n torn_down: boolean;\n total_writes: 0;\n summary: Record<string, never>;\n writes: [];\n}\n\nexport type SandboxDiffResponse = SandboxDiff | SandboxDiffEmpty;\n\n/**\n * `true` when the response carries staging rows (i.e. the run has not\n * been torn down yet). Narrow before reading `summary` / `writes`.\n */\nexport function isSandboxDiffPopulated(\n r: SandboxDiffResponse,\n): r is SandboxDiff {\n return r.total_writes > 0 || (r as SandboxDiff).org_id !== undefined;\n}\n","/**\n * Delegation revocation propagation — wire shape for the\n * `propagate_delegation_revocation()` summary returned by\n * `/v1/authority-delegations/:id/revoke` (and emitted as the\n * `authority_delegation.propagated` audit event).\n *\n * Mirrors migration 20260509120001. The propagator is invoked\n * automatically on `status -> revoked` via DB trigger; consumers\n * see the summary either as the audit-event payload (asynchronous)\n * or attached to the revoke response (synchronous).\n */\n\nexport interface DelegationPropagationSummary {\n delegation_id: string;\n /** `[delegator_user_id, delegate_user_id]` — uuids as strings. */\n principals: [string, string];\n /** Phase-B role-justified delegations carry the role; user-justified\n * delegations omit it. */\n delegator_role?: string | null;\n hitl_reassigned: number;\n financial_invalidated: number;\n policies_flagged: number;\n revoked_reason?: string | null;\n}\n\n/**\n * Convenience predicate: `true` when the revocation produced any\n * downstream effect. Useful for \"are we sure?\" UI guards before\n * surfacing the summary toast.\n */\nexport function delegationPropagationHadEffect(\n s: DelegationPropagationSummary,\n): boolean {\n return (\n s.hitl_reassigned > 0 ||\n s.financial_invalidated > 0 ||\n s.policies_flagged > 0\n );\n}\n","/**\n * Context Envelope types — structured input set for execution-time\n * authorization decisions.\n *\n * These types mirror the `context_envelopes` + `context_signals` +\n * `context_namespace_registry` DB schema introduced in migration\n * `20260522070000_context_envelope_v1.sql`.\n *\n * A V1 envelope has a fixed top-level keyset (the canonical namespace\n * catalog). The recorder validates incoming envelopes against this catalog\n * and rejects unknown top-level keys in strict mode (V2+).\n */\n\n/** Canonical V1 envelope top-level namespace keys. */\nexport const CONTEXT_NAMESPACES = [\n \"intent\",\n \"actor\",\n \"resource\",\n \"environment\",\n \"history\",\n \"evidence_refs\",\n \"signals\",\n \"compatibility_overrides\",\n] as const;\n\nexport type ContextNamespaceKey = (typeof CONTEXT_NAMESPACES)[number];\n\n/** One row from `context_namespace_registry`. */\nexport interface ContextNamespaceEntry {\n namespace: ContextNamespaceKey;\n purpose: string;\n owner: string;\n /** `true` for the `signals` namespace — derived / inferred inputs. */\n is_signal: boolean;\n introduced_in_version: string;\n}\n\n/** One signal attached to a context envelope. */\nexport interface ContextSignal {\n /** Dotted path under the `signals` namespace (e.g. `\"signals.actor_anomaly\"`). */\n namespace: string;\n /** Named source that produced this signal. */\n source: string;\n /** Confidence in [0.0, 1.0]. `null` when not reported. */\n confidence: number | null;\n /** Arbitrary signal payload. */\n payload: Record<string, unknown>;\n /** ISO-8601 timestamp when the signal was produced. */\n produced_at: string;\n /** Seconds until the signal is considered stale. `null` = no expiry. */\n ttl_seconds: number | null;\n}\n\n/**\n * A canonical V1 context envelope — the deterministic input set that\n * powers execution-time authorization decisions.\n *\n * Envelopes are append-only and hash-committed: `envelope_hash` is\n * SHA-256 of the canonical JSON form. The permit issued by the evaluator\n * commits to this hash so the audit chain, the permit, and a verifier all\n * agree on what was evaluated.\n *\n * ```ts\n * import type { ContextEnvelope } from \"@atlasent/sdk\";\n *\n * const envelope: ContextEnvelope = {\n * request_id: \"req_abc123\",\n * org_id: \"org_xyz\",\n * envelope_version: \"atlasent.v1\",\n * protected_action: \"production.deploy\",\n * envelope: {\n * intent: { action: \"deploy\", summary: \"Release v1.2.0\" },\n * actor: { id: \"agent:deploy-bot\", roles: [\"deploy\"] },\n * environment: { name: \"production\", freeze_window: false },\n * },\n * envelope_hash: \"a3f...\",\n * evidence_refs: [],\n * recorded_by: \"v1-evaluate\",\n * received_at: \"2026-06-02T00:00:00Z\",\n * signals: [],\n * };\n * ```\n */\nexport interface ContextEnvelope {\n /** Caller-supplied idempotency / correlation key. */\n request_id: string;\n org_id: string;\n envelope_version: \"atlasent.v1\";\n /** The namespaced action type this envelope covers. */\n protected_action: string;\n /**\n * The full validated envelope payload. Top-level keys must be in\n * {@link CONTEXT_NAMESPACES}. Unknown keys are warn-only in V1.\n */\n envelope: Partial<Record<ContextNamespaceKey, unknown>>;\n /**\n * SHA-256 hex of `canonical-JSON(envelope)`. Three points of truth\n * (permit, audit chain, verifier) reduce to this single hash.\n */\n envelope_hash: string;\n /** UUIDs of governance evidence rows referenced by this envelope. */\n evidence_refs: string[];\n /** Which handler wrote this row (e.g. `\"v1-evaluate\"`). */\n recorded_by: string;\n /** ISO-8601 timestamp. */\n received_at: string;\n /** Signals attached to this envelope. */\n signals: ContextSignal[];\n}\n\n/**\n * Minimal input shape for recording a context envelope via\n * `context_record_envelope()`. The hash is computed by the caller\n * before submitting.\n */\nexport interface RecordContextEnvelopeInput {\n request_id: string;\n org_id: string;\n envelope_version: \"atlasent.v1\";\n protected_action: string;\n envelope: Partial<Record<ContextNamespaceKey, unknown>>;\n envelope_hash: string;\n evidence_refs?: string[];\n recorded_by?: string;\n signals?: Omit<ContextSignal, never>[];\n}\n","/**\n * Trust-root Phase 2 — hybrid snapshot bootstrap + revocation enforcement.\n *\n * Provides a lightweight TrustSnapshot type (numeric epoch timestamps,\n * JWK-array keys, flat revoked_kids list) alongside three helpers that\n * the verify() path and application code can call directly.\n *\n * Design decisions (ADR-005):\n *\n * - D3 (fail-closed expiry): isTrustSnapshotExpired() defaults to a 24-hour\n * TTL and returns true when the snapshot is older than that or when\n * expires_at has already passed. Callers in verify() must treat an expired\n * snapshot as a denial.\n *\n * - D4 (R2/R3 split): revoked_kids is a flat allowlist consulted for ANY\n * KID regardless of role. Role enforcement belongs in auditBundle.ts;\n * this module only answers \"is this KID revoked?\"\n *\n * - Bootstrap: bootstrapTrust() fetches the .well-known endpoint and merges\n * the response with an optional pinned snapshot. The pinned snapshot is\n * returned as-is if the fetch fails (silent fallback).\n *\n * - Refresh: background scheduling is handled by TrustRootManager in\n * trustRoot.ts. bootstrapTrust() is intentionally a one-shot function\n * for callers that need an explicit initial snapshot without wiring up\n * the full manager.\n */\n\n/**\n * Minimal JWK key entry as returned by the .well-known endpoint.\n *\n * Deliberately loose — additional vendor-defined fields (kid, use,\n * alg, crv, x, …) are preserved but not enumerated here so the type\n * survives forward additions to the key document.\n */\nexport interface JWK {\n /** Key identifier — used for revocation checks. */\n kid: string;\n /** Key type, e.g. \"OKP\", \"EC\", \"RSA\". */\n kty: string;\n [key: string]: unknown;\n}\n\n/**\n * Trust snapshot in the Phase 2 wire format.\n *\n * Uses numeric epoch-millisecond timestamps so callers can compare\n * directly with Date.now() without parsing ISO-8601 strings.\n */\nexport interface TrustSnapshot {\n /** Active verification keys from the trust root. */\n keys: JWK[];\n /** KIDs that have been revoked; any permit signed by these must be rejected. */\n revoked_kids: string[];\n /**\n * Unix epoch (ms) when this snapshot was fetched from the server.\n * Used as the reference point for TTL expiry checks.\n */\n fetched_at: number;\n /**\n * Unix epoch (ms) at which this snapshot expires regardless of TTL.\n * bootstrapTrust() derives this from the `valid_until` field in the\n * server response when available, otherwise from fetched_at + TTL.\n */\n expires_at: number;\n}\n\n/** Default snapshot TTL: 24 hours in milliseconds. */\nexport const DEFAULT_TRUST_TTL_MS = 24 * 60 * 60 * 1000;\n\n/** Wire shape of GET /.well-known/atlasent-verifier-keys.json */\ninterface VerifierKeysWire {\n keys?: unknown[];\n}\n\n/** Wire shape of GET /.well-known/atlasent-revocations.json */\ninterface RevocationsWire {\n revoked_keys?: Array<{ kid: string; [k: string]: unknown }>;\n}\n\n/** Wire shape of GET /.well-known/atlasent-trust-root.json */\ninterface TrustRootWire {\n valid_until?: string;\n issued_at?: string;\n}\n\n/**\n * Fetch a fresh TrustSnapshot from the AtlaSent trust-root documents.\n *\n * Fetches three documents from `${baseUrl}/.well-known/` in parallel:\n * - `atlasent-verifier-keys.json` — active verification keys\n * - `atlasent-revocations.json` — revoked KIDs\n * - `atlasent-trust-root.json` — validity window (valid_until, issued_at)\n *\n * Uses a 10-second timeout across all three fetches. On any failure\n * (network error, non-2xx, malformed response) the function returns the\n * `pinnedSnapshot` if provided, or re-throws the underlying error when no\n * fallback is available.\n *\n * The `expires_at` field is derived from the trust-root document's\n * `valid_until` field when present; otherwise it is set to\n * `fetched_at + ttlMs`.\n *\n * @param baseUrl Root URL of the AtlaSent keys host (no trailing slash).\n * @param pinnedSnapshot Optional pre-loaded snapshot to use as fallback.\n * @param ttlMs TTL for the snapshot in ms (default: 24 hours).\n * @param fetchImpl Custom fetch implementation (for tests/environments\n * without a global fetch).\n */\nexport async function bootstrapTrust(\n baseUrl: string,\n pinnedSnapshot?: TrustSnapshot,\n ttlMs: number = DEFAULT_TRUST_TTL_MS,\n fetchImpl: typeof fetch = globalThis.fetch,\n): Promise<TrustSnapshot> {\n let base = baseUrl;\n while (base.endsWith(\"/\")) base = base.slice(0, -1);\n const wk = `${base}/.well-known`;\n\n try {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 10_000);\n\n let keysRes: Response, revocRes: Response, indexRes: Response;\n try {\n [keysRes, revocRes] = await Promise.all([\n fetchImpl(`${wk}/atlasent-verifier-keys.json`, { signal: controller.signal }),\n fetchImpl(`${wk}/atlasent-revocations.json`, { signal: controller.signal }),\n ]);\n indexRes = await fetchImpl(`${wk}/atlasent-trust-root.json`, { signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n\n if (!keysRes.ok || !revocRes.ok || !indexRes.ok) {\n if (pinnedSnapshot !== undefined) return pinnedSnapshot;\n const failedStatus = !keysRes.ok\n ? keysRes.status\n : !revocRes.ok\n ? revocRes.status\n : indexRes.status;\n throw new Error(\n `bootstrapTrust: server returned HTTP ${failedStatus} from ${wk}`,\n );\n }\n\n const [keysWire, revocWire, indexWire] = await Promise.all([\n keysRes.json() as Promise<VerifierKeysWire>,\n revocRes.json() as Promise<RevocationsWire>,\n indexRes.json() as Promise<TrustRootWire>,\n ]);\n\n // Coerce keys to JWK[]: accept any array entry that has a `kid` string.\n const rawKeys: unknown[] = Array.isArray(keysWire.keys) ? keysWire.keys : [];\n const keys: JWK[] = rawKeys.filter(\n (k): k is JWK =>\n k !== null &&\n typeof k === \"object\" &&\n typeof (k as Record<string, unknown>).kid === \"string\" &&\n typeof (k as Record<string, unknown>).kty === \"string\",\n ) as JWK[];\n\n // Revoked KIDs from the dedicated revocations document.\n const revokedKids: string[] = Array.isArray(revocWire.revoked_keys)\n ? revocWire.revoked_keys\n .filter(\n (r): r is { kid: string } =>\n r !== null &&\n typeof r === \"object\" &&\n typeof (r as Record<string, unknown>).kid === \"string\",\n )\n .map((r) => r.kid)\n : [];\n\n const fetchedAt = Date.now();\n const expiresAt =\n typeof indexWire.valid_until === \"string\" && indexWire.valid_until.length > 0\n ? new Date(indexWire.valid_until).getTime()\n : fetchedAt + ttlMs;\n\n return {\n keys,\n revoked_kids: revokedKids,\n fetched_at: fetchedAt,\n expires_at: Number.isFinite(expiresAt) ? expiresAt : fetchedAt + ttlMs,\n };\n } catch (err) {\n if (pinnedSnapshot !== undefined) {\n // Silent fallback to the pinned snapshot (ADR-005 D2 refresh-failure policy).\n return pinnedSnapshot;\n }\n throw err;\n }\n}\n\n/**\n * Returns true when the snapshot should be treated as expired.\n *\n * A snapshot is expired when EITHER:\n * 1. `expires_at` is in the past, OR\n * 2. `fetched_at + ttlMs` is in the past (age-based eviction).\n *\n * The stricter of the two checks wins so a snapshot that was fetched\n * recently but carries an already-expired `expires_at` is still rejected.\n *\n * ADR-005 D3: callers in the verify() path MUST treat an expired\n * snapshot as a denial (`failClosedOnExpiry` is honoured by the client\n * integration — see verify.ts).\n *\n * @param snapshot The snapshot to check.\n * @param ttlMs Maximum age in ms from `fetched_at` (default: 24 hours).\n * @param nowMs Override for `Date.now()` (for testing).\n */\nexport function isTrustSnapshotExpired(\n snapshot: TrustSnapshot,\n ttlMs: number = DEFAULT_TRUST_TTL_MS,\n nowMs: number = Date.now(),\n): boolean {\n // Check explicit expiry timestamp\n if (nowMs > snapshot.expires_at) return true;\n // Check age-based TTL from when the snapshot was fetched\n if (nowMs > snapshot.fetched_at + ttlMs) return true;\n return false;\n}\n\n/**\n * Returns true when the given KID appears in the snapshot's revocation list.\n *\n * Used by the verify() path before accepting a permit's signature:\n * ```ts\n * if (isKidRevoked(snapshot, permit.kid)) {\n * return { valid: false, reason: 'SIGNING_KEY_REVOKED' };\n * }\n * ```\n *\n * @param snapshot Trust snapshot to consult.\n * @param kid Key identifier from the permit or audit bundle header.\n */\nexport function isKidRevoked(snapshot: TrustSnapshot, kid: string): boolean {\n return snapshot.revoked_kids.includes(kid);\n}\n","/**\n * Financial Action Model — canonical types for financial execution authority.\n *\n * Defines the core vocabulary for all financial actions governed by\n * AtlaSent's economic governance layer. Every consequential financial\n * operation must be classified here before execution authorization.\n *\n * Wire-stable as `financial_action.v1`.\n */\n\n/** ISO 4217 currency code. */\nexport type CurrencyCode =\n | \"USD\" | \"EUR\" | \"GBP\" | \"JPY\" | \"CAD\" | \"AUD\" | \"CHF\"\n | \"CNY\" | \"SEK\" | \"NZD\" | string;\n\n/**\n * Risk tier for a financial action.\n *\n * - low: < $1,000 — single-approver sufficient\n * - medium: $1,000–$50,000 — dual-control typically required\n * - high: $50,000–$1,000,000 — CFO-level required\n * - critical: > $1,000,000 or irreversible — board-level or emergency protocol\n */\nexport type FinancialRiskTier = \"low\" | \"medium\" | \"high\" | \"critical\";\n\n/** How accountability is distributed across parties for a financial action. */\nexport type LiabilityClassification =\n | \"individual\" // Single party bears full liability\n | \"shared\" // Multiple parties share liability proportionally\n | \"delegated\" // Liability flows to the delegate, not delegator\n | \"supervisory\" // Supervisors bear liability for team actions\n | \"emergency_override\"; // Special liability regime for emergency bypasses\n\n/** Canonical set of financial action types. */\nexport type FinancialActionType =\n | \"refund\"\n | \"payment_release\"\n | \"invoice_approval\"\n | \"payroll_execution\"\n | \"procurement_approval\"\n | \"wire_transfer\"\n | \"trading_execution\"\n | \"budget_override\"\n | \"spending_authorization\"\n | \"vendor_payment\"\n | \"subscription_cancellation\"\n | \"credit_issuance\"\n | \"fee_waiver\"\n | \"chargeback\"\n | \"contract_commitment\"\n | string;\n\n/**\n * Canonical definition of a financial action class.\n *\n * Stored in `financial_action_classes`. Drives quorum policy,\n * liability classification, and risk tier assignment.\n */\nexport interface FinancialActionClass {\n /** Stable identifier (e.g. \"wire_transfer.domestic\"). */\n readonly action_class_id: string;\n readonly name: string;\n readonly action_type: FinancialActionType;\n readonly risk_tier: FinancialRiskTier;\n /** Minimum number of approvals before execution is permitted. */\n readonly required_approvals: number;\n readonly liability_classification: LiabilityClassification;\n /** Whether this action is reversible post-execution. */\n readonly reversible: boolean;\n /** Maximum allowed execution value for autonomous agents (null = no ceiling). */\n readonly autonomous_ceiling: number | null;\n readonly ceiling_currency: CurrencyCode | null;\n readonly created_at: string;\n readonly description?: string;\n}\n\n/** Status of a financial execution record. */\nexport type FinancialExecutionStatus =\n | \"pending_approval\"\n | \"approved\"\n | \"executing\"\n | \"completed\"\n | \"failed\"\n | \"reversed\"\n | \"disputed\"\n | \"frozen\";\n\n/**\n * Immutable record of a financial action execution.\n *\n * Written at authorization time. Stored in `financial_execution_records`.\n */\nexport interface FinancialExecutionRecord {\n readonly execution_id: string;\n readonly action_class_id: string;\n readonly org_id: string;\n readonly action_value: number;\n readonly currency: CurrencyCode;\n readonly risk_tier: FinancialRiskTier;\n readonly liability_classification: LiabilityClassification;\n readonly initiator_id: string;\n readonly executor_id: string;\n /** Ordered list of approver IDs. */\n readonly approver_ids: readonly string[];\n /** AtlaSent permit IDs — one per approval stage. */\n readonly permit_ids: readonly string[];\n readonly override_applied: boolean;\n readonly override_id: string | null;\n readonly status: FinancialExecutionStatus;\n readonly authorized_at: string;\n readonly executed_at: string | null;\n /** Hash-chained audit trail entry. */\n readonly audit_hash: string;\n readonly context: Record<string, unknown>;\n}\n\n/** Threshold configuration for risk-tier escalation. */\nexport interface RiskTierThreshold {\n readonly tier: FinancialRiskTier;\n /** Inclusive lower bound in the reference currency. */\n readonly lower_bound: number;\n /** Exclusive upper bound; null means unbounded. */\n readonly upper_bound: number | null;\n readonly reference_currency: CurrencyCode;\n}\n\n/** Default risk tier thresholds (USD-denominated). */\nexport const DEFAULT_RISK_TIER_THRESHOLDS: readonly RiskTierThreshold[] = [\n { tier: \"low\", lower_bound: 0, upper_bound: 1_000, reference_currency: \"USD\" },\n { tier: \"medium\", lower_bound: 1_000, upper_bound: 50_000, reference_currency: \"USD\" },\n { tier: \"high\", lower_bound: 50_000, upper_bound: 1_000_000, reference_currency: \"USD\" },\n { tier: \"critical\", lower_bound: 1_000_000, upper_bound: null, reference_currency: \"USD\" },\n] as const;\n\n/**\n * Classify a financial action's risk tier based on its value.\n */\nexport function classifyRiskTier(\n value: number,\n thresholds: readonly RiskTierThreshold[] = DEFAULT_RISK_TIER_THRESHOLDS,\n): FinancialRiskTier {\n for (const t of thresholds) {\n if (value >= t.lower_bound && (t.upper_bound === null || value < t.upper_bound)) {\n return t.tier;\n }\n }\n return \"critical\";\n}\n\n/**\n * Return true when the action value is within the autonomous execution ceiling.\n * A null ceiling means no ceiling is configured (always within bounds).\n */\nexport function withinAutonomousCeiling(\n actionValue: number,\n ceiling: number | null,\n): boolean {\n if (ceiling === null) return true;\n return actionValue <= ceiling;\n}\n","/**\n * Liability Attribution Engine.\n *\n * Tracks and computes liability across the full chain of parties involved\n * in a financial action: who authorized, delegated, executed, overrode,\n * and approved exceptions.\n *\n * Supports shared, delegated, supervisory, and emergency-override liability\n * regimes. Every attribution record is immutable once written.\n *\n * Wire-stable as `liability_attribution.v1`.\n */\n\nimport type { FinancialRiskTier, LiabilityClassification } from \"./financialAction.js\";\n\n/** The role a party played in a financial action. */\nexport type LiabilityPartyRole =\n | \"authorizer\" // Granted initial authorization\n | \"delegator\" // Delegated authority to another party\n | \"delegate\" // Received delegated authority\n | \"executor\" // Performed the actual execution\n | \"approver\" // Approved at a quorum stage\n | \"override_actor\" // Applied an override or exception\n | \"supervisor\" // Bears supervisory liability for the action\n | \"exception_approver\"; // Approved a policy exception\n\n/** A single party in the liability chain. */\nexport interface LiabilityParty {\n readonly party_id: string;\n readonly party_label: string;\n readonly party_type: \"human\" | \"agent\" | \"system\";\n readonly role: LiabilityPartyRole;\n /** Fractional liability weight (0–1); all parties in chain sum to 1. */\n readonly liability_weight: number;\n readonly acted_at: string;\n readonly permit_id: string | null;\n}\n\n/**\n * Immutable liability attribution record for a financial execution.\n *\n * Stored in `liability_attribution_records`. One record per execution.\n */\nexport interface LiabilityAttributionRecord {\n readonly attribution_id: string;\n readonly execution_id: string;\n readonly org_id: string;\n readonly classification: LiabilityClassification;\n readonly risk_tier: FinancialRiskTier;\n /** Ordered liability chain. First party = primary. */\n readonly liability_chain: readonly LiabilityParty[];\n readonly delegation_present: boolean;\n readonly supervisory_present: boolean;\n readonly emergency_override: boolean;\n readonly override_justification: string | null;\n readonly created_at: string;\n /** SHA-256 hash of the canonical chain for integrity verification. */\n readonly chain_hash: string;\n}\n\n/** Input required to build a liability attribution record. */\nexport interface LiabilityAttributionInput {\n readonly execution_id: string;\n readonly org_id: string;\n readonly classification: LiabilityClassification;\n readonly risk_tier: FinancialRiskTier;\n readonly authorizer: Omit<LiabilityParty, \"role\" | \"liability_weight\">;\n readonly executor: Omit<LiabilityParty, \"role\" | \"liability_weight\">;\n readonly approvers: readonly Omit<LiabilityParty, \"role\" | \"liability_weight\">[];\n readonly delegations?: readonly {\n readonly delegator_id: string;\n readonly delegate_id: string;\n readonly delegator_label: string;\n readonly delegate_label: string;\n readonly delegator_type: \"human\" | \"agent\" | \"system\";\n readonly delegate_type: \"human\" | \"agent\" | \"system\";\n readonly permit_id: string | null;\n readonly acted_at: string;\n }[];\n readonly supervisors?: readonly Omit<LiabilityParty, \"role\" | \"liability_weight\">[];\n readonly override?: {\n readonly actor_id: string;\n readonly actor_label: string;\n readonly actor_type: \"human\" | \"agent\" | \"system\";\n readonly justification: string;\n readonly permit_id: string | null;\n readonly acted_at: string;\n };\n}\n\n/** Weight distribution strategy. */\nexport type WeightDistribution = \"equal\" | \"role_weighted\";\n\n/** Role weights for role_weighted distribution. */\nconst ROLE_WEIGHTS: Record<LiabilityPartyRole, number> = {\n authorizer: 0.30,\n delegator: 0.15,\n delegate: 0.15,\n executor: 0.25,\n approver: 0.05,\n override_actor: 0.40,\n supervisor: 0.10,\n exception_approver: 0.05,\n};\n\n/**\n * Compute liability weights for all parties in a chain.\n * Normalizes weights to sum to 1.0.\n */\nexport function computeLiabilityWeights(\n parties: readonly { role: LiabilityPartyRole }[],\n distribution: WeightDistribution = \"role_weighted\",\n): number[] {\n if (parties.length === 0) return [];\n\n let raw: number[];\n if (distribution === \"equal\") {\n raw = parties.map(() => 1);\n } else {\n raw = parties.map((p) => ROLE_WEIGHTS[p.role] ?? 0.05);\n }\n\n const total = raw.reduce((s, w) => s + w, 0);\n if (total <= 0) return parties.map(() => 1 / parties.length);\n return raw.map((w) => w / total);\n}\n\n/**\n * Build a liability chain from attribution input.\n * Assigns roles and computes normalized weights for each party.\n */\nexport function buildLiabilityChain(\n input: LiabilityAttributionInput,\n distribution: WeightDistribution = \"role_weighted\",\n): LiabilityParty[] {\n type Raw = Omit<LiabilityParty, \"liability_weight\">;\n const raw: Raw[] = [];\n\n raw.push({ ...input.authorizer, role: \"authorizer\" });\n\n for (const d of input.delegations ?? []) {\n raw.push({\n party_id: d.delegator_id,\n party_label: d.delegator_label,\n party_type: d.delegator_type,\n role: \"delegator\",\n acted_at: d.acted_at,\n permit_id: d.permit_id,\n });\n raw.push({\n party_id: d.delegate_id,\n party_label: d.delegate_label,\n party_type: d.delegate_type,\n role: \"delegate\",\n acted_at: d.acted_at,\n permit_id: d.permit_id,\n });\n }\n\n for (const a of input.approvers) {\n raw.push({ ...a, role: \"approver\" });\n }\n\n for (const s of input.supervisors ?? []) {\n raw.push({ ...s, role: \"supervisor\" });\n }\n\n raw.push({ ...input.executor, role: \"executor\" });\n\n if (input.override) {\n raw.push({\n party_id: input.override.actor_id,\n party_label: input.override.actor_label,\n party_type: input.override.actor_type,\n role: \"override_actor\",\n acted_at: input.override.acted_at,\n permit_id: input.override.permit_id,\n });\n }\n\n const weights = computeLiabilityWeights(raw, distribution);\n return raw.map((p, i) => ({ ...p, liability_weight: weights[i] ?? 0 }));\n}\n\n/**\n * Find all parties bearing primary liability (weight >= threshold).\n * Used in dispute workflows and regulatory reporting.\n */\nexport function findPrimaryLiabilityParties(\n chain: readonly LiabilityParty[],\n threshold = 0.20,\n): LiabilityParty[] {\n return chain.filter((p) => p.liability_weight >= threshold);\n}\n\n/** Result of validating a liability chain. */\nexport interface LiabilityChainValidation {\n readonly valid: boolean;\n readonly errors: readonly string[];\n}\n\n/**\n * Validate structural correctness of a liability chain:\n * - At least one party present\n * - Weights sum to ~1.0\n * - No duplicate party_id+role pairs\n * - override_actor present when hasEmergencyOverride is true\n */\nexport function validateLiabilityChain(\n chain: readonly LiabilityParty[],\n hasEmergencyOverride: boolean,\n): LiabilityChainValidation {\n const errors: string[] = [];\n\n if (chain.length === 0) {\n errors.push(\"liability chain must have at least one party\");\n }\n\n const weightSum = chain.reduce((s, p) => s + p.liability_weight, 0);\n if (Math.abs(weightSum - 1.0) > 0.01) {\n errors.push(`liability weights sum to ${weightSum.toFixed(4)}, expected 1.0`);\n }\n\n const seen = new Set<string>();\n for (const p of chain) {\n const key = `${p.party_id}:${p.role}`;\n if (seen.has(key)) errors.push(`duplicate party+role: ${key}`);\n seen.add(key);\n }\n\n if (hasEmergencyOverride && !chain.some((p) => p.role === \"override_actor\")) {\n errors.push(\"emergency_override is true but no override_actor in chain\");\n }\n\n return { valid: errors.length === 0, errors };\n}\n","/**\n * Economic Risk Engine.\n *\n * Computes financial exposure, approval concentration risk, override\n * frequency risk, budgetary drift, and execution anomaly risk for an\n * organization's financial governance posture.\n *\n * All computation is pure (no I/O). Inputs are derived from the\n * financial_execution_records and liability_attribution_records tables.\n *\n * Wire-stable as `economic_risk.v1`.\n */\n\nimport type { FinancialExecutionRecord, FinancialRiskTier } from \"./financialAction.js\";\n\n/** Aggregate financial risk score for an organization or scope. */\nexport interface FinancialRiskScore {\n readonly scope_id: string;\n /** Overall risk score (0–100; higher = riskier). */\n readonly overall_score: number;\n readonly exposure_score: number;\n readonly concentration_score: number;\n readonly override_score: number;\n readonly drift_score: number;\n readonly anomaly_score: number;\n readonly implied_tier: FinancialRiskTier;\n readonly computed_at: string;\n readonly factors: readonly RiskFactor[];\n}\n\n/** A single contributing risk factor. */\nexport interface RiskFactor {\n readonly name: string;\n readonly score: number;\n readonly weight: number;\n readonly description: string;\n readonly evidence?: readonly string[];\n}\n\n/** Alert raised when approval authority is too concentrated. */\nexport interface ConcentrationAlert {\n readonly approver_id: string;\n /** Percentage of total approvals (0–100). */\n readonly approval_share_pct: number;\n readonly total_value_approved: number;\n readonly approval_count: number;\n readonly severity: \"warn\" | \"critical\";\n readonly window_start: string;\n readonly window_end: string;\n}\n\n/** Per-approver breakdown within a concentration analysis. */\nexport interface ApproverBreakdown {\n readonly approver_id: string;\n readonly approval_count: number;\n readonly total_value: number;\n /** Share as a percentage (0–100). */\n readonly share_pct: number;\n}\n\n/** Result of approval concentration analysis. */\nexport interface ApprovalConcentrationAnalysis {\n readonly scope_id: string;\n readonly analysis_window_days: number;\n readonly total_approvals: number;\n readonly total_value: number;\n readonly approver_breakdown: readonly ApproverBreakdown[];\n readonly alerts: readonly ConcentrationAlert[];\n /** Herfindahl-Hirschman Index (0–10000). */\n readonly concentration_hhi: number;\n readonly computed_at: string;\n}\n\n/** Budgetary drift analysis for a scope/period. */\nexport interface BudgetaryDriftAnalysis {\n readonly scope_id: string;\n readonly department_id: string | null;\n readonly period_start: string;\n readonly period_end: string;\n readonly budgeted_amount: number;\n readonly actual_amount: number;\n readonly variance_amount: number;\n readonly variance_pct: number;\n readonly drift_detected: boolean;\n readonly drift_severity: \"none\" | \"minor\" | \"moderate\" | \"severe\";\n readonly override_contribution_pct: number;\n readonly unauthorized_escalation_detected: boolean;\n}\n\n/** A single execution anomaly signal. */\nexport interface ExecutionAnomaly {\n readonly anomaly_id: string;\n readonly execution_id: string;\n readonly anomaly_type: AnomalyType;\n readonly description: string;\n readonly severity: \"low\" | \"medium\" | \"high\";\n readonly detected_at: string;\n readonly evidence: Record<string, unknown>;\n}\n\n/** Known anomaly types detected by the risk engine. */\nexport type AnomalyType =\n | \"unusual_amount\" // Value significantly outside historical baseline\n | \"unusual_frequency\" // Too many executions in a short period\n | \"off_hours_execution\" // Outside normal business hours\n | \"rapid_sequential\" // Rapid sequential approvals (rubber-stamping signal)\n | \"self_approval\" // Initiator and approver are the same party\n | \"jurisdiction_mismatch\" // Currency/amount inconsistent with counterparty locale\n | \"dormant_approver\" // Approver who hasn't approved in a long time\n | \"velocity_spike\" // Sudden spike in total daily value\n | string;\n\n/** Sub-score weights for overall risk computation. */\nconst SCORE_WEIGHTS = {\n exposure: 0.25,\n concentration: 0.25,\n override: 0.20,\n drift: 0.15,\n anomaly: 0.15,\n} as const;\n\n/**\n * Compute the overall financial risk score from sub-scores.\n * Returns a value in [0, 100].\n */\nexport function computeOverallRiskScore(subScores: {\n exposure: number;\n concentration: number;\n override: number;\n drift: number;\n anomaly: number;\n}): number {\n return Math.min(\n 100,\n Math.max(\n 0,\n subScores.exposure * SCORE_WEIGHTS.exposure +\n subScores.concentration * SCORE_WEIGHTS.concentration +\n subScores.override * SCORE_WEIGHTS.override +\n subScores.drift * SCORE_WEIGHTS.drift +\n subScores.anomaly * SCORE_WEIGHTS.anomaly,\n ),\n );\n}\n\n/**\n * Infer a risk tier from an overall score.\n * 0–25: low | 26–55: medium | 56–80: high | 81–100: critical\n */\nexport function scoreToRiskTier(score: number): FinancialRiskTier {\n if (score <= 25) return \"low\";\n if (score <= 55) return \"medium\";\n if (score <= 80) return \"high\";\n return \"critical\";\n}\n\n/**\n * Compute the Herfindahl-Hirschman Index from a list of shares (0–100 each).\n * HHI > 2500 indicates high concentration.\n */\nexport function computeHHI(shares: readonly number[]): number {\n return shares.reduce((acc, s) => acc + s * s, 0);\n}\n\n/** Map HHI (0–10000) to a concentration score (0–100). */\nexport function hhiToConcentrationScore(hhi: number): number {\n return Math.min(100, (hhi / 10_000) * 100);\n}\n\n/**\n * Compute an exposure score (0–100) from execution records.\n * Total active-state value as a fraction of a reference ceiling.\n */\nexport function computeExposureScore(\n records: readonly Pick<FinancialExecutionRecord, \"action_value\" | \"status\" | \"risk_tier\">[],\n exposureCeilingUSD = 10_000_000,\n): number {\n const activeStatuses = new Set<FinancialExecutionRecord[\"status\"]>(\n [\"pending_approval\", \"approved\", \"executing\"],\n );\n const totalExposure = records\n .filter((r) => activeStatuses.has(r.status))\n .reduce((acc, r) => acc + r.action_value, 0);\n return Math.min(100, (totalExposure / exposureCeilingUSD) * 100);\n}\n\n/**\n * Compute an override frequency score (0–100).\n * More than 10% override rate → score = 100.\n */\nexport function computeOverrideScore(\n totalExecutions: number,\n overriddenExecutions: number,\n): number {\n if (totalExecutions === 0) return 0;\n const rate = overriddenExecutions / totalExecutions;\n return Math.min(100, rate * 1000); // 10% rate maps to 100\n}\n\n/**\n * Detect self-approval: initiator and approver are the same party.\n */\nexport function detectSelfApproval(\n initiatorId: string,\n approverIds: readonly string[],\n): boolean {\n return approverIds.includes(initiatorId);\n}\n\n/** Compute an approval risk score from concentration analysis. */\nexport function computeApprovalRiskScore(analysis: ApprovalConcentrationAnalysis): number {\n return hhiToConcentrationScore(analysis.concentration_hhi);\n}\n","/**\n * Financial Quorum — extends the AtlaSent approval quorum model with\n * monetary thresholds, dynamic escalation, and emergency freeze support.\n *\n * Builds on the base QuorumPolicy in approvalQuorum.ts. Every financial\n * quorum check MUST first satisfy base quorum requirements before\n * financial-layer policy is evaluated.\n *\n * Wire-stable as `financial_quorum.v1`.\n */\n\nimport type { QuorumPolicy, QuorumProof } from \"./approvalQuorum.js\";\nimport type { CurrencyCode, FinancialRiskTier } from \"./financialAction.js\";\n\n/** A financial role requirement with optional monetary and tier filters. */\nexport interface FinancialRoleRequirement {\n readonly role: string;\n readonly min: number;\n /** Only apply this requirement when action value >= this amount. */\n readonly applies_above?: number;\n /** Only apply when the action's risk_tier is in this set. */\n readonly applies_to_tiers?: readonly FinancialRiskTier[];\n}\n\n/** Amount-based threshold that triggers additional quorum requirements. */\nexport interface AmountThreshold {\n readonly value: number;\n readonly currency: CurrencyCode;\n readonly additional_approvals: number;\n readonly additional_roles: readonly FinancialRoleRequirement[];\n readonly senior_review_required: boolean;\n}\n\n/**\n * Financial quorum policy.\n *\n * Extends the base QuorumPolicy with amount thresholds, financial role\n * requirements, regulator approval thresholds, and emergency freeze.\n */\nexport interface FinancialQuorumPolicy extends QuorumPolicy {\n readonly financial_role_requirements: readonly FinancialRoleRequirement[];\n readonly amount_thresholds: readonly AmountThreshold[];\n readonly reference_currency: CurrencyCode;\n readonly emergency_freeze_active: boolean;\n /** Regulator approval required above this value (null = not required). */\n readonly regulator_approval_threshold: number | null;\n /** Customer + vendor dual-release required above this value. */\n readonly dual_release_threshold: number | null;\n}\n\n/** Emergency freeze record — applied org-wide or per scope. */\nexport interface EmergencyFreeze {\n readonly freeze_id: string;\n readonly scope_id: string;\n readonly scope_type: \"org\" | \"department\" | \"action_class\";\n readonly triggered_by: string;\n readonly reason: string;\n readonly triggered_at: string;\n readonly expires_at: string | null;\n readonly lifted: boolean;\n readonly lifted_at: string | null;\n readonly lifted_by: string | null;\n}\n\n/** Result of evaluating a financial quorum. */\nexport interface FinancialQuorumResult {\n readonly passed: boolean;\n readonly base_quorum_passed: boolean;\n readonly amount_threshold_satisfied: boolean;\n readonly financial_roles_satisfied: boolean;\n readonly regulator_approval_missing: boolean;\n readonly blocked_by_freeze: boolean;\n readonly base_quorum_proof: QuorumProof | null;\n readonly denial_reason: string | null;\n readonly unmet_requirements: readonly string[];\n}\n\n/** Input to financial quorum evaluation. */\nexport interface FinancialQuorumInput {\n readonly policy: FinancialQuorumPolicy;\n readonly action_value: number;\n readonly risk_tier: FinancialRiskTier;\n /** Roles present in the approval set (role → count). */\n readonly present_roles: Record<string, number>;\n readonly approval_count: number;\n readonly regulator_approval_present: boolean;\n readonly base_quorum_proof: QuorumProof | null;\n readonly active_freezes: readonly EmergencyFreeze[];\n}\n\n/**\n * Evaluate a financial quorum policy.\n *\n * Checks in order: emergency freeze → base count → amount thresholds\n * → financial roles → regulator approval.\n */\nexport function evaluateFinancialQuorum(input: FinancialQuorumInput): FinancialQuorumResult {\n const unmet: string[] = [];\n\n // Hard block: emergency freeze\n const activeFreeze = input.active_freezes.find((f) => !f.lifted);\n if (activeFreeze) {\n return {\n passed: false,\n base_quorum_passed: false,\n amount_threshold_satisfied: false,\n financial_roles_satisfied: false,\n regulator_approval_missing: false,\n blocked_by_freeze: true,\n base_quorum_proof: null,\n denial_reason: `action blocked by emergency freeze (${activeFreeze.freeze_id}): ${activeFreeze.reason}`,\n unmet_requirements: [`emergency_freeze:${activeFreeze.freeze_id}`],\n };\n }\n\n // Base quorum\n const baseQuorumPassed =\n input.base_quorum_proof !== null ||\n input.approval_count >= input.policy.required_count;\n if (!baseQuorumPassed) {\n unmet.push(\n `base quorum requires ${input.policy.required_count} approvals, have ${input.approval_count}`,\n );\n }\n\n // Amount threshold escalation\n let amountThresholdSatisfied = true;\n for (const threshold of input.policy.amount_thresholds) {\n if (input.action_value >= threshold.value) {\n const needed = input.policy.required_count + threshold.additional_approvals;\n if (input.approval_count < needed) {\n amountThresholdSatisfied = false;\n unmet.push(\n `amount threshold ${threshold.value} ${threshold.currency} requires ${needed} approvals`,\n );\n }\n for (const req of threshold.additional_roles) {\n const present = input.present_roles[req.role] ?? 0;\n if (present < req.min) {\n amountThresholdSatisfied = false;\n unmet.push(`amount threshold requires ${req.min} ${req.role} approver(s), have ${present}`);\n }\n }\n if (threshold.senior_review_required && !(input.present_roles[\"senior_finance\"] ?? 0)) {\n amountThresholdSatisfied = false;\n unmet.push(\"amount threshold requires senior_finance review\");\n }\n }\n }\n\n // Financial role requirements\n let financialRolesSatisfied = true;\n for (const req of input.policy.financial_role_requirements) {\n if (req.applies_to_tiers && !req.applies_to_tiers.includes(input.risk_tier)) continue;\n if (req.applies_above !== undefined && input.action_value < req.applies_above) continue;\n const present = input.present_roles[req.role] ?? 0;\n if (present < req.min) {\n financialRolesSatisfied = false;\n unmet.push(`financial role ${req.role} requires ${req.min} approver(s), have ${present}`);\n }\n }\n\n // Regulator approval\n const regulatorMissing =\n input.policy.regulator_approval_threshold !== null &&\n input.action_value >= input.policy.regulator_approval_threshold &&\n !input.regulator_approval_present;\n if (regulatorMissing) {\n unmet.push(\"regulator approval required for this action value\");\n }\n\n const passed =\n baseQuorumPassed &&\n amountThresholdSatisfied &&\n financialRolesSatisfied &&\n !regulatorMissing;\n\n return {\n passed,\n base_quorum_passed: baseQuorumPassed,\n amount_threshold_satisfied: amountThresholdSatisfied,\n financial_roles_satisfied: financialRolesSatisfied,\n regulator_approval_missing: regulatorMissing,\n blocked_by_freeze: false,\n base_quorum_proof: input.base_quorum_proof,\n denial_reason: passed ? null : (unmet[0] ?? \"financial quorum not satisfied\"),\n unmet_requirements: unmet,\n };\n}\n\n/**\n * Determine the escalated minimum approval count for a given action value.\n * Returns base count plus the largest additional_approvals from matching thresholds.\n */\nexport function computeEscalatedApprovalCount(\n baseCount: number,\n actionValue: number,\n thresholds: readonly AmountThreshold[],\n): number {\n let additional = 0;\n for (const t of thresholds) {\n if (actionValue >= t.value) {\n additional = Math.max(additional, t.additional_approvals);\n }\n }\n return baseCount + additional;\n}\n","/**\n * Budgetary Governance — policy and constraint infrastructure for\n * organizational financial limits.\n *\n * Prevents budget overruns, unauthorized escalations, and hidden approvals\n * by enforcing declared spending constraints before financial actions\n * are authorized.\n *\n * Wire-stable as `budget_governance.v1`.\n */\n\nimport type { CurrencyCode, FinancialActionType, FinancialRiskTier } from \"./financialAction.js\";\n\n/** Scope a budget limit applies to. */\nexport type BudgetScope =\n | \"org\" // Entire organization\n | \"department\" // Named department\n | \"team\" // Named team within a department\n | \"environment\" // Deployment environment (prod, staging, etc.)\n | \"action_class\" // Specific financial action class\n | \"project\" // Project or cost center code\n | \"time_bounded\"; // Time-bounded budget (sprint, quarter, etc.)\n\n/** A declared budget limit for a scope. */\nexport interface BudgetLimit {\n readonly limit_id: string;\n readonly org_id: string;\n readonly scope_type: BudgetScope;\n readonly scope_id: string;\n readonly limit_amount: number;\n readonly currency: CurrencyCode;\n /** Hard limits block execution; soft limits warn only. */\n readonly enforcement: \"hard\" | \"soft\";\n readonly period_start: string | null;\n readonly period_end: string | null;\n readonly active: boolean;\n readonly created_by: string;\n readonly created_at: string;\n}\n\n/** Current spending state against a budget limit. */\nexport interface BudgetSpendingState {\n readonly limit_id: string;\n readonly spent_amount: number;\n readonly remaining_amount: number;\n readonly exceeded: boolean;\n /** Utilization percentage (0–100+). */\n readonly utilization_pct: number;\n readonly updated_at: string;\n}\n\n/** A spending constraint on a financial action class or type. */\nexport interface SpendingConstraint {\n readonly constraint_id: string;\n readonly org_id: string;\n /** \"*\" matches all action types. */\n readonly action_type: FinancialActionType | \"*\";\n readonly max_single_transaction: number;\n readonly max_daily_aggregate: number | null;\n readonly max_monthly_aggregate: number | null;\n readonly currency: CurrencyCode;\n readonly applies_to_tier_gte: FinancialRiskTier | null;\n readonly allow_anonymous_agents: boolean;\n readonly active: boolean;\n}\n\n/** A specific budget violation. */\nexport interface BudgetViolation {\n readonly violation_type:\n | \"limit_exceeded\"\n | \"single_transaction_exceeds\"\n | \"daily_aggregate_exceeds\"\n | \"monthly_aggregate_exceeds\"\n | \"anonymous_agent_blocked\"\n | \"period_expired\";\n readonly limit_id?: string;\n readonly constraint_id?: string;\n readonly description: string;\n readonly overage_amount?: number;\n}\n\n/** Result of checking an action against budget constraints. */\nexport interface BudgetConstraintCheckResult {\n readonly permitted: boolean;\n readonly hard_blocks: readonly BudgetViolation[];\n readonly soft_warnings: readonly BudgetViolation[];\n readonly limits_checked: readonly string[];\n readonly constraints_checked: readonly string[];\n}\n\n/** A complete budget policy document for an organization. */\nexport interface BudgetPolicy {\n readonly policy_id: string;\n readonly org_id: string;\n readonly name: string;\n readonly limits: readonly BudgetLimit[];\n readonly constraints: readonly SpendingConstraint[];\n readonly override_requires_exception: boolean;\n readonly allow_approved_escalation: boolean;\n readonly version: string;\n readonly effective_from: string;\n readonly expires_at: string | null;\n}\n\n/**\n * Check an action value against applicable budget limits and constraints.\n *\n * Hard limits block execution; soft limits surface as warnings.\n */\nexport function checkBudgetConstraints(params: {\n actionValue: number;\n currency: CurrencyCode;\n actionType: FinancialActionType;\n riskTier: FinancialRiskTier;\n isAnonymousAgent: boolean;\n currentDailySpend: number;\n currentMonthlySpend: number;\n applicableLimits: readonly (BudgetLimit & { spending: BudgetSpendingState })[];\n applicableConstraints: readonly SpendingConstraint[];\n now?: Date;\n}): BudgetConstraintCheckResult {\n const hardBlocks: BudgetViolation[] = [];\n const softWarnings: BudgetViolation[] = [];\n const limitsChecked: string[] = [];\n const constraintsChecked: string[] = [];\n const nowIso = (params.now ?? new Date()).toISOString();\n\n for (const limit of params.applicableLimits) {\n limitsChecked.push(limit.limit_id);\n\n if (limit.period_end && nowIso > limit.period_end) {\n const v: BudgetViolation = {\n violation_type: \"period_expired\",\n limit_id: limit.limit_id,\n description: `Budget limit ${limit.limit_id} period expired at ${limit.period_end}`,\n };\n if (limit.enforcement === \"hard\") hardBlocks.push(v); else softWarnings.push(v);\n continue;\n }\n\n const projected = limit.spending.spent_amount + params.actionValue;\n if (projected > limit.limit_amount) {\n const v: BudgetViolation = {\n violation_type: \"limit_exceeded\",\n limit_id: limit.limit_id,\n description: `Action would exceed ${limit.scope_type} limit (${limit.limit_amount} ${limit.currency})`,\n overage_amount: projected - limit.limit_amount,\n };\n if (limit.enforcement === \"hard\") hardBlocks.push(v); else softWarnings.push(v);\n }\n }\n\n for (const constraint of params.applicableConstraints) {\n constraintsChecked.push(constraint.constraint_id);\n\n if (constraint.action_type !== \"*\" && constraint.action_type !== params.actionType) continue;\n\n if (!constraint.allow_anonymous_agents && params.isAnonymousAgent) {\n hardBlocks.push({\n violation_type: \"anonymous_agent_blocked\",\n constraint_id: constraint.constraint_id,\n description: `Anonymous agents are not permitted to execute ${params.actionType}`,\n });\n }\n\n if (params.actionValue > constraint.max_single_transaction) {\n hardBlocks.push({\n violation_type: \"single_transaction_exceeds\",\n constraint_id: constraint.constraint_id,\n description: `Value ${params.actionValue} exceeds single-transaction limit ${constraint.max_single_transaction} ${constraint.currency}`,\n overage_amount: params.actionValue - constraint.max_single_transaction,\n });\n }\n\n if (\n constraint.max_daily_aggregate !== null &&\n params.currentDailySpend + params.actionValue > constraint.max_daily_aggregate\n ) {\n hardBlocks.push({\n violation_type: \"daily_aggregate_exceeds\",\n constraint_id: constraint.constraint_id,\n description: `Action would exceed daily aggregate limit ${constraint.max_daily_aggregate} ${constraint.currency}`,\n overage_amount: params.currentDailySpend + params.actionValue - constraint.max_daily_aggregate,\n });\n }\n\n if (\n constraint.max_monthly_aggregate !== null &&\n params.currentMonthlySpend + params.actionValue > constraint.max_monthly_aggregate\n ) {\n hardBlocks.push({\n violation_type: \"monthly_aggregate_exceeds\",\n constraint_id: constraint.constraint_id,\n description: `Action would exceed monthly aggregate limit ${constraint.max_monthly_aggregate} ${constraint.currency}`,\n overage_amount: params.currentMonthlySpend + params.actionValue - constraint.max_monthly_aggregate,\n });\n }\n }\n\n return {\n permitted: hardBlocks.length === 0,\n hard_blocks: hardBlocks,\n soft_warnings: softWarnings,\n limits_checked: limitsChecked,\n constraints_checked: constraintsChecked,\n };\n}\n\n/**\n * Determine budget utilization severity for dashboard display.\n */\nexport function budgetUtilizationSeverity(\n utilizationPct: number,\n): \"normal\" | \"warn\" | \"critical\" {\n if (utilizationPct >= 100) return \"critical\";\n if (utilizationPct >= 80) return \"warn\";\n return \"normal\";\n}\n","/**\n * Autonomous Financial Execution — governance for AI-driven financial actions.\n *\n * Defines bounded authority, execution ceilings, and runtime verification\n * requirements for autonomous agents performing financial operations:\n * refunds, procurement, cloud-cost optimization, vendor payments, etc.\n *\n * Wire-stable as `autonomous_financial.v1`.\n */\n\nimport type { CurrencyCode, FinancialActionType, FinancialRiskTier } from \"./financialAction.js\";\n\n/** Authority bounds for an autonomous financial agent. */\nexport interface AutonomousExecutionBounds {\n readonly bounds_id: string;\n readonly org_id: string;\n readonly agent_id: string;\n readonly agent_name: string;\n /** Action types this agent is permitted to execute autonomously. */\n readonly permitted_action_types: readonly FinancialActionType[];\n readonly ceilings: readonly ExecutionCeiling[];\n readonly daily_aggregate_ceiling: number;\n readonly aggregate_currency: CurrencyCode;\n /** Maximum risk tier the agent may autonomously execute. */\n readonly max_risk_tier: FinancialRiskTier;\n readonly require_runtime_verification: boolean;\n readonly anomaly_detection_enabled: boolean;\n readonly created_at: string;\n readonly expires_at: string | null;\n readonly active: boolean;\n}\n\n/** Per-action-type execution ceiling. */\nexport interface ExecutionCeiling {\n readonly action_type: FinancialActionType;\n readonly per_execution_max: number;\n readonly currency: CurrencyCode;\n readonly max_daily_count: number | null;\n readonly require_permit: boolean;\n}\n\n/** Record of an autonomous execution attempt. */\nexport interface AutonomousExecutionRecord {\n readonly record_id: string;\n readonly agent_id: string;\n readonly org_id: string;\n readonly action_type: FinancialActionType;\n readonly action_value: number;\n readonly currency: CurrencyCode;\n readonly permitted: boolean;\n readonly denial_reason: string | null;\n readonly permit_id: string | null;\n readonly anomaly_detected: boolean;\n readonly anomaly_description: string | null;\n readonly attempted_at: string;\n readonly executed_at: string | null;\n}\n\n/** Result of checking whether an autonomous execution is within bounds. */\nexport interface AutonomousExecutionCheckResult {\n readonly permitted: boolean;\n readonly action_type_permitted: boolean;\n readonly within_execution_ceiling: boolean;\n readonly within_daily_aggregate: boolean;\n readonly within_risk_tier: boolean;\n readonly bounds_active: boolean;\n readonly bounds_not_expired: boolean;\n readonly applicable_ceiling: ExecutionCeiling | null;\n readonly denial_reason: string | null;\n readonly violations: readonly string[];\n}\n\nconst RISK_TIER_ORDER: Record<FinancialRiskTier, number> = {\n low: 1,\n medium: 2,\n high: 3,\n critical: 4,\n};\n\n/**\n * Check whether an autonomous execution is within declared bounds.\n */\nexport function checkAutonomousBounds(params: {\n bounds: AutonomousExecutionBounds;\n actionType: FinancialActionType;\n actionValue: number;\n currency: CurrencyCode;\n riskTier: FinancialRiskTier;\n currentDailyAggregate: number;\n currentDailyCount: Partial<Record<string, number>>;\n now?: Date;\n}): AutonomousExecutionCheckResult {\n const violations: string[] = [];\n const nowIso = (params.now ?? new Date()).toISOString();\n\n const boundsActive = params.bounds.active;\n if (!boundsActive) violations.push(\"agent execution bounds are inactive\");\n\n const boundsNotExpired =\n params.bounds.expires_at === null || params.bounds.expires_at > nowIso;\n if (!boundsNotExpired) {\n violations.push(`agent bounds expired at ${params.bounds.expires_at}`);\n }\n\n const actionTypePermitted = (params.bounds.permitted_action_types as string[]).includes(\n params.actionType,\n );\n if (!actionTypePermitted) {\n violations.push(`action type ${params.actionType} not in agent's permitted set`);\n }\n\n const applicableCeiling =\n params.bounds.ceilings.find((c) => c.action_type === params.actionType) ?? null;\n\n let withinExecutionCeiling = true;\n if (applicableCeiling !== null) {\n if (params.actionValue > applicableCeiling.per_execution_max) {\n withinExecutionCeiling = false;\n violations.push(\n `value ${params.actionValue} exceeds per-execution ceiling ${applicableCeiling.per_execution_max} ${applicableCeiling.currency}`,\n );\n }\n if (applicableCeiling.max_daily_count !== null) {\n const todayCount = params.currentDailyCount[params.actionType] ?? 0;\n if (todayCount >= applicableCeiling.max_daily_count) {\n withinExecutionCeiling = false;\n violations.push(\n `daily count ${todayCount} at or exceeds limit ${applicableCeiling.max_daily_count} for ${params.actionType}`,\n );\n }\n }\n }\n\n const withinDailyAggregate =\n params.currentDailyAggregate + params.actionValue <= params.bounds.daily_aggregate_ceiling;\n if (!withinDailyAggregate) {\n violations.push(\n `daily aggregate ${params.currentDailyAggregate + params.actionValue} would exceed ceiling ${params.bounds.daily_aggregate_ceiling} ${params.bounds.aggregate_currency}`,\n );\n }\n\n const withinRiskTier =\n RISK_TIER_ORDER[params.riskTier] <= RISK_TIER_ORDER[params.bounds.max_risk_tier];\n if (!withinRiskTier) {\n violations.push(\n `action risk tier ${params.riskTier} exceeds agent max ${params.bounds.max_risk_tier}`,\n );\n }\n\n const permitted =\n boundsActive &&\n boundsNotExpired &&\n actionTypePermitted &&\n withinExecutionCeiling &&\n withinDailyAggregate &&\n withinRiskTier;\n\n return {\n permitted,\n action_type_permitted: actionTypePermitted,\n within_execution_ceiling: withinExecutionCeiling,\n within_daily_aggregate: withinDailyAggregate,\n within_risk_tier: withinRiskTier,\n bounds_active: boundsActive,\n bounds_not_expired: boundsNotExpired,\n applicable_ceiling: applicableCeiling,\n denial_reason: permitted ? null : (violations[0] ?? \"execution out of bounds\"),\n violations,\n };\n}\n\n/**\n * Detect a potential anomaly in autonomous execution.\n * Returns a description when an anomaly is detected, or null.\n */\nexport function detectAutonomousAnomaly(params: {\n actionValue: number;\n historicalMeanValue: number;\n historicalStdDev: number;\n recentExecutionCount: number;\n burstThreshold: number;\n isOffHours: boolean;\n}): { anomalyDetected: boolean; description: string | null } {\n const zScore =\n params.historicalStdDev > 0\n ? Math.abs(params.actionValue - params.historicalMeanValue) / params.historicalStdDev\n : 0;\n\n if (zScore > 3) {\n return {\n anomalyDetected: true,\n description: `action value ${params.actionValue} is ${zScore.toFixed(1)}σ from mean (${params.historicalMeanValue})`,\n };\n }\n\n if (params.recentExecutionCount > params.burstThreshold) {\n return {\n anomalyDetected: true,\n description: `execution burst: ${params.recentExecutionCount} in window (threshold: ${params.burstThreshold})`,\n };\n }\n\n if (params.isOffHours && params.actionValue > params.historicalMeanValue * 2) {\n return {\n anomalyDetected: true,\n description: `off-hours execution with above-average value ${params.actionValue}`,\n };\n }\n\n return { anomalyDetected: false, description: null };\n}\n","/**\n * Incentive Alignment Engine.\n *\n * Detects governance anti-patterns that indicate misaligned incentives:\n * excessive overrides, rushed approvals, emergency bypass repetition,\n * authority concentration, and governance fatigue.\n *\n * These signals are leading indicators of systemic governance failure.\n * They do not block execution but feed into risk scoring and dashboards.\n *\n * Wire-stable as `incentive_alignment.v1`.\n */\n\n/** Categories of governance incentive signals. */\nexport type IncentiveSignalType =\n | \"excessive_overrides\"\n | \"rushed_approval\"\n | \"emergency_bypass_repeat\"\n | \"authority_concentration\"\n | \"rubber_stamping\"\n | \"approval_collusion\"\n | \"escalation_avoidance\"\n | \"governance_fatigue\"\n | \"delegation_chain_depth\"\n | \"approval_velocity_spike\";\n\n/** A detected incentive alignment signal. */\nexport interface IncentiveSignal {\n readonly signal_id: string;\n readonly signal_type: IncentiveSignalType;\n readonly party_id: string;\n readonly party_label: string;\n /** Severity (0–100). */\n readonly severity: number;\n readonly description: string;\n readonly evidence: readonly string[];\n readonly detected_at: string;\n readonly reviewed: boolean;\n readonly reviewed_by: string | null;\n}\n\n/** Behavior pattern analysis for a governance actor. */\nexport interface GovernanceBehaviorPattern {\n readonly party_id: string;\n readonly party_label: string;\n readonly observation_window_days: number;\n readonly total_approvals: number;\n readonly total_overrides: number;\n readonly total_emergency_bypasses: number;\n readonly mean_approval_latency_seconds: number;\n readonly min_approval_latency_seconds: number;\n readonly approval_concentration_score: number;\n readonly delegation_depth_max: number;\n readonly signals: readonly IncentiveSignal[];\n /** 0–100; higher = healthier governance posture. */\n readonly governance_health_score: number;\n}\n\n/** Misalignment alert for operator review. */\nexport interface MisalignmentAlert {\n readonly alert_id: string;\n readonly org_id: string;\n readonly severity: \"warn\" | \"critical\";\n readonly alert_type: IncentiveSignalType;\n readonly affected_party_ids: readonly string[];\n readonly description: string;\n readonly recommendation: string;\n readonly signals: readonly IncentiveSignal[];\n readonly created_at: string;\n readonly resolved: boolean;\n readonly resolved_at: string | null;\n}\n\n/** Thresholds for incentive alignment detection. */\nexport interface IncentiveAlignmentConfig {\n readonly max_override_rate: number;\n readonly min_approval_latency_seconds: number;\n readonly max_emergency_bypasses_30d: number;\n readonly max_concentration_share: number;\n readonly max_delegation_depth: number;\n}\n\nexport const DEFAULT_INCENTIVE_CONFIG: IncentiveAlignmentConfig = {\n max_override_rate: 0.05,\n min_approval_latency_seconds: 30,\n max_emergency_bypasses_30d: 3,\n max_concentration_share: 0.40,\n max_delegation_depth: 3,\n};\n\n/**\n * Analyze a governance actor's behavior to detect misaligned incentives.\n * Returns signals sorted by severity (highest first).\n */\nexport function detectMisalignedIncentives(params: {\n partyId: string;\n partyLabel: string;\n windowDays: number;\n totalActions: number;\n overrideCount: number;\n emergencyBypassCount: number;\n approvalLatencies: readonly number[];\n approvalShare: number;\n delegationDepthMax: number;\n config?: IncentiveAlignmentConfig;\n now?: Date;\n}): IncentiveSignal[] {\n const config = params.config ?? DEFAULT_INCENTIVE_CONFIG;\n const signals: IncentiveSignal[] = [];\n const now = (params.now ?? new Date()).toISOString();\n let signalIdx = 0;\n const makeId = () => `signal_${params.partyId}_${signalIdx++}`;\n\n // Excessive overrides\n const overrideRate = params.totalActions > 0 ? params.overrideCount / params.totalActions : 0;\n if (overrideRate > config.max_override_rate) {\n signals.push({\n signal_id: makeId(),\n signal_type: \"excessive_overrides\",\n party_id: params.partyId,\n party_label: params.partyLabel,\n severity: Math.min(100, (overrideRate / config.max_override_rate) * 50),\n description: `Override rate ${(overrideRate * 100).toFixed(1)}% exceeds threshold ${(config.max_override_rate * 100).toFixed(1)}%`,\n evidence: [`override_count:${params.overrideCount}`, `total_actions:${params.totalActions}`],\n detected_at: now,\n reviewed: false,\n reviewed_by: null,\n });\n }\n\n // Emergency bypass repeat\n if (params.emergencyBypassCount > config.max_emergency_bypasses_30d) {\n signals.push({\n signal_id: makeId(),\n signal_type: \"emergency_bypass_repeat\",\n party_id: params.partyId,\n party_label: params.partyLabel,\n severity: Math.min(100, (params.emergencyBypassCount / config.max_emergency_bypasses_30d) * 60),\n description: `${params.emergencyBypassCount} emergency bypasses in ${params.windowDays}d (threshold: ${config.max_emergency_bypasses_30d})`,\n evidence: [`bypass_count:${params.emergencyBypassCount}`],\n detected_at: now,\n reviewed: false,\n reviewed_by: null,\n });\n }\n\n // Rushed approvals\n const rushCount = params.approvalLatencies.filter((l) => l < config.min_approval_latency_seconds).length;\n if (rushCount > 0 && params.approvalLatencies.length > 0) {\n const minLatency = Math.min(...params.approvalLatencies);\n const rushRate = rushCount / params.approvalLatencies.length;\n signals.push({\n signal_id: makeId(),\n signal_type: \"rushed_approval\",\n party_id: params.partyId,\n party_label: params.partyLabel,\n severity: Math.min(100, rushRate * 80),\n description: `${rushCount} approvals in under ${config.min_approval_latency_seconds}s (min observed: ${minLatency.toFixed(0)}s)`,\n evidence: [`rushed_count:${rushCount}`, `total_approvals:${params.approvalLatencies.length}`],\n detected_at: now,\n reviewed: false,\n reviewed_by: null,\n });\n }\n\n // Authority concentration\n if (params.approvalShare > config.max_concentration_share) {\n signals.push({\n signal_id: makeId(),\n signal_type: \"authority_concentration\",\n party_id: params.partyId,\n party_label: params.partyLabel,\n severity: Math.min(100, (params.approvalShare / config.max_concentration_share) * 50),\n description: `Party controls ${(params.approvalShare * 100).toFixed(1)}% of approvals (threshold: ${(config.max_concentration_share * 100).toFixed(1)}%)`,\n evidence: [`approval_share:${params.approvalShare.toFixed(3)}`],\n detected_at: now,\n reviewed: false,\n reviewed_by: null,\n });\n }\n\n // Deep delegation chains\n if (params.delegationDepthMax > config.max_delegation_depth) {\n signals.push({\n signal_id: makeId(),\n signal_type: \"delegation_chain_depth\",\n party_id: params.partyId,\n party_label: params.partyLabel,\n severity: Math.min(100, ((params.delegationDepthMax - config.max_delegation_depth) / config.max_delegation_depth) * 60),\n description: `Delegation depth ${params.delegationDepthMax} exceeds threshold ${config.max_delegation_depth}`,\n evidence: [`depth:${params.delegationDepthMax}`],\n detected_at: now,\n reviewed: false,\n reviewed_by: null,\n });\n }\n\n return signals.sort((a, b) => b.severity - a.severity);\n}\n\n/**\n * Compute a governance health score (0–100).\n * 100 = perfect governance; 0 = extreme misalignment.\n */\nexport function computeGovernanceHealthScore(signals: readonly IncentiveSignal[]): number {\n if (signals.length === 0) return 100;\n const totalPenalty = signals.reduce((acc, s) => acc + s.severity * 0.5, 0);\n return Math.max(0, 100 - totalPenalty);\n}\n","/**\n * Economic Evidence Bundles.\n *\n * Generates signed evidence proving approval provenance, execution\n * authorization, runtime conformity, liability chain, and policy compliance\n * for regulatory review, insurance, financial audit, and legal discovery.\n *\n * Follows the same signing pattern as auditBundle.ts, scoped to financial\n * governance evidence.\n *\n * Wire-stable as `economic_evidence.v1`.\n */\n\nimport type { FinancialExecutionRecord } from \"./financialAction.js\";\nimport type { LiabilityAttributionRecord } from \"./liabilityAttribution.js\";\nimport type { FinancialQuorumResult } from \"./financialQuorum.js\";\nimport type { BudgetConstraintCheckResult } from \"./budgetaryGovernance.js\";\n\n/** Purpose for which an economic evidence bundle is generated. */\nexport type EvidencePurpose =\n | \"regulator_review\"\n | \"insurance_review\"\n | \"financial_audit\"\n | \"legal_discovery\"\n | \"internal_review\"\n | \"dispute_resolution\";\n\n/** Approval provenance record within the evidence bundle. */\nexport interface ApprovalProvenance {\n readonly approver_id: string;\n readonly approver_label: string;\n readonly permit_id: string;\n readonly approved_at: string;\n readonly audit_hash: string;\n readonly role: string;\n}\n\n/** Complete economic evidence bundle. */\nexport interface EconomicEvidenceBundle {\n readonly version: \"economic_evidence.v1\";\n readonly bundle_id: string;\n readonly org_id: string;\n readonly purpose: EvidencePurpose;\n readonly execution_record: FinancialExecutionRecord;\n readonly liability_attribution: LiabilityAttributionRecord;\n readonly quorum_result: FinancialQuorumResult;\n readonly budget_check: BudgetConstraintCheckResult;\n readonly approval_provenance: readonly ApprovalProvenance[];\n readonly runtime_conformity: boolean;\n readonly runtime_conformity_notes: readonly string[];\n readonly policy_compliant: boolean;\n readonly policy_violations: readonly string[];\n readonly generated_at: string;\n readonly requested_by: string;\n /** SHA-256 hex of the canonical signable content. */\n readonly content_hash: string;\n /** Base64url Ed25519 signature of the canonical content. */\n readonly signature: string | null;\n readonly signing_key_id: string | null;\n}\n\n/** Canonical content shape that gets hashed and signed. */\nexport interface EvidenceBundleSignableContent {\n readonly bundle_id: string;\n readonly org_id: string;\n readonly purpose: EvidencePurpose;\n readonly execution_id: string;\n readonly attribution_id: string;\n readonly liability_chain_hash: string;\n readonly approval_count: number;\n readonly permit_ids: readonly string[];\n readonly policy_compliant: boolean;\n readonly generated_at: string;\n}\n\n/** Verification result for an economic evidence bundle. */\nexport interface EvidenceBundleVerificationResult {\n readonly valid: boolean;\n readonly content_hash_valid: boolean;\n readonly signature_valid: boolean;\n readonly liability_chain_hash_matches: boolean;\n readonly permit_ids_match: boolean;\n readonly reason: string | null;\n}\n\n/**\n * Canonicalize a value to a stable string representation.\n *\n * Exported (rather than file-private) to enable cross-language\n * byte-equivalence verification against the Python implementation in\n * ``atlasent-sdk/python/atlasent/governance/_canonical.py``. The shared\n * fixture lives at ``compat/governance/fixtures/parity.json``.\n */\nexport function canonicalizeForEvidence(value: unknown): string {\n if (value === null || value === undefined) return \"null\";\n if (typeof value === \"number\") return Number.isFinite(value) ? String(value) : \"null\";\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n if (typeof value === \"string\") return JSON.stringify(value);\n if (Array.isArray(value)) return \"[\" + value.map(canonicalizeForEvidence).join(\",\") + \"]\";\n if (typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n return \"{\" + keys.map((k) => JSON.stringify(k) + \":\" + canonicalizeForEvidence(obj[k])).join(\",\") + \"}\";\n }\n return \"null\";\n}\n\n/**\n * Build the signable content object for a bundle.\n * Key order is load-bearing — must remain stable across versions.\n */\nexport function buildSignableContent(\n bundle: Omit<EconomicEvidenceBundle, \"content_hash\" | \"signature\" | \"signing_key_id\">,\n): EvidenceBundleSignableContent {\n return {\n bundle_id: bundle.bundle_id,\n org_id: bundle.org_id,\n purpose: bundle.purpose,\n execution_id: bundle.execution_record.execution_id,\n attribution_id: bundle.liability_attribution.attribution_id,\n liability_chain_hash: bundle.liability_attribution.chain_hash,\n approval_count: bundle.approval_provenance.length,\n permit_ids: bundle.approval_provenance.map((a) => a.permit_id),\n policy_compliant: bundle.policy_compliant,\n generated_at: bundle.generated_at,\n };\n}\n\n/**\n * Serialize signable content to canonical UTF-8 bytes.\n * Uses the same sort-keyed canonicalization as auditBundle.\n */\nexport function serializeSignableContent(\n content: EvidenceBundleSignableContent,\n): Uint8Array {\n return new TextEncoder().encode(canonicalizeForEvidence(content));\n}\n\n/**\n * Verify an economic evidence bundle's structural integrity.\n * Does NOT verify the Ed25519 signature (requires crypto keys).\n */\nexport function verifyEvidenceBundleStructure(\n bundle: EconomicEvidenceBundle,\n): EvidenceBundleVerificationResult {\n const errors: string[] = [];\n\n // Permit ID consistency between provenance and execution record\n const bundlePermitIds = new Set(bundle.execution_record.permit_ids);\n const provenancePermitIds = bundle.approval_provenance.map((a) => a.permit_id);\n const permitIdsMatch = provenancePermitIds.every((id) => bundlePermitIds.has(id));\n if (!permitIdsMatch) {\n errors.push(\"permit IDs in approval provenance do not all appear in execution record\");\n }\n\n // Content hash format check (SHA-256 hex = 64 chars)\n const contentHashValid = typeof bundle.content_hash === \"string\" && bundle.content_hash.length === 64;\n if (!contentHashValid) errors.push(\"content_hash appears invalid (expected 64-char hex)\");\n\n // Liability chain hash presence\n const liabilityChainHashMatches =\n typeof bundle.liability_attribution.chain_hash === \"string\" &&\n bundle.liability_attribution.chain_hash.length > 0;\n if (!liabilityChainHashMatches) errors.push(\"liability_attribution.chain_hash is missing or empty\");\n\n const signatureValid = bundle.signature !== null && bundle.signature.length > 0;\n\n return {\n valid: errors.length === 0 && contentHashValid,\n content_hash_valid: contentHashValid,\n signature_valid: signatureValid,\n liability_chain_hash_matches: liabilityChainHashMatches,\n permit_ids_match: permitIdsMatch,\n reason: errors.length === 0 ? null : errors[0] ?? \"bundle integrity check failed\",\n };\n}\n","/**\n * Dispute + Reversal Workflows.\n *\n * Manages disputed financial actions, rollback workflows, frozen actions,\n * and temporary suspensions. Tracks dispute origin, remediation timeline,\n * and reversal authority.\n *\n * Wire-stable as `dispute_reversal.v1`.\n */\n\nimport type { FinancialExecutionStatus } from \"./financialAction.js\";\n\n/** Who or what originated a dispute. */\nexport type DisputeOrigin =\n | \"counterparty\" // External counterparty challenged the action\n | \"regulator\" // Regulatory body flagged the action\n | \"internal_audit\" // Internal audit team\n | \"fraud_detection\" // Automated fraud detection\n | \"approver_retract\" // An approver retracted their approval\n | \"policy_violation\" // Policy violation detected post-execution\n | \"agent_error\"; // Autonomous agent error\n\n/** Current state of a dispute. */\nexport type DisputeStatus =\n | \"open\"\n | \"under_review\"\n | \"escalated\"\n | \"resolved_in_favor\"\n | \"resolved_against\"\n | \"reversed\"\n | \"withdrawn\";\n\n/** A dispute record for a financial action. */\nexport interface DisputeRecord {\n readonly dispute_id: string;\n readonly execution_id: string;\n readonly org_id: string;\n readonly origin: DisputeOrigin;\n readonly filed_by: string;\n readonly description: string;\n readonly status: DisputeStatus;\n readonly execution_frozen: boolean;\n readonly opened_at: string;\n readonly resolution_deadline: string | null;\n readonly resolved_at: string | null;\n readonly resolved_by: string | null;\n readonly resolution_notes: string | null;\n readonly reversal_initiated: boolean;\n readonly reversal_id: string | null;\n}\n\n/** Reversal workflow stage. */\nexport type ReversalStage =\n | \"initiated\"\n | \"authorization_pending\"\n | \"authorized\"\n | \"executing\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\";\n\n/** A reversal workflow for a financial execution. */\nexport interface ReversalWorkflow {\n readonly reversal_id: string;\n readonly execution_id: string;\n readonly dispute_id: string | null;\n readonly org_id: string;\n readonly initiated_by: string;\n readonly reason: string;\n readonly stage: ReversalStage;\n readonly authorized_by: string | null;\n readonly authorization_permit_id: string | null;\n readonly initiated_at: string;\n readonly authorized_at: string | null;\n readonly completed_at: string | null;\n readonly reversal_value: number;\n readonly partial: boolean;\n}\n\n/** Action freeze record. */\nexport interface ActionFreeze {\n readonly freeze_id: string;\n readonly execution_id: string;\n readonly org_id: string;\n readonly triggered_by: string;\n readonly reason: string;\n readonly triggered_at: string;\n readonly expires_at: string | null;\n readonly lifted: boolean;\n readonly lifted_at: string | null;\n readonly lifted_by: string | null;\n readonly frozen_status: FinancialExecutionStatus;\n}\n\nconst VALID_DISPUTE_TRANSITIONS: Record<DisputeStatus, readonly DisputeStatus[]> = {\n open: [\"under_review\", \"withdrawn\"],\n under_review: [\"escalated\", \"resolved_in_favor\", \"resolved_against\", \"reversed\"],\n escalated: [\"resolved_in_favor\", \"resolved_against\", \"reversed\"],\n resolved_in_favor: [],\n resolved_against: [],\n reversed: [],\n withdrawn: [],\n};\n\n/** Validate and apply a dispute status transition. */\nexport function transitionDispute(\n current: DisputeStatus,\n next: DisputeStatus,\n): { success: boolean; new_status: DisputeStatus | null; error: string | null } {\n const allowed = VALID_DISPUTE_TRANSITIONS[current];\n if (!allowed.includes(next)) {\n return { success: false, new_status: null, error: `invalid dispute transition: ${current} → ${next}` };\n }\n return { success: true, new_status: next, error: null };\n}\n\nconst VALID_REVERSAL_TRANSITIONS: Record<ReversalStage, readonly ReversalStage[]> = {\n initiated: [\"authorization_pending\", \"cancelled\"],\n authorization_pending: [\"authorized\", \"cancelled\"],\n authorized: [\"executing\", \"cancelled\"],\n executing: [\"completed\", \"failed\"],\n completed: [],\n failed: [\"initiated\"], // Allow retry\n cancelled: [],\n};\n\n/** Validate and apply a reversal workflow stage transition. */\nexport function transitionReversal(\n current: ReversalStage,\n next: ReversalStage,\n): { success: boolean; error: string | null } {\n const allowed = VALID_REVERSAL_TRANSITIONS[current];\n if (!allowed.includes(next)) {\n return { success: false, error: `invalid reversal transition: ${current} → ${next}` };\n }\n return { success: true, error: null };\n}\n\n/**\n * Return true when a freeze is currently active (not lifted and not expired).\n */\nexport function isFreezeActive(freeze: ActionFreeze, now?: Date): boolean {\n if (freeze.lifted) return false;\n if (freeze.expires_at !== null) {\n const nowIso = (now ?? new Date()).toISOString();\n if (nowIso >= freeze.expires_at) return false;\n }\n return true;\n}\n\n/**\n * Compute remediation urgency based on dispute deadline.\n * Returns 'overdue' when past deadline, 'urgent' within 24h, else 'normal'.\n */\nexport function computeRemediationUrgency(\n _openedAt: string,\n deadline: string | null,\n now?: Date,\n): \"normal\" | \"urgent\" | \"overdue\" {\n if (deadline === null) return \"normal\";\n const nowMs = (now ?? new Date()).getTime();\n const deadlineMs = new Date(deadline).getTime();\n const remaining = deadlineMs - nowMs;\n if (remaining < 0) return \"overdue\";\n if (remaining < 24 * 60 * 60 * 1000) return \"urgent\";\n return \"normal\";\n}\n","/**\n * Financial Control Dashboard — types for governance visualization.\n *\n * Covers approval concentration analysis, override analytics, budget drift,\n * economic risk timelines, and liability visualization.\n *\n * These are pure data types; rendering is left to UI consumers.\n *\n * Wire-stable as `financial_dashboard.v1`.\n */\n\nimport type { FinancialRiskTier } from \"./financialAction.js\";\nimport type { ApprovalConcentrationAnalysis, BudgetaryDriftAnalysis, FinancialRiskScore } from \"./economicRisk.js\";\nimport type { MisalignmentAlert } from \"./incentiveAlignment.js\";\nimport type { LiabilityParty } from \"./liabilityAttribution.js\";\nimport type { DisputeRecord, ReversalWorkflow } from \"./disputeReversal.js\";\n\n/** Top-level financial governance summary for a dashboard view. */\nexport interface FinancialGovernanceSummary {\n readonly org_id: string;\n readonly generated_at: string;\n readonly window_days: number;\n readonly current_risk_score: FinancialRiskScore;\n readonly total_actions: number;\n readonly total_value: number;\n readonly override_count: number;\n readonly emergency_bypass_count: number;\n readonly active_dispute_count: number;\n readonly pending_reversal_count: number;\n readonly active_freeze_count: number;\n readonly budget_warning_count: number;\n readonly budget_critical_count: number;\n readonly concentration_analysis: ApprovalConcentrationAnalysis;\n readonly budget_drift: readonly BudgetaryDriftAnalysis[];\n readonly misalignment_alerts: readonly MisalignmentAlert[];\n readonly risk_timeline: readonly RiskTimelinePoint[];\n}\n\n/** A single point on the economic risk timeline. */\nexport interface RiskTimelinePoint {\n readonly date: string;\n readonly risk_score: number;\n readonly risk_tier: FinancialRiskTier;\n readonly action_count: number;\n readonly total_value: number;\n readonly override_count: number;\n readonly anomaly_count: number;\n}\n\n/** Override analytics for operator review. */\nexport interface OverrideAnalytics {\n readonly org_id: string;\n readonly window_days: number;\n readonly total_overrides: number;\n readonly override_rate: number;\n readonly overrides_by_actor: readonly ActorOverrideStat[];\n readonly overrides_by_action_type: readonly ActionTypeOverrideStat[];\n readonly override_value_total: number;\n readonly repeat_override_actors: readonly string[];\n readonly emergency_override_count: number;\n readonly computed_at: string;\n}\n\nexport interface ActorOverrideStat {\n readonly actor_id: string;\n readonly actor_label: string;\n readonly override_count: number;\n readonly override_value_total: number;\n readonly last_override_at: string;\n}\n\nexport interface ActionTypeOverrideStat {\n readonly action_type: string;\n readonly override_count: number;\n readonly total_value: number;\n}\n\n/** Liability visualization data for graph/chart rendering. */\nexport interface LiabilityVisualization {\n readonly execution_id: string;\n readonly org_id: string;\n readonly nodes: readonly LiabilityNode[];\n readonly edges: readonly LiabilityEdge[];\n readonly total_weight: number;\n}\n\nexport interface LiabilityNode {\n readonly id: string;\n readonly label: string;\n readonly party_type: \"human\" | \"agent\" | \"system\";\n readonly role: string;\n readonly liability_weight: number;\n readonly acted_at: string;\n}\n\nexport interface LiabilityEdge {\n readonly from_id: string;\n readonly to_id: string;\n readonly relationship: \"authorized\" | \"delegated_to\" | \"approved_for\" | \"supervised\" | \"overrode\";\n readonly weight: number;\n}\n\n/** Active disputes and reversals dashboard summary. */\nexport interface DisputeReversalSummary {\n readonly org_id: string;\n readonly active_disputes: readonly DisputeRecord[];\n readonly pending_reversals: readonly ReversalWorkflow[];\n readonly resolved_last_30d: number;\n readonly average_resolution_days: number;\n readonly overdue_disputes: readonly DisputeRecord[];\n readonly total_disputed_value: number;\n readonly total_reversed_value: number;\n readonly generated_at: string;\n}\n\n/**\n * Build a liability visualization graph from a liability chain.\n */\nexport function buildLiabilityVisualization(\n executionId: string,\n orgId: string,\n chain: readonly LiabilityParty[],\n): LiabilityVisualization {\n const nodes: LiabilityNode[] = chain.map((p) => ({\n id: p.party_id,\n label: p.party_label,\n party_type: p.party_type,\n role: p.role,\n liability_weight: p.liability_weight,\n acted_at: p.acted_at,\n }));\n\n const edges: LiabilityEdge[] = [];\n for (let i = 0; i < chain.length - 1; i++) {\n const from = chain[i]!;\n const to = chain[i + 1]!;\n let relationship: LiabilityEdge[\"relationship\"] = \"authorized\";\n if (from.role === \"delegator\" && to.role === \"delegate\") relationship = \"delegated_to\";\n else if (from.role === \"supervisor\") relationship = \"supervised\";\n else if (to.role === \"approver\") relationship = \"approved_for\";\n else if (to.role === \"override_actor\") relationship = \"overrode\";\n edges.push({\n from_id: from.party_id,\n to_id: to.party_id,\n relationship,\n weight: Math.min(from.liability_weight, to.liability_weight),\n });\n }\n\n return {\n execution_id: executionId,\n org_id: orgId,\n nodes,\n edges,\n total_weight: chain.reduce((s, p) => s + p.liability_weight, 0),\n };\n}\n\n/**\n * Build a risk timeline from daily snapshot data.\n */\nexport function buildRiskTimeline(\n snapshots: readonly {\n date: string;\n riskScore: number;\n actionCount: number;\n totalValue: number;\n overrideCount: number;\n anomalyCount: number;\n }[],\n): RiskTimelinePoint[] {\n return snapshots.map((s) => {\n let tier: FinancialRiskTier = \"low\";\n if (s.riskScore > 80) tier = \"critical\";\n else if (s.riskScore > 55) tier = \"high\";\n else if (s.riskScore > 25) tier = \"medium\";\n return {\n date: s.date,\n risk_score: s.riskScore,\n risk_tier: tier,\n action_count: s.actionCount,\n total_value: s.totalValue,\n override_count: s.overrideCount,\n anomaly_count: s.anomalyCount,\n };\n });\n}\n","/**\n * Enforcement-layer helpers for the canonical economic governance primitives.\n *\n * The canonical EGAS modules (`financialQuorum`, `liabilityAttribution`,\n * `economicEvidence`, `budgetaryGovernance`, `autonomousFinancial`) are\n * **advisory**: they produce structured decision objects but never block\n * execution. This module converts \"not permitted\" advisory results into\n * thrown {@link GovernanceEnforcementError} so callers cannot silently\n * proceed when a governance gate refuses an action.\n *\n * Three gates, layered in this order at consumer call sites:\n *\n * ```ts\n * enforceFinancialQuorum(quorumResult);\n * enforceBudgetConstraint(budgetResult);\n * enforceAutonomousBounds(autonomousResult);\n * ```\n *\n * Each helper is a no-op when its result is permitted; otherwise it throws\n * with a stable {@link GovernanceEnforcementError.denyCode} matching a row\n * in `docs/APPROVAL_DENY_REASONS.md`. The deny-code taxonomy is locked\n * cross-language by the parity fixture at\n * `compat/governance/fixtures/parity.json`.\n */\n\nimport { AtlaSentError, type AtlaSentErrorInit } from \"./errors.js\";\nimport type { AutonomousExecutionCheckResult } from \"./autonomousFinancial.js\";\nimport type { BudgetConstraintCheckResult } from \"./budgetaryGovernance.js\";\nimport type { FinancialQuorumResult } from \"./financialQuorum.js\";\n\n/** Which enforcement gate fired. */\nexport type GovernanceGate = \"financial_quorum\" | \"budget\" | \"autonomous_bounds\";\n\n/** Stable deny codes for the financial-quorum gate. */\nexport type FinancialQuorumDenyCode =\n | \"blocked_by_emergency_freeze\"\n | \"base_count_unmet\"\n | \"amount_threshold_unmet\"\n | \"financial_role_unmet\"\n | \"regulator_approval_missing\";\n\n/** Stable deny codes for the budget gate. */\nexport type BudgetDenyCode =\n | \"limit_exceeded\"\n | \"single_transaction_exceeds\"\n | \"daily_aggregate_exceeds\"\n | \"monthly_aggregate_exceeds\"\n | \"anonymous_agent_blocked\"\n | \"period_expired\";\n\n/** Stable deny codes for the autonomous-bounds gate. */\nexport type AutonomousBoundsDenyCode =\n | \"inactive\"\n | \"expired\"\n | \"action_type_not_permitted\"\n | \"execution_ceiling_exceeded\"\n | \"daily_aggregate_exceeded\"\n | \"risk_tier_exceeded\";\n\n/** Initialization options for {@link GovernanceEnforcementError}. */\nexport interface GovernanceEnforcementErrorInit {\n gate: GovernanceGate;\n denyCode: string;\n reason: string;\n details: unknown;\n requestId?: string;\n}\n\n/**\n * Thrown when an EGAS advisory result fails an enforcement gate.\n *\n * Extends {@link AtlaSentError} so `instanceof AtlaSentError` catches\n * these too. Use `instanceof GovernanceEnforcementError` to distinguish\n * a governance refusal from a transport / config error.\n */\nexport class GovernanceEnforcementError extends AtlaSentError {\n override name: string = \"GovernanceEnforcementError\";\n\n /** Which gate fired (`financial_quorum` / `budget` / `autonomous_bounds`). */\n readonly gate: GovernanceGate;\n /** Stable taxonomy code; maps to a row in `docs/APPROVAL_DENY_REASONS.md`. */\n readonly denyCode: string;\n /** Human-readable explanation. Do NOT branch on this string — branch on `denyCode`. */\n readonly reason: string;\n /** The structured advisory result that produced the denial. */\n readonly details: unknown;\n\n constructor(init: GovernanceEnforcementErrorInit) {\n const errInit: AtlaSentErrorInit = { code: \"forbidden\" };\n if (init.requestId !== undefined) errInit.requestId = init.requestId;\n super(`[${init.gate}/${init.denyCode}] ${init.reason}`, errInit);\n this.gate = init.gate;\n this.denyCode = init.denyCode;\n this.reason = init.reason;\n this.details = init.details;\n }\n\n /** Combined `<gate>/<denyCode>` string used in audit records. */\n get fullyQualifiedCode(): string {\n return `${this.gate}/${this.denyCode}`;\n }\n}\n\n// ─── financial_quorum ─────────────────────────────────────────────────\n\nfunction financialQuorumDenyCode(\n result: FinancialQuorumResult,\n): FinancialQuorumDenyCode {\n // Order matches evaluateFinancialQuorum so first-failing-gate wins\n // produces the same code in TS and Python.\n if (result.blocked_by_freeze) return \"blocked_by_emergency_freeze\";\n if (!result.base_quorum_passed) return \"base_count_unmet\";\n if (!result.amount_threshold_satisfied) return \"amount_threshold_unmet\";\n if (!result.financial_roles_satisfied) return \"financial_role_unmet\";\n if (result.regulator_approval_missing) return \"regulator_approval_missing\";\n // Defensive fallback; unreachable when result.passed is false.\n return \"base_count_unmet\";\n}\n\n/**\n * Throw {@link GovernanceEnforcementError} when a quorum result fails.\n * Returns silently when `result.passed` is true.\n */\nexport function enforceFinancialQuorum(result: FinancialQuorumResult): void {\n if (result.passed) return;\n const denyCode = financialQuorumDenyCode(result);\n throw new GovernanceEnforcementError({\n gate: \"financial_quorum\",\n denyCode,\n reason: result.denial_reason ?? `financial quorum failed: ${denyCode}`,\n details: result,\n });\n}\n\n// ─── budget ─────────────────────────────────────────────────────────────────\n\n/**\n * Throw {@link GovernanceEnforcementError} on a budget hard block.\n *\n * Returns silently when `result.permitted` is true (no hard blocks; soft\n * warnings do not cause enforcement to fire).\n */\nexport function enforceBudgetConstraint(result: BudgetConstraintCheckResult): void {\n if (result.permitted) return;\n if (result.hard_blocks.length === 0) {\n // Defensive: permitted=false without a hard block is a contract bug.\n throw new GovernanceEnforcementError({\n gate: \"budget\",\n denyCode: \"limit_exceeded\",\n reason: \"budget enforcement failed without a structured violation\",\n details: result,\n });\n }\n const first = result.hard_blocks[0]!;\n throw new GovernanceEnforcementError({\n gate: \"budget\",\n denyCode: first.violation_type,\n reason: first.description,\n details: result,\n });\n}\n\n// ─── autonomous_bounds ────────────────────────────────────────────────────\n\nfunction autonomousBoundsDenyCode(\n result: AutonomousExecutionCheckResult,\n): AutonomousBoundsDenyCode {\n // Order matches checkAutonomousBounds.\n if (!result.bounds_active) return \"inactive\";\n if (!result.bounds_not_expired) return \"expired\";\n if (!result.action_type_permitted) return \"action_type_not_permitted\";\n if (!result.within_execution_ceiling) return \"execution_ceiling_exceeded\";\n if (!result.within_daily_aggregate) return \"daily_aggregate_exceeded\";\n if (!result.within_risk_tier) return \"risk_tier_exceeded\";\n return \"inactive\";\n}\n\n/**\n * Throw {@link GovernanceEnforcementError} when autonomous bounds fail.\n * Returns silently when `result.permitted` is true.\n */\nexport function enforceAutonomousBounds(\n result: AutonomousExecutionCheckResult,\n): void {\n if (result.permitted) return;\n const denyCode = autonomousBoundsDenyCode(result);\n throw new GovernanceEnforcementError({\n gate: \"autonomous_bounds\",\n denyCode,\n reason:\n result.denial_reason ??\n `autonomous execution out of bounds: ${denyCode}`,\n details: result,\n });\n}\n\n/**\n * Convenience: layer all three gates in canonical order.\n *\n * Order: quorum (who approved) → budget (does it fit policy spend) →\n * autonomous_bounds (is the agent allowed to do this autonomously). The\n * first failing gate throws; subsequent gates are not evaluated.\n *\n * Pass `undefined` for gates that don't apply (e.g. omit `autonomous` for\n * human-initiated actions).\n */\nexport function enforceEconomicGovernance(params: {\n quorum?: FinancialQuorumResult;\n budget?: BudgetConstraintCheckResult;\n autonomous?: AutonomousExecutionCheckResult;\n}): void {\n if (params.quorum !== undefined) enforceFinancialQuorum(params.quorum);\n if (params.budget !== undefined) enforceBudgetConstraint(params.budget);\n if (params.autonomous !== undefined) enforceAutonomousBounds(params.autonomous);\n}\n","/**\n * Governance and enforcement webhook types — wire shapes for\n * `v1-governance-webhooks` and `v1-enforcement-webhooks`.\n *\n * Covers subscription management, signed delivery callbacks, and\n * delivery receipt records. Use `verifyWebhookSignature` in your\n * receiver to authenticate payloads.\n */\n\nexport type GovernanceWebhookEvent =\n | \"enforcement.blocked\"\n | \"policy.violation\"\n | \"access_review.completed\"\n | \"mfa.enrollment_required\"\n | \"contract.activated\"\n | \"replay.drift_detected\";\n\nexport type EnforcementWebhookEvent =\n | \"enforcement.blocked\"\n | \"enforcement.pending_approval\"\n | \"enforcement.approved\"\n | \"enforcement.expired\";\n\nexport type WebhookDeliveryStatus = \"pending\" | \"delivered\" | \"failed\";\n\nexport interface WebhookSubscription {\n id: string;\n org_id: string;\n url: string;\n events: string[];\n enabled: boolean;\n description: string | null;\n created_at: string;\n}\n\nexport interface WebhookDelivery {\n id: string;\n subscription_id: string;\n event_type: string;\n payload: Record<string, unknown>;\n status: WebhookDeliveryStatus;\n response_status: number | null;\n response_body: string | null;\n attempted_at: string;\n}\n\nexport interface CreateWebhookSubscriptionRequest {\n url: string;\n events: string[];\n enabled?: boolean;\n description?: string;\n}\n\nexport interface ListWebhookSubscriptionsResponse {\n subscriptions: WebhookSubscription[];\n /** For governance webhooks, the server returns supported event names. */\n valid_events?: string[];\n}\n\nexport interface ListWebhookDeliveriesResponse {\n deliveries: WebhookDelivery[];\n}\n\n/**\n * Signed webhook payload delivered to subscriber endpoints.\n *\n * AtlaSent sets two headers on every delivery:\n * - `X-AtlaSent-Signature: sha256=<hex>` — HMAC-SHA256 of the raw body\n * - `X-AtlaSent-Event: <event_type>`\n *\n * Verify with `verifyWebhookSignature` before processing.\n */\nexport interface WebhookPayload<T = Record<string, unknown>> {\n id: string;\n org_id: string;\n event_type: string;\n source_id: string | null;\n data: T;\n created_at: string;\n}\n\n/**\n * Verify a webhook delivery signature using the subscription secret.\n *\n * Performs a constant-time HMAC-SHA256 comparison so timing attacks\n * cannot reveal secret length. Requires `globalThis.crypto.subtle`\n * (Node 20+, all modern browsers, Deno, Cloudflare Workers).\n *\n * @param payload Raw UTF-8 request body string.\n * @param signature Value of the `X-AtlaSent-Signature` header.\n * @param secret Webhook subscription secret from the AtlaSent console.\n * @returns `true` when the signature is valid.\n *\n * @example\n * ```ts\n * import { verifyWebhookSignature } from \"@atlasent/sdk\";\n *\n * app.post(\"/webhook\", async (req, res) => {\n * const ok = await verifyWebhookSignature(\n * req.rawBody,\n * req.headers[\"x-atlasent-signature\"],\n * process.env.WEBHOOK_SECRET!,\n * );\n * if (!ok) return res.status(401).send(\"invalid signature\");\n * // process req.body …\n * });\n * ```\n */\nexport async function verifyWebhookSignature(\n payload: string,\n signature: string,\n secret: string,\n): Promise<boolean> {\n const prefix = \"sha256=\";\n if (!signature.startsWith(prefix)) return false;\n const receivedHex = signature.slice(prefix.length);\n\n const encoder = new TextEncoder();\n const key = await crypto.subtle.importKey(\n \"raw\",\n encoder.encode(secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n const sigBuffer = await crypto.subtle.sign(\"HMAC\", key, encoder.encode(payload));\n const expectedHex = Array.from(new Uint8Array(sigBuffer))\n .map(b => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n\n if (receivedHex.length !== expectedHex.length) return false;\n let diff = 0;\n for (let i = 0; i < expectedHex.length; i++) {\n diff |= receivedHex.charCodeAt(i) ^ expectedHex.charCodeAt(i);\n }\n return diff === 0;\n}\n","/**\n * Compliance evidence types — wire shapes for `v1-compliance-evidence`.\n *\n * Supports on-demand SOC 2 Type II control evidence collection. The\n * same run shape is used for ISO 27001, GDPR, and HIPAA; control IDs\n * differ per framework.\n */\n\nexport type ComplianceFramework = \"soc2\" | \"iso27001\" | \"gdpr\" | \"hipaa\";\n\nexport type EvidenceControlStatus = \"pass\" | \"gap\" | \"finding\";\n\nexport type ComplianceRunStatus =\n | \"pending\"\n | \"running\"\n | \"completed\"\n | \"failed\";\n\n/**\n * A single evaluated control within an evidence run.\n * `evidence` is a free-form object whose keys are framework-specific\n * metric names (e.g. `mfa_enforced_policies`, `audit_events_last_30d`).\n */\nexport interface EvidenceControl {\n control_id: string;\n title: string;\n status: EvidenceControlStatus;\n evidence: Record<string, unknown>;\n}\n\nexport interface ComplianceEvidenceSummary {\n total: number;\n pass: number;\n gap: number;\n finding: number;\n}\n\nexport interface ComplianceEvidenceRun {\n id: string;\n org_id: string;\n framework: ComplianceFramework;\n period_start: string;\n period_end: string;\n status: ComplianceRunStatus;\n controls: EvidenceControl[];\n summary: ComplianceEvidenceSummary | null;\n applied_by: string | null;\n created_at: string;\n}\n\nexport interface TriggerEvidenceRunRequest {\n framework: ComplianceFramework;\n /** ISO 8601 date string; defaults to 30 days ago on the server. */\n period_start?: string;\n /** ISO 8601 date string; defaults to now on the server. */\n period_end?: string;\n}\n\nexport interface TriggerEvidenceRunResponse {\n run: ComplianceEvidenceRun;\n}\n\nexport interface ListEvidenceRunsResponse {\n runs: ComplianceEvidenceRun[];\n}\n\n/**\n * SOC 2 control IDs evaluated by `v1-compliance-evidence`.\n *\n * | ID | Area |\n * |--------|------|\n * | CC6.1 | MFA enforcement |\n * | CC6.3 | Periodic access reviews |\n * | CC7.2 | Audit trail completeness |\n * | CC8.1 | Change management / HITL |\n * | CC3.2 | Policy violations |\n */\nexport type SOC2ControlId = \"CC6.1\" | \"CC6.3\" | \"CC7.2\" | \"CC8.1\" | \"CC3.2\";\n\n/**\n * Returns `true` when every control in the run has `pass` or `gap`\n * status (no `finding`). A `gap` means a control is partially met;\n * a `finding` is a blocking deficiency that requires remediation.\n */\nexport function evidenceRunPasses(run: ComplianceEvidenceRun): boolean {\n return (run.controls ?? []).every(c => c.status !== \"finding\");\n}\n\n/**\n * Returns controls that do not have `pass` status, sorted so\n * `finding` controls appear before `gap` controls.\n */\nexport function nonPassingControls(run: ComplianceEvidenceRun): EvidenceControl[] {\n return (run.controls ?? [])\n .filter(c => c.status !== \"pass\")\n .sort((a, b) => {\n if (a.status === \"finding\" && b.status !== \"finding\") return -1;\n if (b.status === \"finding\" && a.status !== \"finding\") return 1;\n return 0;\n });\n}\n","/**\n * Policy-as-code GitOps sync types — wire shapes for `v1-policy-sync`.\n *\n * Supports a dry-run diff preview / apply workflow for pushing policy\n * bundles from CI/CD pipelines or the AtlaSent console.\n *\n * Typical flow:\n * 1. POST `{ policies, dry_run: true }` → receive `run` with `diff`\n * 2. Review diff, then POST `/{run.id}/apply` to execute\n *\n * Or POST `{ policies, dry_run: false }` for an immediate apply.\n */\n\nexport type PolicySyncStatus =\n | \"pending\" // dry-run complete; awaiting apply\n | \"validating\" // server is parsing the bundle\n | \"applying\" // writes in progress\n | \"completed\" // applied successfully\n | \"failed\" // apply error; see server logs\n | \"rejected\"; // validation failed (e.g. schema error)\n\nexport interface PolicyRef {\n name: string;\n /** SHA-256 hex of the policy body. */\n body_hash?: string;\n}\n\nexport interface PolicySyncDiff {\n added: PolicyRef[];\n updated: PolicyRef[];\n removed: PolicyRef[];\n}\n\nexport interface PolicySyncRun {\n id: string;\n org_id: string;\n /** Identifies the caller: `\"console\"`, `\"github-actions\"`, etc. */\n source: string;\n commit_sha: string | null;\n ref: string | null;\n bundle_hash: string | null;\n status: PolicySyncStatus;\n policies_added: number;\n policies_updated: number;\n policies_removed: number;\n /** Populated on dry-run; null after apply. */\n diff: PolicySyncDiff | null;\n applied_by: string | null;\n created_at: string;\n}\n\nexport interface PolicyBundleEntry {\n name: string;\n /** Policy body — OPA Rego, JSON schema, or custom DSL depending on config. */\n body: string;\n description?: string;\n tags?: string[];\n}\n\nexport interface SubmitPolicySyncRequest {\n policies: PolicyBundleEntry[];\n /** Identifies the caller (e.g. `\"github-actions\"`, `\"console\"`). */\n source?: string;\n commit_sha?: string;\n ref?: string;\n /**\n * When `true` (default), computes the diff without applying changes.\n * The returned run will have `status: \"pending\"` and a populated `diff`.\n * POST to `/{run.id}/apply` to execute.\n */\n dry_run?: boolean;\n}\n\nexport interface SubmitPolicySyncResponse {\n run: PolicySyncRun;\n}\n\nexport interface ListPolicySyncRunsResponse {\n runs: PolicySyncRun[];\n}\n\nexport interface ApplyPolicySyncResponse {\n run: PolicySyncRun;\n}\n\n/**\n * Returns a human-readable one-line diff summary suitable for CI logs.\n *\n * @example\n * formatPolicySyncDiff(run) // \"+3 added, ~1 updated, -2 removed\"\n * formatPolicySyncDiff(run) // \"no changes\"\n */\nexport function formatPolicySyncDiff(\n run: Pick<PolicySyncRun, \"policies_added\" | \"policies_updated\" | \"policies_removed\">,\n): string {\n const parts: string[] = [];\n if (run.policies_added > 0) parts.push(`+${run.policies_added} added`);\n if (run.policies_updated > 0) parts.push(`~${run.policies_updated} updated`);\n if (run.policies_removed > 0) parts.push(`-${run.policies_removed} removed`);\n return parts.length > 0 ? parts.join(\", \") : \"no changes\";\n}\n\n/**\n * Returns `true` when a sync run is in a terminal state\n * (completed, failed, or rejected) and no further transitions are expected.\n */\nexport function isPolicySyncTerminal(run: PolicySyncRun): boolean {\n return run.status === \"completed\" || run.status === \"failed\" || run.status === \"rejected\";\n}\n","/**\n * Webhook signature verification for AtlaSent.\n *\n * AtlaSent signs webhook payloads with HMAC-SHA256 using your webhook secret.\n * The signature is sent in the `X-AtlaSent-Signature` header as `sha256=<hex>`.\n *\n * Usage:\n * ```ts\n * import { verifyWebhook, assertWebhook, WebhookVerificationError } from \"@atlasent/sdk\";\n *\n * // Returns true/false — good for middleware that needs to continue on failure\n * const valid = verifyWebhook(rawBody, req.headers[\"x-atlasent-signature\"], secret);\n *\n * // Throws WebhookVerificationError on failure — good for middleware that throws\n * assertWebhook(rawBody, req.headers[\"x-atlasent-signature\"], secret);\n * ```\n */\n\n/**\n * Thrown by {@link assertWebhook} when the signature is missing,\n * malformed, or does not match the payload.\n */\nexport class WebhookVerificationError extends Error {\n override name = \"WebhookVerificationError\";\n\n constructor(message: string) {\n super(message);\n }\n}\n\n// ── Environment detection ─────────────────────────────────────────────────────\n\n/**\n * True when the Web Crypto API (`crypto.subtle`) is available.\n * This is the case in browsers, Cloudflare Workers, Deno, and Node ≥ 20\n * with the global `crypto` exposed. We also accept Node's\n * `require('node:crypto').webcrypto` shape, which exposes `subtle` at the\n * same path when running under Node 18/19.\n *\n * Evaluated once at module load to avoid per-call overhead.\n */\nconst _hasWebCrypto: boolean = (() => {\n try {\n return (\n typeof crypto !== \"undefined\" &&\n typeof (crypto as { subtle?: unknown }).subtle === \"object\" &&\n (crypto as { subtle?: unknown }).subtle !== null\n );\n } catch {\n return false;\n }\n})();\n\n// ── Hex helpers ───────────────────────────────────────────────────────────────\n\n/**\n * Extract the raw hex digest from a `sha256=<hex>` or bare `<hex>` signature\n * string. Returns `null` for any value that doesn't look like a valid\n * lowercase hex string of the expected length (64 chars = 32 bytes = SHA-256).\n */\nfunction _extractHex(signature: string): string | null {\n if (typeof signature !== \"string\") return null;\n\n const hex = signature.startsWith(\"sha256=\") ? signature.slice(7) : signature;\n\n // SHA-256 produces exactly 32 bytes → 64 hex characters.\n if (hex.length !== 64) return null;\n if (!/^[0-9a-f]+$/i.test(hex)) return null;\n\n return hex.toLowerCase();\n}\n\n// ── Timing-safe comparison ────────────────────────────────────────────────────\n\n/**\n * Constant-time string comparison for hex digests.\n *\n * In Node we delegate to `crypto.timingSafeEqual` which operates on\n * `Buffer`s. In browser / edge environments we implement a manual XOR\n * accumulator over the character codes. Both reject unequal-length strings\n * in constant time (length leak is acceptable for fixed-length hex digests).\n */\nasync function _timingSafeEqual(a: string, b: string): Promise<boolean> {\n // Different lengths cannot be equal; short-circuit without exposing which\n // characters differ.\n if (a.length !== b.length) return false;\n\n if (!_hasWebCrypto) {\n // Node.js path — dynamically import `node:crypto` to stay tree-shakeable\n // in browser bundles.\n const { timingSafeEqual, createHmac: _c } = await import(\"node:crypto\");\n const aBuf = Buffer.from(a, \"hex\");\n const bBuf = Buffer.from(b, \"hex\");\n return timingSafeEqual(aBuf, bBuf);\n }\n\n // Browser / edge path — manual XOR accumulator.\n let acc = 0;\n for (let i = 0; i < a.length; i++) {\n acc |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return acc === 0;\n}\n\n// ── HMAC computation ──────────────────────────────────────────────────────────\n\n/**\n * Compute HMAC-SHA256(`secret`, `payload`) and return the hex digest.\n */\nasync function _hmacSha256Hex(payload: string, secret: string): Promise<string> {\n if (_hasWebCrypto) {\n const enc = new TextEncoder();\n const key = await crypto.subtle.importKey(\n \"raw\",\n enc.encode(secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n const sig = await crypto.subtle.sign(\"HMAC\", key, enc.encode(payload));\n return Array.from(new Uint8Array(sig))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n // Node.js path.\n const { createHmac } = await import(\"node:crypto\");\n return createHmac(\"sha256\", secret).update(payload).digest(\"hex\");\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Verifies an AtlaSent webhook payload signature.\n *\n * AtlaSent signs webhook payloads with HMAC-SHA256 using your webhook secret.\n * The signature is sent in the `X-AtlaSent-Signature` header as `\"sha256=<hex>\"`.\n *\n * @param payload - Raw request body as a string (do **not** parse before verifying)\n * @param signature - Value of the `X-AtlaSent-Signature` header\n * @param secret - Your webhook signing secret\n * @returns `true` if the signature is valid, `false` otherwise\n *\n * @remarks\n * Returns `false` (does not throw) for malformed or missing signatures.\n * Use {@link assertWebhook} if you prefer exception-based control flow.\n */\nexport async function verifyWebhook(\n payload: string,\n signature: string,\n secret: string,\n): Promise<boolean> {\n try {\n const expectedHex = _extractHex(signature);\n if (expectedHex === null) return false;\n\n const actualHex = await _hmacSha256Hex(payload, secret);\n return await _timingSafeEqual(actualHex, expectedHex);\n } catch {\n return false;\n }\n}\n\n/**\n * Same as {@link verifyWebhook} but throws {@link WebhookVerificationError}\n * on failure instead of returning `false`. Useful in middleware where\n * throwing is cleaner than inspecting a boolean return value.\n *\n * @param payload - Raw request body as a string (do **not** parse before verifying)\n * @param signature - Value of the `X-AtlaSent-Signature` header\n * @param secret - Your webhook signing secret\n * @throws {@link WebhookVerificationError} if the signature is invalid or malformed\n */\nexport async function assertWebhook(\n payload: string,\n signature: string,\n secret: string,\n): Promise<void> {\n const valid = await verifyWebhook(payload, signature, secret);\n if (!valid) {\n throw new WebhookVerificationError(\n \"Webhook signature verification failed: the signature does not match the payload.\",\n );\n }\n}\n","/**\n * Cross-Org Permission Negotiation.\n *\n * Evaluates whether an identity in one organization is permitted to\n * perform an action on resources owned by another organization.\n * Resolves trust paths, conditions, and cross-org trust levels.\n *\n * Wire-stable as `cross_org_permission.v1`.\n */\n\n/** A single hop in the cross-org trust path. */\nexport interface CrossOrgTrustHop {\n org_id: string;\n trust_type: string;\n trust_level: string;\n}\n\n/** Request payload for a cross-org permission check. */\nexport interface CrossOrgPermissionCheckRequest {\n source_org_id: string;\n target_org_id: string;\n identity_id?: string;\n action: string;\n resource_type?: string;\n resource_id?: string;\n}\n\n/** Result of a cross-org permission evaluation. */\nexport interface CrossOrgPermissionCheckResult {\n check_id: string;\n allowed: boolean;\n reason: string;\n trust_path: Array<CrossOrgTrustHop>;\n conditions: string[];\n checked_at: string;\n}\n\n/** Parameters for listing previous cross-org permission checks. */\nexport interface CrossOrgPermissionCheckListParams {\n source_org_id?: string;\n target_org_id?: string;\n allowed?: boolean;\n limit?: number;\n}\n\n/**\n * Summarize whether a cross-org check result is unconditionally allowed,\n * conditionally allowed, or denied.\n */\nexport function summarizeCrossOrgPermission(\n result: CrossOrgPermissionCheckResult,\n): \"allowed\" | \"conditional\" | \"denied\" {\n if (!result.allowed) return \"denied\";\n if (result.conditions.length > 0) return \"conditional\";\n return \"allowed\";\n}\n","/**\n * Anomaly Response Automation.\n *\n * Rules-driven automated responses to governance anomalies detected\n * during agent execution. Supports freezing agents, creating incidents,\n * notifying administrators, requiring human-in-the-loop review,\n * rolling back executions, and escalating to regulators.\n *\n * Wire-stable as `anomaly_response.v1`.\n */\n\n/** The automated action type to take when an anomaly rule triggers. */\nexport type AnomalyActionType =\n | \"freeze_agent\"\n | \"create_incident\"\n | \"notify_admin\"\n | \"require_hitl\"\n | \"rollback_execution\"\n | \"escalate_to_regulator\";\n\n/** A rule that triggers an automated response when an anomaly threshold is crossed. */\nexport interface AnomalyResponseRule {\n id: string;\n org_id: string;\n name: string;\n description?: string;\n anomaly_score_threshold: number;\n action_type: AnomalyActionType;\n action_config: Record<string, unknown>;\n is_active: boolean;\n created_at: string;\n updated_at: string;\n}\n\n/** A record of an anomaly response that was triggered. */\nexport interface AnomalyResponseEvent {\n id: string;\n rule_id: string;\n execution_id: string;\n org_id: string;\n anomaly_score: number;\n action_type: AnomalyActionType;\n action_result: Record<string, unknown>;\n triggered_at: string;\n}\n\n/** Request body for creating a new anomaly response rule. */\nexport interface CreateAnomalyResponseRuleRequest {\n name: string;\n description?: string;\n anomaly_score_threshold: number;\n action_type: AnomalyActionType;\n action_config?: Record<string, unknown>;\n}\n\n/** Request body for manually triggering an anomaly response check. */\nexport interface TriggerAnomalyResponseRequest {\n execution_id: string;\n anomaly_score: number;\n context?: Record<string, unknown>;\n}\n\n/**\n * Determine which rules from a set would trigger for a given anomaly score.\n * Returns only active rules whose threshold is met or exceeded.\n */\nexport function matchAnomalyRules(\n rules: readonly AnomalyResponseRule[],\n anomalyScore: number,\n): AnomalyResponseRule[] {\n return rules\n .filter((r) => r.is_active && anomalyScore >= r.anomaly_score_threshold)\n .sort((a, b) => b.anomaly_score_threshold - a.anomaly_score_threshold);\n}\n\n/**\n * Determine the most severe action type from a set of triggered rules.\n * Severity order (highest first):\n * escalate_to_regulator > rollback_execution > freeze_agent >\n * require_hitl > create_incident > notify_admin\n */\nexport function highestSeverityAction(\n rules: readonly AnomalyResponseRule[],\n): AnomalyActionType | null {\n const ORDER: AnomalyActionType[] = [\n \"escalate_to_regulator\",\n \"rollback_execution\",\n \"freeze_agent\",\n \"require_hitl\",\n \"create_incident\",\n \"notify_admin\",\n ];\n for (const action of ORDER) {\n if (rules.some((r) => r.action_type === action)) return action;\n }\n return null;\n}\n","/**\n * Budget Exception Workflows.\n *\n * Structured request-and-approval process for temporary exceptions\n * to budget policy limits. Supports creation, review, approval,\n * rejection, and cancellation lifecycles with full audit trails.\n *\n * Wire-stable as `budget_exceptions.v1`.\n */\n\n/** Lifecycle status of a budget exception request. */\nexport type BudgetExceptionStatus =\n | \"pending\"\n | \"under_review\"\n | \"approved\"\n | \"rejected\"\n | \"expired\"\n | \"cancelled\";\n\n/** A formal request for a temporary exception to a budget policy limit. */\nexport interface BudgetExceptionRequest {\n id: string;\n org_id: string;\n budget_policy_id?: string;\n requested_by: string;\n amount_requested: number;\n currency: string;\n reason: string;\n justification?: string;\n business_impact?: string;\n status: BudgetExceptionStatus;\n reviewed_by?: string;\n reviewed_at?: string;\n review_notes?: string;\n effective_from?: string;\n effective_until?: string;\n approved_amount?: number;\n conditions: string[];\n created_at: string;\n updated_at: string;\n}\n\n/** Request body for creating a new budget exception request. */\nexport interface CreateBudgetExceptionRequest {\n budget_policy_id?: string;\n amount_requested: number;\n currency?: string;\n reason: string;\n justification?: string;\n business_impact?: string;\n effective_from?: string;\n effective_until?: string;\n}\n\n/** Request body for approving a budget exception. */\nexport interface ApproveBudgetExceptionRequest {\n review_notes?: string;\n approved_amount: number;\n conditions?: string[];\n effective_from?: string;\n effective_until?: string;\n}\n\n/**\n * Returns true when an approved exception is currently in effect.\n * An exception is in effect when:\n * - status is \"approved\"\n * - current time is within [effective_from, effective_until]\n */\nexport function isBudgetExceptionActive(\n exception: BudgetExceptionRequest,\n now?: Date,\n): boolean {\n if (exception.status !== \"approved\") return false;\n const ts = (now ?? new Date()).toISOString();\n if (exception.effective_from && ts < exception.effective_from) return false;\n if (exception.effective_until && ts > exception.effective_until) return false;\n return true;\n}\n\n/**\n * Returns true when a budget exception request is in a terminal state\n * (no further transitions are possible).\n */\nexport function isBudgetExceptionTerminal(\n status: BudgetExceptionStatus,\n): boolean {\n return status === \"approved\" || status === \"rejected\" || status === \"expired\" || status === \"cancelled\";\n}\n","/**\n * Regulatory Escalation Chain.\n *\n * Hierarchical escalation infrastructure for routing governance issues\n * through defined authority levels. Supports multi-jurisdiction\n * regulatory chains with SLA tracking and resolution workflows.\n *\n * Wire-stable as `regulatory_escalation.v1`.\n */\n\n/**\n * A defined level in the regulatory authority hierarchy.\n * Levels are ordered numerically — lower numbers = lower authority.\n */\nexport interface RegulatoryAuthorityLevel {\n id: string;\n org_id: string;\n name: string;\n level: number;\n description?: string;\n parent_level_id?: string;\n jurisdiction?: string;\n escalation_sla_hours: number;\n created_at: string;\n}\n\n/** Lifecycle status of a regulatory escalation. */\nexport type RegulatoryEscalationStatus =\n | \"pending\"\n | \"acknowledged\"\n | \"under_review\"\n | \"resolved\"\n | \"overridden\";\n\n/** A formal escalation between two regulatory authority levels. */\nexport interface RegulatoryEscalation {\n id: string;\n org_id: string;\n from_level_id: string;\n to_level_id: string;\n subject_type: string;\n subject_id: string;\n reason: string;\n details: Record<string, unknown>;\n status: RegulatoryEscalationStatus;\n escalated_by: string;\n acknowledged_by?: string;\n acknowledged_at?: string;\n resolved_by?: string;\n resolved_at?: string;\n resolution?: string;\n resolution_details?: Record<string, unknown>;\n created_at: string;\n updated_at: string;\n}\n\n/** Request body for creating a new regulatory escalation. */\nexport interface CreateRegulatoryEscalationRequest {\n from_level_id: string;\n to_level_id: string;\n subject_type: string;\n subject_id: string;\n reason: string;\n details?: Record<string, unknown>;\n}\n\n/**\n * Returns true when a regulatory escalation is in a terminal state.\n */\nexport function isRegulatoryEscalationTerminal(\n status: RegulatoryEscalationStatus,\n): boolean {\n return status === \"resolved\" || status === \"overridden\";\n}\n\n/**\n * Determine whether an escalation has breached its SLA.\n * Compares the SLA hours on the target authority level against the\n * elapsed time since creation.\n */\nexport function isEscalationSlaBreached(\n escalation: RegulatoryEscalation,\n targetLevel: RegulatoryAuthorityLevel,\n now?: Date,\n): boolean {\n if (isRegulatoryEscalationTerminal(escalation.status)) return false;\n const createdMs = new Date(escalation.created_at).getTime();\n const nowMs = (now ?? new Date()).getTime();\n const elapsedHours = (nowMs - createdMs) / (1000 * 60 * 60);\n return elapsedHours > targetLevel.escalation_sla_hours;\n}\n","/**\n * Incentive Signal Feedback Loop.\n *\n * Captures how governance actors respond to incentive alignment signals\n * and tracks outcomes. Feeds back into signal calibration and governance\n * health scoring over time.\n *\n * Wire-stable as `incentive_signal_feedback.v1`.\n */\n\n/** The type of action taken in response to a governance signal. */\nexport type SignalActionType =\n | \"accepted\"\n | \"dismissed\"\n | \"escalated\"\n | \"delegated\"\n | \"policy_updated\"\n | \"training_initiated\"\n | \"process_changed\"\n | \"monitoring_increased\"\n | \"auto_remediated\";\n\n/** A record of an action taken in response to a governance signal. */\nexport interface GovernanceSignalAction {\n id: string;\n signal_id: string;\n org_id: string;\n action_type: SignalActionType;\n action_description?: string;\n taken_by?: string;\n taken_at: string;\n outcome_score?: number;\n outcome_description?: string;\n outcome_recorded_at?: string;\n metadata: Record<string, unknown>;\n}\n\n/** Request body for recording a new signal action. */\nexport interface RecordSignalActionRequest {\n action_type: SignalActionType;\n action_description?: string;\n metadata?: Record<string, unknown>;\n}\n\n/** Request body for recording an outcome on a previous signal action. */\nexport interface RecordSignalOutcomeRequest {\n outcome_score: number;\n outcome_description?: string;\n}\n\n/** Aggregate summary of signal actions for an organization. */\nexport interface SignalActionSummary {\n total_signals: number;\n acted_on: number;\n dismissed: number;\n average_outcome_score: number;\n by_action_type: Record<SignalActionType, { count: number; avg_outcome: number }>;\n}\n\n/**\n * Compute a simple engagement rate from a signal action summary.\n * Returns the fraction of signals that received a non-dismissed response.\n */\nexport function computeSignalEngagementRate(\n summary: SignalActionSummary,\n): number {\n if (summary.total_signals === 0) return 0;\n return summary.acted_on / summary.total_signals;\n}\n\n/**\n * Determine whether a signal action represents a substantive governance\n * response (i.e. more than a dismissal or auto-remediation).\n */\nexport function isSubstantiveSignalResponse(\n actionType: SignalActionType,\n): boolean {\n return (\n actionType === \"policy_updated\" ||\n actionType === \"training_initiated\" ||\n actionType === \"process_changed\" ||\n actionType === \"monitoring_increased\" ||\n actionType === \"escalated\"\n );\n}\n","/**\n * Cross-Org Impersonation.\n *\n * Allows a service account in one organization to impersonate a role in\n * another organization under explicit, audited grants. Supports bounded\n * token issuance, grant revocation, and token validation.\n *\n * Wire-stable as `cross_org_impersonation.v1`.\n */\n\n/** An explicit grant allowing one org's service account to impersonate a role in another org. */\nexport interface CrossOrgImpersonationGrant {\n id: string;\n grantor_org_id: string;\n grantee_org_id: string;\n grantee_service_account_id: string;\n impersonated_role: string;\n allowed_actions: string[];\n allowed_resource_types: string[];\n max_token_duration_seconds: number;\n is_active: boolean;\n created_by: string;\n created_at: string;\n expires_at?: string;\n revoked_at?: string;\n}\n\n/** Request body for creating a new impersonation grant. */\nexport interface CreateImpersonationGrantRequest {\n grantee_org_id: string;\n grantee_service_account_id: string;\n impersonated_role: string;\n allowed_actions: string[];\n allowed_resource_types: string[];\n max_token_duration_seconds?: number;\n expires_at?: string;\n}\n\n/** A short-lived impersonation token issued under a grant. */\nexport interface ImpersonationToken {\n token: string;\n expires_at: string;\n grant_id: string;\n}\n\n/** Result of validating an impersonation token. */\nexport interface ImpersonationValidationResult {\n valid: boolean;\n grant?: CrossOrgImpersonationGrant;\n impersonated_role?: string;\n allowed_actions?: string[];\n allowed_resource_types?: string[];\n error?: string;\n}\n\n/**\n * Returns true when an impersonation grant is currently usable:\n * - is_active is true\n * - not yet expired\n * - not revoked\n */\nexport function isImpersonationGrantUsable(\n grant: CrossOrgImpersonationGrant,\n now?: Date,\n): boolean {\n if (!grant.is_active) return false;\n if (grant.revoked_at) return false;\n const ts = (now ?? new Date()).toISOString();\n if (grant.expires_at && ts > grant.expires_at) return false;\n return true;\n}\n\n/**\n * Clamp a requested token duration to the grant's maximum.\n * Returns the minimum of the requested duration and the grant ceiling.\n */\nexport function clampTokenDuration(\n grant: CrossOrgImpersonationGrant,\n requestedSeconds: number,\n): number {\n return Math.min(requestedSeconds, grant.max_token_duration_seconds);\n}\n","/**\n * V2 Wave-A endpoints (V2-D3, V2-D4, V2-D8) — additive on top of v1.\n *\n * Three additional methods on top of the v1 {@link AtlaSentClient}\n * surface that target the new wire endpoints landed in `atlasent-api`\n * PRs #742 (batch), #745 (stream), and #746 (graphql).\n *\n * The v1 substrate is frozen (post-GA 2026-05-17) — this module is\n * purely additive. Existing 1.x methods (`protect`, `requirePermit`,\n * `evaluate`, …) are untouched.\n *\n * ## Closed-by-default discipline\n *\n * Each tenant gates the new endpoints behind `v2_batch`,\n * `v2_streaming`, and `v2_graphql` flags. When the flag is off the\n * API returns HTTP 404, surfaced here as {@link FeatureNotEnabledError}\n * so callers can deterministically fall back (typically to a per-item\n * `/v1-evaluate` loop). The SDK never silently falls back — that would\n * change billing and audit semantics.\n */\n\nimport { AtlaSentError, type AtlaSentErrorInit } from \"./errors.js\";\n\n// ── Constants ────────────────────────────────────────────────────────\n\nexport const V2_BATCH_PATH = \"/v1/evaluate/batch\";\nexport const V2_STREAM_PATH = \"/v1/evaluate/stream\";\nexport const V2_GRAPHQL_PATH = \"/v1/graphql\";\n\n/** Maximum items per batch (mirrors the server-side cap, V2-D3). */\nexport const V2_MAX_BATCH_ITEMS = 100;\n/** Maximum request body size (mirrors the server-side 1MB cap). */\nexport const V2_MAX_BODY_BYTES = 1_000_000;\n/** GraphQL document depth cap (V2-D2). */\nexport const V2_GRAPHQL_MAX_DEPTH = 8;\n\n// ── Errors ───────────────────────────────────────────────────────────\n\n/**\n * Identifier of the tenant flag gating a V2 endpoint.\n */\nexport type V2Feature = \"batch\" | \"streaming\" | \"graphql\";\n\n/**\n * Initialization options for {@link FeatureNotEnabledError}.\n */\nexport interface FeatureNotEnabledErrorInit {\n feature: V2Feature;\n endpoint: string;\n requestId?: string;\n}\n\n/**\n * Thrown when a V2 endpoint returns 404 because the tenant feature\n * flag is off.\n *\n * The three V2 endpoints (`/v1/evaluate/batch`, `/v1/evaluate/stream`,\n * `/v1/graphql`) are close-by-default per tenant. When the\n * corresponding flag is unset, the API returns HTTP 404; the SDK\n * surfaces that as this distinct error so the caller can\n * deterministically fall back to the v1 per-item loop.\n *\n * Subclass of {@link AtlaSentError} so `instanceof AtlaSentError`\n * catches it alongside the SDK's other typed errors.\n */\nexport class FeatureNotEnabledError extends AtlaSentError {\n override name: string = \"FeatureNotEnabledError\";\n\n /** Which tenant flag is gating the endpoint. */\n readonly feature: V2Feature;\n /** The wire path the SDK attempted (for diagnostics). */\n readonly endpoint: string;\n\n constructor(init: FeatureNotEnabledErrorInit) {\n const message =\n `AtlaSent V2 feature '${init.feature}' is not enabled for this tenant ` +\n `(POST ${init.endpoint} returned 404). Enable the v2_${init.feature} ` +\n `flag or fall back to the v1 per-item /v1-evaluate loop.`;\n // `feature_disabled` (not `forbidden`): the request was not denied\n // on authorization grounds — the tenant lacks the v2_<feature> flag.\n // Callers branching on `err.code === \"forbidden\"` would otherwise\n // conflate this with real 403 auth failures.\n const errInit: AtlaSentErrorInit = { status: 404, code: \"feature_disabled\" };\n if (init.requestId !== undefined) errInit.requestId = init.requestId;\n super(message, errInit);\n this.feature = init.feature;\n this.endpoint = init.endpoint;\n }\n}\n\n// ── Response / event shapes ────────────────────────────────────────────────\n\n/**\n * One element of an {@link EvaluateBatchResponse.items} list.\n *\n * Preserves input order — `items[i]` corresponds to `request.items[i]`.\n * On a per-item RPC failure the server returns `decision: undefined`\n * and populates `errorCode` / `errorMessage` instead.\n */\nexport interface EvaluateBatchItem {\n index: number;\n decision?: string;\n decisionId?: string;\n permitToken?: string;\n reason?: string;\n errorCode?: string;\n errorMessage?: string;\n}\n\n/** Response shape for `POST /v1/evaluate/batch`. */\nexport interface EvaluateBatchResponse {\n batchId: string;\n items: ReadonlyArray<EvaluateBatchItem>;\n partial: boolean;\n}\n\n/** Request payload for {@link evaluateMany} and {@link authorizeStream}. */\nexport interface EvaluateManyRequest {\n items: ReadonlyArray<Record<string, unknown>>;\n batchId?: string;\n}\n\n/** `event: decision` frame surfaced via the `onDecision` callback. */\nexport interface StreamDecisionFrame {\n index: number;\n decision: string;\n decisionId?: string;\n permitToken?: string;\n reason?: string;\n}\n\n/** `event: error` frame surfaced via the `onError` callback. */\nexport interface StreamErrorFrame {\n index: number;\n errorCode: string;\n message: string;\n}\n\n/** Terminal `event: complete` payload returned by {@link authorizeStream}. */\nexport interface StreamComplete {\n batchId: string;\n count: number;\n partial: boolean;\n}\n\n/** GraphQL request body. */\nexport interface GraphQLRequest {\n query: string;\n variables?: Record<string, unknown>;\n operationName?: string;\n}\n\n/**\n * GraphQL response. Resolver errors land on `errors`; the SDK does\n * not throw on them — the caller branches.\n */\nexport interface GraphQLResponse<T = unknown> {\n data: T | null;\n errors?: ReadonlyArray<Record<string, unknown>>;\n}\n\n// ── Minimal client surface this module needs ──────────────────────────────────────\n\n/**\n * The minimal subset of an {@link AtlaSentClient}-like object this\n * module needs: a `fetch`-compatible HTTP function and a base URL.\n *\n * Passed explicitly so the v2 module never reaches into v1 internals\n * (and so callers can plug in a custom fetch for testing / edge\n * runtimes / Node fetch wrappers).\n */\nexport interface V2Transport {\n /** Base URL (no trailing slash), e.g. `https://api.atlasent.io`. */\n baseUrl: string;\n /** Bearer API key (without the `Bearer ` prefix). */\n apiKey: string;\n /** A `fetch`-like function. Defaults to global `fetch` if omitted. */\n fetch?: typeof fetch;\n}\n\n// ── UUID validation ──────────────────────────────────────────────────────────\n\nconst UUID_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nfunction assertValidBatchId(batchId: string | undefined): void {\n if (batchId === undefined) return;\n if (typeof batchId !== \"string\" || !UUID_RE.test(batchId)) {\n throw new TypeError(`batchId must be a valid UUID: ${String(batchId)}`);\n }\n}\n\nfunction assertItemsShape(items: ReadonlyArray<unknown>): void {\n if (!Array.isArray(items) || items.length === 0) {\n throw new TypeError(\"items must be a non-empty array\");\n }\n if (items.length > V2_MAX_BATCH_ITEMS) {\n throw new TypeError(\n `items length ${items.length} exceeds maximum of ${V2_MAX_BATCH_ITEMS}`,\n );\n }\n}\n\nfunction assertBodyWithinCap(raw: string): void {\n // UTF-8 byte length, not character length.\n const bytes = new TextEncoder().encode(raw).length;\n if (bytes > V2_MAX_BODY_BYTES) {\n throw new TypeError(\n `request body ${bytes} bytes exceeds maximum of ${V2_MAX_BODY_BYTES}`,\n );\n }\n}\n\nfunction commonHeaders(apiKey: string): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n };\n}\n\nfunction pickFetch(t: V2Transport): typeof fetch {\n if (t.fetch !== undefined) return t.fetch;\n if (typeof fetch !== \"undefined\") return fetch;\n throw new Error(\n \"v2: no fetch implementation available (set transport.fetch or run on Node ≥ 18)\",\n );\n}\n\n// ── evaluateMany ──────────────────────────────────────────────────────────\n\n/**\n * `POST /v1/evaluate/batch` — V2-D3.\n *\n * One round-trip for up to {@link V2_MAX_BATCH_ITEMS} evaluate items.\n * Items are returned in input order — `response.items[i].index === i`.\n *\n * @throws {FeatureNotEnabledError} When the tenant `v2_batch` flag is off (404).\n * @throws {AtlaSentError} For any other transport / HTTP failure.\n * @throws {TypeError} When `items` is empty, exceeds the cap, or\n * `batchId` is not a valid UUID.\n */\nexport async function evaluateMany(\n transport: V2Transport,\n req: EvaluateManyRequest,\n): Promise<EvaluateBatchResponse> {\n assertItemsShape(req.items);\n assertValidBatchId(req.batchId);\n\n const body: Record<string, unknown> = { items: req.items };\n if (req.batchId !== undefined) body[\"batch_id\"] = req.batchId;\n const raw = JSON.stringify(body);\n assertBodyWithinCap(raw);\n\n const url = `${transport.baseUrl}${V2_BATCH_PATH}`;\n const fetchImpl = pickFetch(transport);\n const response = await fetchImpl(url, {\n method: \"POST\",\n headers: commonHeaders(transport.apiKey),\n body: raw,\n });\n\n const requestId = response.headers.get(\"X-Request-ID\") ?? undefined;\n if (response.status === 404) {\n const init: FeatureNotEnabledErrorInit = {\n feature: \"batch\",\n endpoint: V2_BATCH_PATH,\n };\n if (requestId !== undefined) init.requestId = requestId;\n throw new FeatureNotEnabledError(init);\n }\n if (!response.ok) {\n throwHttpError(V2_BATCH_PATH, response.status, requestId);\n }\n\n const parsed = await safeJson(response, V2_BATCH_PATH, requestId);\n return parseBatchResponse(parsed);\n}\n\nfunction parseBatchResponse(data: unknown): EvaluateBatchResponse {\n const root = (data ?? {}) as Record<string, unknown>;\n const rawItems = (root[\"items\"] ?? []) as ReadonlyArray<\n Record<string, unknown>\n >;\n const items: EvaluateBatchItem[] = rawItems.map((it) => {\n const out: EvaluateBatchItem = {\n index: typeof it[\"index\"] === \"number\" ? (it[\"index\"] as number) : -1,\n };\n const decision = it[\"decision\"];\n if (typeof decision === \"string\") out.decision = decision;\n const decisionId = it[\"decision_id\"];\n if (typeof decisionId === \"string\") out.decisionId = decisionId;\n const permitToken = it[\"permit_token\"];\n if (typeof permitToken === \"string\") out.permitToken = permitToken;\n const reason = it[\"reason\"];\n if (typeof reason === \"string\") out.reason = reason;\n const errorCode = it[\"error_code\"];\n if (typeof errorCode === \"string\") out.errorCode = errorCode;\n const errorMessage = it[\"error_message\"];\n if (typeof errorMessage === \"string\") out.errorMessage = errorMessage;\n return out;\n });\n const batchId = root[\"batch_id\"];\n return {\n batchId: typeof batchId === \"string\" ? batchId : \"\",\n items,\n partial: Boolean(root[\"partial\"]),\n };\n}\n\n// ── authorizeStream ──────────────────────────────────────────────────────────\n\n/**\n * Callbacks consumed by {@link authorizeStream}.\n */\nexport interface AuthorizeStreamHandlers {\n onDecision?: (frame: StreamDecisionFrame) => void;\n onError?: (frame: StreamErrorFrame) => void;\n}\n\n/**\n * `POST /v1/evaluate/stream` — V2-D4.\n *\n * Streams `event: decision` frames in input order. Per-item RPC\n * failures arrive as `event: error` frames and do not tear down the\n * stream (V2-D7 async semantics). Resolves with the terminal\n * `event: complete` payload.\n *\n * @throws {FeatureNotEnabledError} When the tenant `v2_streaming` flag is off.\n * @throws {AtlaSentError} For transport failures, including the stream\n * closing without a `complete` frame.\n */\nexport async function authorizeStream(\n transport: V2Transport,\n req: EvaluateManyRequest,\n handlers: AuthorizeStreamHandlers = {},\n): Promise<StreamComplete> {\n assertItemsShape(req.items);\n assertValidBatchId(req.batchId);\n\n const body: Record<string, unknown> = { items: req.items };\n if (req.batchId !== undefined) body[\"batch_id\"] = req.batchId;\n const raw = JSON.stringify(body);\n assertBodyWithinCap(raw);\n\n const url = `${transport.baseUrl}${V2_STREAM_PATH}`;\n const fetchImpl = pickFetch(transport);\n const response = await fetchImpl(url, {\n method: \"POST\",\n headers: {\n ...commonHeaders(transport.apiKey),\n Accept: \"text/event-stream\",\n },\n body: raw,\n });\n\n const requestId = response.headers.get(\"X-Request-ID\") ?? undefined;\n if (response.status === 404) {\n const init: FeatureNotEnabledErrorInit = {\n feature: \"streaming\",\n endpoint: V2_STREAM_PATH,\n };\n if (requestId !== undefined) init.requestId = requestId;\n throw new FeatureNotEnabledError(init);\n }\n if (!response.ok) {\n throwHttpError(V2_STREAM_PATH, response.status, requestId);\n }\n if (response.body === null) {\n throw new AtlaSentError(\n `POST ${V2_STREAM_PATH} returned no response body`,\n { code: \"bad_response\", status: response.status },\n );\n }\n\n const complete = await consumeSseStream(response.body, handlers);\n if (complete === null) {\n throw new AtlaSentError(\n \"authorizeStream: stream closed without a `complete` event\",\n { code: \"bad_response\" },\n );\n }\n return complete;\n}\n\nasync function consumeSseStream(\n body: ReadableStream<Uint8Array>,\n handlers: AuthorizeStreamHandlers,\n): Promise<StreamComplete | null> {\n const reader = body.getReader();\n const decoder = new TextDecoder(\"utf-8\");\n let buffer = \"\";\n let eventName: string | undefined = undefined;\n let complete: StreamComplete | null = null;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const { value, done } = await reader.read();\n if (value !== undefined) {\n buffer += decoder.decode(value, { stream: !done });\n }\n if (done) {\n buffer += decoder.decode();\n }\n\n // Process complete lines (separator: \\n; tolerate \\r\\n).\n let nl: number;\n while ((nl = buffer.indexOf(\"\\n\")) !== -1) {\n let line = buffer.slice(0, nl);\n buffer = buffer.slice(nl + 1);\n if (line.endsWith(\"\\r\")) line = line.slice(0, -1);\n\n if (line === \"\") {\n eventName = undefined;\n continue;\n }\n if (line.startsWith(\":\")) continue; // keep-alive heartbeat\n if (line.startsWith(\"event:\")) {\n eventName = line.slice(\"event:\".length).trim();\n continue;\n }\n if (!line.startsWith(\"data:\")) continue;\n const dataText = line.slice(\"data:\".length).trim();\n let payload: unknown;\n try {\n payload = JSON.parse(dataText);\n } catch {\n continue;\n }\n if (typeof payload !== \"object\" || payload === null || Array.isArray(payload)) {\n continue;\n }\n const p = payload as Record<string, unknown>;\n if (eventName === \"decision\" && handlers.onDecision !== undefined) {\n const dIndex = p[\"index\"];\n const dDecision = p[\"decision\"];\n const frame: StreamDecisionFrame = {\n index: typeof dIndex === \"number\" ? dIndex : -1,\n decision: typeof dDecision === \"string\" ? dDecision : \"\",\n };\n const dId = p[\"decision_id\"];\n if (typeof dId === \"string\") frame.decisionId = dId;\n const pt = p[\"permit_token\"];\n if (typeof pt === \"string\") frame.permitToken = pt;\n const r = p[\"reason\"];\n if (typeof r === \"string\") frame.reason = r;\n handlers.onDecision(frame);\n } else if (eventName === \"error\" && handlers.onError !== undefined) {\n const eIndex = p[\"index\"];\n const eCode = p[\"error_code\"];\n const eMsg = p[\"message\"];\n handlers.onError({\n index: typeof eIndex === \"number\" ? eIndex : -1,\n errorCode: typeof eCode === \"string\" ? eCode : \"\",\n message: typeof eMsg === \"string\" ? eMsg : \"\",\n });\n } else if (eventName === \"complete\") {\n const cBatchId = p[\"batch_id\"];\n const cCount = p[\"count\"];\n complete = {\n batchId: typeof cBatchId === \"string\" ? cBatchId : \"\",\n count: typeof cCount === \"number\" ? cCount : 0,\n partial: Boolean(p[\"partial\"]),\n };\n try {\n await reader.cancel();\n } catch {\n // best-effort cancel\n }\n return complete;\n }\n }\n\n if (done) break;\n }\n\n return complete;\n}\n\n// ── graphql ───────────────────────────────────────────────────────────\n\n/**\n * `POST /v1/graphql` — V2-D2 + V2-D8.\n *\n * Bearer-only auth (no query-param). Wave A schema is read-only\n * (`recentEvaluations(limit)` + `activeBundle`). Server enforces the\n * V2-D8 OR-gate (`audit:read` OR `policy:read`) at request layer and\n * a per-resolver AND-gate at field resolution time.\n *\n * Resolver-level errors surface on `response.errors` — the SDK does\n * not throw on them so callers can inspect partial data.\n *\n * @throws {FeatureNotEnabledError} When the tenant `v2_graphql` flag is off.\n * @throws {AtlaSentError} For transport / HTTP failures.\n * @throws {TypeError} When `query` is empty or the body exceeds the 1MB cap.\n */\nexport async function graphql<T = unknown>(\n transport: V2Transport,\n req: GraphQLRequest,\n): Promise<GraphQLResponse<T>> {\n if (typeof req.query !== \"string\" || req.query.trim() === \"\") {\n throw new TypeError(\"query must be a non-empty string\");\n }\n const body: Record<string, unknown> = { query: req.query };\n if (req.variables !== undefined) body[\"variables\"] = req.variables;\n if (req.operationName !== undefined)\n body[\"operationName\"] = req.operationName;\n\n const raw = JSON.stringify(body);\n assertBodyWithinCap(raw);\n\n const url = `${transport.baseUrl}${V2_GRAPHQL_PATH}`;\n const fetchImpl = pickFetch(transport);\n const response = await fetchImpl(url, {\n method: \"POST\",\n headers: commonHeaders(transport.apiKey),\n body: raw,\n });\n const requestId = response.headers.get(\"X-Request-ID\") ?? undefined;\n if (response.status === 404) {\n const init: FeatureNotEnabledErrorInit = {\n feature: \"graphql\",\n endpoint: V2_GRAPHQL_PATH,\n };\n if (requestId !== undefined) init.requestId = requestId;\n throw new FeatureNotEnabledError(init);\n }\n if (!response.ok) {\n throwHttpError(V2_GRAPHQL_PATH, response.status, requestId);\n }\n\n const parsed = (await safeJson(response, V2_GRAPHQL_PATH, requestId)) as\n | Record<string, unknown>\n | null;\n const root = parsed ?? {};\n const out: GraphQLResponse<T> = {\n data: (root[\"data\"] ?? null) as T | null,\n };\n const errs = root[\"errors\"];\n if (Array.isArray(errs) && errs.length > 0) {\n out.errors = errs as ReadonlyArray<Record<string, unknown>>;\n }\n return out;\n}\n\n// ── helpers ───────────────────────────────────────────────────────────\n\nfunction throwHttpError(\n path: string,\n status: number,\n requestId: string | undefined,\n): never {\n const errInit: AtlaSentErrorInit = {\n status,\n code: status >= 500 ? \"server_error\" : \"bad_request\",\n };\n if (requestId !== undefined) errInit.requestId = requestId;\n throw new AtlaSentError(`POST ${path} returned ${status}`, errInit);\n}\n\nasync function safeJson(\n response: Response,\n path: string,\n requestId: string | undefined,\n): Promise<unknown> {\n try {\n return await response.json();\n } catch (cause) {\n const errInit: AtlaSentErrorInit = {\n status: response.status,\n code: \"bad_response\",\n cause,\n };\n if (requestId !== undefined) errInit.requestId = requestId;\n throw new AtlaSentError(`${path}: malformed JSON response`, errInit);\n }\n}\n","/**\n * Runtime v2 client — authorized-state-change lifecycle.\n *\n * Thin client over `/v2/orgs/:org_id/…` endpoints landed in\n * `atlasent-api` PR #1031. Accepts the same {@link V2Transport}\n * interface used by the existing v2 batch/stream/graphql module so\n * callers can reuse the same auth headers and fetch implementation.\n *\n * @example\n * ```ts\n * import { RuntimeV2Client } from \"@atlasent/sdk/runtime_v2\";\n *\n * const rt = new RuntimeV2Client({\n * baseUrl: \"https://api.atlasent.io\",\n * apiKey: process.env.ATLASENT_API_KEY!,\n * });\n * const decision = await rt.authorize(\"org_acme\", { transition: { … } });\n * ```\n */\n\nimport { AtlaSentError } from \"./errors.js\";\nimport type { V2Transport } from \"./v2.js\";\n\n// ── Wire types ────────────────────────────────────────────────────────────────\n\nexport interface VerificationFailure {\n code: string;\n message: string;\n field?: string;\n}\n\nexport interface VerificationResult {\n passed: boolean;\n verified_at: string;\n failures: VerificationFailure[];\n warnings: Array<Record<string, unknown>>;\n}\n\nexport interface ExecutionReceipt {\n receipt_id: string;\n permit_id: string;\n org_id: string;\n issued_at: string;\n post_state_fingerprint: string;\n evidence_id: string;\n}\n\nexport interface PostExecutionResult {\n verified: boolean;\n evidence_completeness: \"COMPLETE\" | \"PARTIAL\" | \"FAILED\";\n failures: VerificationFailure[];\n receipt?: ExecutionReceipt;\n}\n\nexport interface AuthorizationDecision {\n status: \"PERMITTED\" | \"PENDING_APPROVAL\" | \"DENIED\" | \"ERROR\";\n permit?: Record<string, unknown>;\n required_approvers?: string[];\n reasons?: string[];\n policy_ids?: string[];\n code?: string;\n message?: string;\n}\n\nexport interface AuthorityRecord {\n authority_id: string;\n org_id: string;\n name: string;\n action_classes: string[];\n public_key: string;\n key_id: string;\n status: string;\n created_at: string;\n [key: string]: unknown;\n}\n\nexport interface RuntimeAuditEntry {\n entry_id: string;\n org_id: string;\n sequence: number;\n receipt_id: string;\n prior_hash: string;\n entry_hash: string;\n appended_at: string;\n}\n\nexport interface AuditChainPage {\n entries: RuntimeAuditEntry[];\n total: number;\n page: number;\n page_size: number;\n}\n\nexport interface ChainIntegrityReport {\n valid: boolean;\n checked_entries: number;\n first_sequence: number;\n last_sequence: number;\n gaps: number[];\n invalid_hashes: number[];\n verified_at: string;\n}\n\nexport interface ComplianceExport {\n export_id: string;\n org_id: string;\n from: string;\n to: string;\n entry_count: number;\n format: string;\n content_ref: string;\n content_hash: string;\n generated_at: string;\n signed_by: string;\n}\n\nexport interface AuditChainFilters {\n action_class?: string;\n principal_did?: string;\n resource_locator?: string;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction orgPath(orgId: string, ...parts: string[]): string {\n const base = `/v2/orgs/${orgId}`;\n return parts.length ? `${base}/${parts.join(\"/\")}` : base;\n}\n\nfunction headers(apiKey: string): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n };\n}\n\nfunction pickFetch(t: V2Transport): typeof fetch {\n if (t.fetch !== undefined) return t.fetch;\n if (typeof fetch !== \"undefined\") return fetch;\n throw new Error(\n \"runtime_v2: no fetch available (set transport.fetch or run Node ≥ 18)\",\n );\n}\n\nasync function doPost(\n t: V2Transport,\n path: string,\n body: unknown,\n): Promise<Record<string, unknown>> {\n const f = pickFetch(t);\n const res = await f(`${t.baseUrl}${path}`, {\n method: \"POST\",\n headers: headers(t.apiKey),\n body: JSON.stringify(body),\n });\n const data = (await res.json()) as Record<string, unknown>;\n if (!res.ok) {\n const err = (data[\"error\"] as Record<string, unknown>) ?? {};\n throw new AtlaSentError(\n String(err[\"message\"] ?? `POST ${path} failed (${res.status})`),\n { status: res.status },\n );\n }\n return data;\n}\n\nasync function doGet(\n t: V2Transport,\n path: string,\n params?: Record<string, string>,\n): Promise<Record<string, unknown>> {\n const f = pickFetch(t);\n const url = new URL(`${t.baseUrl}${path}`);\n if (params) {\n for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);\n }\n const res = await f(url.toString(), {\n method: \"GET\",\n headers: headers(t.apiKey),\n });\n const data = (await res.json()) as Record<string, unknown>;\n if (!res.ok) {\n const err = (data[\"error\"] as Record<string, unknown>) ?? {};\n throw new AtlaSentError(\n String(err[\"message\"] ?? `GET ${path} failed (${res.status})`),\n { status: res.status },\n );\n }\n return data;\n}\n\nasync function doDelete(\n t: V2Transport,\n path: string,\n body: unknown,\n): Promise<void> {\n const f = pickFetch(t);\n const res = await f(`${t.baseUrl}${path}`, {\n method: \"DELETE\",\n headers: headers(t.apiKey),\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n const data = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n const err = (data[\"error\"] as Record<string, unknown>) ?? {};\n throw new AtlaSentError(\n String(err[\"message\"] ?? `DELETE ${path} failed (${res.status})`),\n { status: res.status },\n );\n }\n}\n\n// ── Client ────────────────────────────────────────────────────────────────────\n\n/** Runtime v2 client — four-plane authorized-state-change lifecycle. */\nexport class RuntimeV2Client {\n constructor(private readonly transport: V2Transport) {}\n\n // ── Control plane ────────────────────────────────────────────────────────────\n\n /** `POST /v2/orgs/:orgId/transitions` */\n async authorize(\n orgId: string,\n request: Record<string, unknown>,\n ): Promise<AuthorizationDecision> {\n const data = await doPost(this.transport, orgPath(orgId, \"transitions\"), request);\n const permit = data[\"permit\"] as Record<string, unknown> | undefined;\n const code = data[\"code\"] as string | undefined;\n const message = data[\"message\"] as string | undefined;\n return {\n status: data[\"status\"] as AuthorizationDecision[\"status\"],\n ...(permit !== undefined ? { permit } : {}),\n required_approvers: (data[\"required_approvers\"] as string[] | undefined) ?? [],\n reasons: (data[\"reasons\"] as string[] | undefined) ?? [],\n policy_ids: (data[\"policy_ids\"] as string[] | undefined) ?? [],\n ...(code !== undefined ? { code } : {}),\n ...(message !== undefined ? { message } : {}),\n };\n }\n\n // ── Permit plane ─────────────────────────────────────────────────────────────\n\n /** `GET /v2/orgs/:orgId/permits/:permitId` */\n async getPermit(\n orgId: string,\n permitId: string,\n ): Promise<Record<string, unknown> | null> {\n const data = await doGet(this.transport, orgPath(orgId, \"permits\", permitId));\n return (data[\"permit\"] as Record<string, unknown>) ?? null;\n }\n\n /** `POST /v2/orgs/:orgId/permits/:permitId/consume` */\n async consume(\n orgId: string,\n permitId: string,\n observedSourceFingerprint: string,\n ): Promise<VerificationResult> {\n const data = await doPost(\n this.transport,\n orgPath(orgId, \"permits\", permitId, \"consume\"),\n { observed_source_fingerprint: observedSourceFingerprint },\n );\n return {\n passed: Boolean(data[\"passed\"]),\n verified_at: String(data[\"verified_at\"] ?? \"\"),\n failures: ((data[\"failures\"] as VerificationFailure[]) ?? []),\n warnings: ((data[\"warnings\"] as Array<Record<string, unknown>>) ?? []),\n };\n }\n\n /** `POST /v2/orgs/:orgId/permits/:permitId/approve` */\n async approve(\n orgId: string,\n permitId: string,\n approverDid: string,\n signature: string,\n comment?: string,\n ): Promise<{ approved: boolean; status: string }> {\n const body: Record<string, unknown> = { approver_did: approverDid, signature };\n if (comment !== undefined) body[\"comment\"] = comment;\n const data = await doPost(\n this.transport,\n orgPath(orgId, \"permits\", permitId, \"approve\"),\n body,\n );\n return {\n approved: Boolean(data[\"approved\"]),\n status: String(data[\"status\"] ?? \"\"),\n };\n }\n\n /** `POST /v2/orgs/:orgId/permits/:permitId/complete` */\n async complete(\n orgId: string,\n permitId: string,\n evidenceId: string,\n observedPostFingerprint: string,\n ): Promise<PostExecutionResult> {\n const data = await doPost(\n this.transport,\n orgPath(orgId, \"permits\", permitId, \"complete\"),\n { evidence_id: evidenceId, observed_post_fingerprint: observedPostFingerprint },\n );\n const rd = data[\"receipt\"] as Record<string, unknown> | undefined;\n const receipt: ExecutionReceipt | undefined = rd\n ? {\n receipt_id: String(rd[\"receipt_id\"] ?? \"\"),\n permit_id: String(rd[\"permit_id\"] ?? \"\"),\n org_id: String(rd[\"org_id\"] ?? \"\"),\n issued_at: String(rd[\"issued_at\"] ?? \"\"),\n post_state_fingerprint: String(rd[\"post_state_fingerprint\"] ?? \"\"),\n evidence_id: String(rd[\"evidence_id\"] ?? \"\"),\n }\n : undefined;\n return {\n verified: Boolean(data[\"verified\"]),\n evidence_completeness: (data[\"evidence_completeness\"] as PostExecutionResult[\"evidence_completeness\"]) ?? \"FAILED\",\n failures: ((data[\"failures\"] as VerificationFailure[]) ?? []),\n ...(receipt !== undefined ? { receipt } : {}),\n };\n }\n\n /** `DELETE /v2/orgs/:orgId/permits/:permitId` */\n async revokePermit(\n orgId: string,\n permitId: string,\n revokedBy: string,\n reason: string,\n propagatesToChildren = false,\n ): Promise<void> {\n await doDelete(\n this.transport,\n orgPath(orgId, \"permits\", permitId),\n { revoked_by: revokedBy, reason, propagates_to_children: propagatesToChildren },\n );\n }\n\n // ── Authority plane ──────────────────────────────────────────────────────────\n\n /** `GET /v2/orgs/:orgId/authorities` */\n async listAuthorities(\n orgId: string,\n includeInactive = false,\n ): Promise<AuthorityRecord[]> {\n const params: Record<string, string> = {};\n if (includeInactive) params[\"include_inactive\"] = \"true\";\n const data = await doGet(this.transport, orgPath(orgId, \"authorities\"), params);\n return (data[\"authorities\"] as AuthorityRecord[]) ?? [];\n }\n\n /** `POST /v2/orgs/:orgId/authorities` */\n async createAuthority(\n orgId: string,\n record: Record<string, unknown>,\n ): Promise<AuthorityRecord> {\n const data = await doPost(this.transport, orgPath(orgId, \"authorities\"), record);\n return (data[\"authority\"] ?? data) as AuthorityRecord;\n }\n\n /** `GET /v2/orgs/:orgId/authorities/:authorityId` */\n async getAuthority(\n orgId: string,\n authorityId: string,\n ): Promise<AuthorityRecord | null> {\n const data = await doGet(this.transport, orgPath(orgId, \"authorities\", authorityId));\n return (data[\"authority\"] as AuthorityRecord) ?? null;\n }\n\n /** `POST /v2/orgs/:orgId/authorities/:authorityId/rotate` */\n async rotateAuthority(\n orgId: string,\n authorityId: string,\n newPublicKey: string,\n newKeyId: string,\n ): Promise<AuthorityRecord> {\n const data = await doPost(\n this.transport,\n orgPath(orgId, \"authorities\", authorityId, \"rotate\"),\n { new_public_key: newPublicKey, new_key_id: newKeyId },\n );\n return (data[\"authority\"] ?? data) as AuthorityRecord;\n }\n\n /** `POST /v2/orgs/:orgId/authorities/:authorityId/revoke` */\n async revokeAuthority(\n orgId: string,\n authorityId: string,\n reason: string,\n ): Promise<void> {\n await doPost(\n this.transport,\n orgPath(orgId, \"authorities\", authorityId, \"revoke\"),\n { reason },\n );\n }\n\n // ── Evidence plane ───────────────────────────────────────────────────────────\n\n /** `POST /v2/orgs/:orgId/evidence` */\n async submitEvidence(\n orgId: string,\n pkg: Record<string, unknown>,\n ): Promise<void> {\n await doPost(this.transport, orgPath(orgId, \"evidence\"), pkg);\n }\n\n /** `GET /v2/orgs/:orgId/evidence/:evidenceId` */\n async getEvidence(\n orgId: string,\n evidenceId: string,\n ): Promise<Record<string, unknown> | null> {\n const data = await doGet(\n this.transport,\n orgPath(orgId, \"evidence\", evidenceId),\n );\n return (data[\"evidence\"] as Record<string, unknown>) ?? null;\n }\n\n /** `GET /v2/orgs/:orgId/audit-chain` */\n async queryAuditChain(\n orgId: string,\n from: string,\n to: string,\n options?: AuditChainFilters & { page?: number; page_size?: number },\n ): Promise<AuditChainPage> {\n const params: Record<string, string> = { from, to };\n if (options?.page !== undefined) params[\"page\"] = String(options.page);\n if (options?.page_size !== undefined) params[\"page_size\"] = String(options.page_size);\n if (options?.action_class) params[\"action_class\"] = options.action_class;\n if (options?.principal_did) params[\"principal_did\"] = options.principal_did;\n if (options?.resource_locator) params[\"resource_locator\"] = options.resource_locator;\n const data = await doGet(this.transport, orgPath(orgId, \"audit-chain\"), params);\n return {\n entries: (data[\"entries\"] as RuntimeAuditEntry[]) ?? [],\n total: Number(data[\"total\"] ?? 0),\n page: Number(data[\"page\"] ?? 1),\n page_size: Number(data[\"page_size\"] ?? 100),\n };\n }\n\n /** `GET /v2/orgs/:orgId/audit-chain/integrity` */\n async verifyChainIntegrity(\n orgId: string,\n fromSequence: number,\n toSequence: number,\n ): Promise<ChainIntegrityReport> {\n const data = await doGet(\n this.transport,\n orgPath(orgId, \"audit-chain\", \"integrity\"),\n { from_sequence: String(fromSequence), to_sequence: String(toSequence) },\n );\n return {\n valid: Boolean(data[\"valid\"]),\n checked_entries: Number(data[\"checked_entries\"] ?? 0),\n first_sequence: Number(data[\"first_sequence\"] ?? fromSequence),\n last_sequence: Number(data[\"last_sequence\"] ?? toSequence),\n gaps: (data[\"gaps\"] as number[]) ?? [],\n invalid_hashes: (data[\"invalid_hashes\"] as number[]) ?? [],\n verified_at: String(data[\"verified_at\"] ?? \"\"),\n };\n }\n\n /** `POST /v2/orgs/:orgId/compliance-export` */\n async exportCompliance(\n orgId: string,\n from: string,\n to: string,\n format: \"JSON\" | \"CSV\" | \"CISA_SBOM\" = \"JSON\",\n ): Promise<ComplianceExport> {\n const data = await doPost(\n this.transport,\n orgPath(orgId, \"compliance-export\"),\n { from, to, format },\n );\n return {\n export_id: String(data[\"export_id\"] ?? \"\"),\n org_id: String(data[\"org_id\"] ?? orgId),\n from: String(data[\"from\"] ?? from),\n to: String(data[\"to\"] ?? to),\n entry_count: Number(data[\"entry_count\"] ?? 0),\n format: String(data[\"format\"] ?? format),\n content_ref: String(data[\"content_ref\"] ?? \"\"),\n content_hash: String(data[\"content_hash\"] ?? \"\"),\n generated_at: String(data[\"generated_at\"] ?? \"\"),\n signed_by: String(data[\"signed_by\"] ?? \"\"),\n };\n }\n}\n","export type EnforcementMode = \"observe\" | \"warn\" | \"enforce\";\n\nexport interface HealthReport {\n readonly healthy: boolean;\n readonly apiReachable: boolean;\n readonly authenticated: boolean;\n readonly latencyMs: number | null;\n readonly apiVersion: string | null;\n readonly checkedAt: string;\n readonly errors: string[];\n}\n\nexport interface EnforcementStatus {\n readonly actionClass: string;\n readonly mode: EnforcementMode;\n readonly blockRate: number | null;\n readonly totalEvaluations: number | null;\n readonly lastSeenAt: string | null;\n readonly schemaRegistered: boolean;\n}\n\nexport interface ProtectedActionEntry {\n readonly actionClass: string;\n readonly firstRegisteredAt: string;\n readonly lastUpdatedAt: string;\n readonly enforcementMode: EnforcementMode;\n readonly schemaId: string | null;\n readonly tags: string[];\n}\n\nexport interface OrgSummary {\n readonly orgId: string;\n readonly activePolicies: number;\n readonly totalPolicies: number;\n readonly activeOverrides: number;\n readonly pendingEscalations: number;\n readonly evidenceSigningEnabled: boolean;\n readonly shadowModeActions: number;\n readonly enforcedActions: number;\n readonly lastEvaluationAt: string | null;\n}\n\nexport interface ControlSurfaceConfig {\n apiKey?: string;\n baseUrl?: string;\n timeoutMs?: number;\n}\n\nlet _config: ControlSurfaceConfig = {};\n\nexport function configureControlSurface(config: ControlSurfaceConfig): void {\n _config = { ..._config, ...config };\n}\n\nfunction resolveConfig(opts?: ControlSurfaceConfig): Required<ControlSurfaceConfig> {\n return {\n apiKey: opts?.apiKey ?? _config.apiKey ?? process.env[\"ATLASENT_API_KEY\"] ?? \"\",\n baseUrl: opts?.baseUrl ?? _config.baseUrl ?? process.env[\"ATLASENT_BASE_URL\"] ?? \"https://api.atlasent.ai\",\n timeoutMs: opts?.timeoutMs ?? _config.timeoutMs ?? 10_000,\n };\n}\n\nasync function apiGet<T>(\n path: string,\n config: Required<ControlSurfaceConfig>,\n): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), config.timeoutMs);\n try {\n const res = await fetch(`${config.baseUrl}${path}`, {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${config.apiKey}`,\n Accept: \"application/json\",\n },\n signal: controller.signal,\n });\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}`);\n }\n return res.json() as Promise<T>;\n } finally {\n clearTimeout(timer);\n }\n}\n\nasync function apiPost<T>(\n path: string,\n body: unknown,\n config: Required<ControlSurfaceConfig>,\n): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), config.timeoutMs);\n try {\n const res = await fetch(`${config.baseUrl}${path}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${config.apiKey}`,\n },\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}`);\n }\n return res.json() as Promise<T>;\n } finally {\n clearTimeout(timer);\n }\n}\n\nexport async function checkIntegrationHealth(\n opts?: ControlSurfaceConfig,\n): Promise<HealthReport> {\n const config = resolveConfig(opts);\n const errors: string[] = [];\n let apiReachable = false;\n let authenticated = false;\n let latencyMs: number | null = null;\n let apiVersion: string | null = null;\n\n if (!config.apiKey) {\n errors.push(\"ATLASENT_API_KEY is not configured\");\n }\n\n const start = Date.now();\n try {\n const data = await apiGet<{ version?: string; status?: string }>(\"/v1/health\", config);\n latencyMs = Date.now() - start;\n apiReachable = true;\n apiVersion = data.version ?? null;\n if (data.status === \"ok\" || data.status === \"healthy\") {\n authenticated = true;\n } else {\n errors.push(`API health status: ${data.status ?? \"unknown\"}`);\n }\n } catch (err) {\n latencyMs = Date.now() - start;\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes(\"401\") || message.includes(\"403\")) {\n apiReachable = true;\n errors.push(\"API key is invalid or lacks required permissions\");\n } else {\n errors.push(`API unreachable: ${message}`);\n }\n }\n\n return {\n healthy: apiReachable && authenticated && errors.length === 0,\n apiReachable,\n authenticated,\n latencyMs,\n apiVersion,\n checkedAt: new Date().toISOString(),\n errors,\n };\n}\n\nexport interface ReportProtectedActionOptions extends ControlSurfaceConfig {\n actionClass: string;\n enforcementMode?: EnforcementMode;\n schemaId?: string;\n tags?: string[];\n}\n\nexport async function reportProtectedAction(\n opts: ReportProtectedActionOptions,\n): Promise<ProtectedActionEntry> {\n const config = resolveConfig(opts);\n return apiPost<ProtectedActionEntry>(\n \"/v1/control-surface/actions\",\n {\n action_class: opts.actionClass,\n enforcement_mode: opts.enforcementMode ?? \"observe\",\n schema_id: opts.schemaId ?? null,\n tags: opts.tags ?? [],\n },\n config,\n );\n}\n\nexport interface GetEnforcementStatusOptions extends ControlSurfaceConfig {\n actionClass: string;\n}\n\nexport async function getEnforcementStatus(\n opts: GetEnforcementStatusOptions,\n): Promise<EnforcementStatus> {\n const config = resolveConfig(opts);\n return apiGet<EnforcementStatus>(\n `/v1/control-surface/actions/${encodeURIComponent(opts.actionClass)}/status`,\n config,\n );\n}\n\nexport async function getOrgSummary(\n opts?: ControlSurfaceConfig,\n): Promise<OrgSummary> {\n const config = resolveConfig(opts);\n return apiGet<OrgSummary>(\"/v1/control-surface/summary\", config);\n}\n","/**\n * Claims → Evidence Lineage\n *\n * Builds and verifies {@link ClaimEvidenceLink} objects — signed, wire-stable\n * artifacts that tie a canonical claim row to its full evidence chain:\n *\n * 1. **`runtime_evidence`** — {@link DecisionReceipt} from `protectWithEvidence()`\n * 2. **`deploy_evidence`** — `protectDeploy()` gate record\n * 3. **`integration_evidence`** — `ComplianceEvidenceRun` summary\n * 4. **`approval_artifact`** — HITL chain or ApprovalArtifact summary\n * 5. **`delta`** — policy + schema drift since the claim was asserted\n * 6. **`verification_checklist`** — machine-auditable `all_pass` + per-slot status\n *\n * Wire schema: `contract/schemas/claim-evidence-link.schema.json`\n * Proposal: `contract/PROPOSALS/004-claims-evidence-links.md`\n *\n * @module\n */\n\nimport { createHmac, randomUUID } from \"node:crypto\";\nimport type { DecisionReceipt, DecisionReceiptAlgorithm } from \"./evidenceEngine.js\";\nimport type { ComplianceEvidenceRun } from \"./complianceEvidence.js\";\nimport type { HitlEscalation, HitlApprovalRecord } from \"./hitl.js\";\nimport { AtlaSentError } from \"./errors.js\";\n\n// ── Evidence slot wire types ──────────────────────────────────────────────────\n\nexport interface RuntimeEvidenceSlot {\n readonly permit_token: string;\n readonly audit_hash: string;\n readonly decision: \"allow\" | \"deny\" | \"escalate\";\n readonly decision_id: string;\n readonly evaluated_at: string;\n readonly algorithm: DecisionReceiptAlgorithm;\n readonly signature: string | null;\n readonly permit_revoked_at: string | null;\n readonly verified_at_claim_time: boolean;\n readonly verified_at_link_creation: boolean;\n}\n\nexport interface DeployEvidenceSlot {\n readonly deploy_id: string;\n readonly environment: string;\n readonly sha: string;\n readonly actor_id: string;\n readonly deployed_at: string;\n readonly gate_permit_token: string;\n}\n\nexport interface IntegrationEvidenceSlot {\n readonly run_id: string;\n readonly framework: \"soc2\" | \"iso27001\" | \"hipaa\" | \"pci_dss\" | \"gdpr\" | \"fedramp\";\n readonly period_start: string;\n readonly period_end: string;\n readonly status: \"pending\" | \"running\" | \"completed\" | \"failed\";\n readonly passing_control_count: number;\n readonly failing_control_count: number;\n readonly run_completed_at: string;\n}\n\nexport interface ApprovalArtifactSlot {\n readonly approval_id: string;\n readonly approval_kind: \"hitl_chain\" | \"approval_artifact\";\n readonly quorum_type: \"single_approver\" | \"simple_majority\" | \"two_thirds\" | \"unanimous\";\n readonly approver_count: number;\n readonly approver_ids: readonly string[];\n readonly approved_at: string;\n readonly artifact_hash: string;\n}\n\nexport type DriftChangeType =\n | \"rule_added\"\n | \"rule_removed\"\n | \"rule_modified\"\n | \"threshold_changed\"\n | \"policy_updated\"\n | \"schema_field_added\"\n | \"schema_field_removed\"\n | \"schema_field_type_changed\";\n\nexport type DriftSeverity = \"info\" | \"warning\" | \"critical\";\n\nexport interface DriftDetail {\n readonly change_type: DriftChangeType;\n readonly severity: DriftSeverity;\n readonly rule_id: string | null;\n readonly changed_at: string | null;\n readonly description: string;\n}\n\nexport type DeltaStatus = \"pending\" | \"computing\" | \"computed\" | \"failed\";\n\nexport interface DeltaSlot {\n readonly status: DeltaStatus;\n readonly computed_at: string | null;\n readonly policy_version_at_claim: string | null;\n readonly policy_version_current: string | null;\n readonly policy_drift_detected: boolean | null;\n readonly schema_version_at_claim: string;\n readonly schema_version_current: string;\n readonly schema_drift_detected: boolean;\n readonly drift_details: readonly DriftDetail[];\n}\n\nexport type EvidenceSlotStatus = \"present\" | \"not_applicable\" | \"missing\";\n\nexport interface VerificationChecklist {\n readonly runtime_evidence_present: boolean;\n readonly verified_at_claim_time: boolean;\n readonly verified_at_link_creation: boolean;\n readonly deploy_evidence_status: EvidenceSlotStatus;\n readonly integration_evidence_status: EvidenceSlotStatus;\n readonly approval_artifact_status: EvidenceSlotStatus;\n readonly delta_computed: boolean;\n readonly policy_drift_clean: boolean | null;\n readonly schema_drift_clean: boolean;\n readonly all_pass: boolean;\n readonly last_verified_at: string | null;\n readonly computed_at: string;\n}\n\nexport interface ClaimEvidenceLink {\n readonly version: \"claim_evidence_link.v1\";\n readonly link_id: string;\n readonly claim_id: string;\n readonly org_id: string;\n readonly linked_at: string;\n readonly updated_at: string;\n readonly revision: number;\n readonly link_algorithm: \"hmac-sha256\" | \"none\";\n readonly link_hash: string;\n readonly link_signature: string | null;\n readonly runtime_evidence: RuntimeEvidenceSlot;\n readonly deploy_evidence: DeployEvidenceSlot | null;\n readonly integration_evidence: IntegrationEvidenceSlot | null;\n readonly approval_artifact: ApprovalArtifactSlot | null;\n readonly delta: DeltaSlot;\n readonly verification_checklist: VerificationChecklist;\n}\n\n// ── Slot input types ──────────────────────────────────────────────────────────\n\n/** Caller signals evidence does not apply to this claim. */\nexport interface NotApplicable {\n readonly notApplicable: true;\n}\n\nexport const NOT_APPLICABLE: NotApplicable = { notApplicable: true };\n\nfunction isNotApplicable(v: unknown): v is NotApplicable {\n return typeof v === \"object\" && v !== null && (v as NotApplicable).notApplicable === true;\n}\n\n/** Raw deploy gate inputs — caller supplies at minimum environment + service. */\nexport interface DeployEvidenceInput {\n readonly deploy_id: string;\n readonly environment: string;\n readonly sha: string;\n readonly actor_id: string;\n readonly deployed_at: string;\n readonly gate_permit_token: string;\n}\n\n/** Summary from a HITL chain (derived from HitlEscalation + approval records). */\nexport interface HitlChainSummary {\n readonly escalation: HitlEscalation;\n readonly approvals: readonly HitlApprovalRecord[];\n /** SHA-256 hex of the canonical JSON of the full chain object. */\n readonly artifact_hash: string;\n}\n\n/** Out-of-band approval artifact (pre-signed). */\nexport interface SignedApprovalArtifact {\n readonly approval_id: string;\n readonly approval_kind: \"approval_artifact\";\n readonly quorum_type: \"single_approver\" | \"simple_majority\" | \"two_thirds\" | \"unanimous\";\n readonly approver_ids: readonly string[];\n readonly approved_at: string;\n /** SHA-256 hex of the canonical encoding of the full artifact. */\n readonly artifact_hash: string;\n}\n\nexport interface BuildClaimEvidenceLinkOpts {\n /** The canonical claim ID this link annotates. */\n readonly claimId: string;\n /**\n * The org that owns the claim. Defaults to `receipt.org_id` from\n * `runtimeEvidence` when omitted.\n */\n readonly orgId?: string;\n /** DecisionReceipt from `protectWithEvidence()`. Required. */\n readonly runtimeEvidence: DecisionReceipt;\n /**\n * Deploy gate record. Pass `NOT_APPLICABLE` for non-deployment actions.\n * Omit (or pass `undefined`) when the deploy record was expected but\n * unavailable — the slot status will be `\"missing\"` and `all_pass`\n * will be `false`.\n */\n readonly deployEvidence?: DeployEvidenceInput | NotApplicable;\n /**\n * Most recent compliance run covering the claim period. Pass\n * `NOT_APPLICABLE` when no compliance run applies.\n */\n readonly integrationEvidence?: ComplianceEvidenceRun | NotApplicable;\n /**\n * HITL chain summary or out-of-band approval artifact. Pass\n * `NOT_APPLICABLE` when no human approval was required.\n */\n readonly approvalArtifact?: HitlChainSummary | SignedApprovalArtifact | NotApplicable;\n /**\n * HMAC-SHA256 signing secret. When provided the link is signed and\n * `link_algorithm` is `\"hmac-sha256\"`. Omit for unsigned links\n * (`link_algorithm: \"none\"`).\n */\n readonly signingSecret?: string;\n /**\n * Override the schema version recorded in `delta.schema_version_at_claim`.\n * Defaults to the SDK package version embedded at build time.\n */\n readonly schemaVersion?: string;\n}\n\nexport interface VerifyClaimEvidenceLinkOpts {\n /**\n * Signing secret used to re-verify `link_signature`. Required when\n * `link.link_algorithm` is `\"hmac-sha256\"`.\n */\n readonly signingSecret?: string;\n /**\n * When true, skips re-calling `/v1-verify-permit` even if a client is\n * provided. Useful when the permit is known to be expired and you only\n * want to check structural integrity.\n */\n readonly skipPermitRecheck?: boolean;\n}\n\nexport interface VerifyClaimEvidenceLinkResult {\n /** Updated link with refreshed checklist, incremented revision, and recomputed hash. */\n readonly link: ClaimEvidenceLink;\n readonly valid: boolean;\n /** Names of verification_checklist fields that are false or \"missing\". */\n readonly failedSlots: readonly string[];\n}\n\n// ── Action bundle input types ─────────────────────────────────────────────────\n\n/**\n * Subset of an `ActionEvidenceBundle.receipt` produced by the AtlaSent\n * GitHub Action (atlasent-action `evidenceBundle.ts`).\n *\n * Only the fields consumed by {@link buildClaimEvidenceLinkFromActionBundle}\n * are required here; the full receipt shape lives in the action repo.\n */\nexport interface ActionBundleReceipt {\n readonly receipt_id: string;\n readonly evaluation_id: string;\n readonly permit_id: string | null;\n readonly audit_hash: string | null;\n readonly issued_at: string;\n readonly algorithm: \"hmac-sha256\" | \"none\";\n readonly signature: string | null;\n readonly decision: \"allow\";\n}\n\n/**\n * Minimal shape of an `ActionEvidenceBundle` emitted by the AtlaSent\n * GitHub Action as its `evidence-bundle` output. Pass the parsed JSON\n * directly; no re-shaping needed.\n */\nexport interface ActionBundleInput {\n readonly bundle_id: string;\n readonly action: string;\n readonly actor: string;\n readonly environment: string;\n readonly repository: string;\n readonly sha: string;\n readonly run_id: string;\n readonly generated_at: string;\n readonly receipt: ActionBundleReceipt;\n}\n\nexport interface BuildFromActionBundleOpts {\n /** The canonical claim ID this link annotates. */\n readonly claimId: string;\n /** Owning org. Defaults to `\"\"` for v1 (no org context on the action). */\n readonly orgId?: string;\n /**\n * Set to `true` when the bundle does NOT represent a deploy action.\n * The deploy slot will be `NOT_APPLICABLE` instead of auto-populated\n * from `bundle.sha` / `bundle.environment`.\n */\n readonly deployNotApplicable?: boolean;\n readonly signingSecret?: string;\n readonly schemaVersion?: string;\n}\n\n// ── SDK version ───────────────────────────────────────────────────────────────\n\nconst SDK_VERSION = \"@atlasent/sdk@1.4.2\";\n\n// ── Canonical serialisation ───────────────────────────────────────────────────\n\nfunction canonicalize(value: unknown): string {\n if (value === null || value === undefined) return \"null\";\n if (typeof value === \"number\") return Number.isFinite(value) ? String(value) : \"null\";\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n if (typeof value === \"string\") return JSON.stringify(value);\n if (Array.isArray(value)) return \"[\" + value.map(canonicalize).join(\",\") + \"]\";\n if (typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n return \"{\" + keys.map((k) => JSON.stringify(k) + \":\" + canonicalize(obj[k])).join(\",\") + \"}\";\n }\n return \"null\";\n}\n\nfunction sha256Hex(input: string): string {\n const { createHash } = require(\"node:crypto\") as typeof import(\"node:crypto\");\n return createHash(\"sha256\").update(input).digest(\"hex\");\n}\n\nfunction hmacSha256Base64url(payload: string, secret: string): string {\n return createHmac(\"sha256\", secret)\n .update(payload)\n .digest(\"base64url\");\n}\n\nfunction computeLinkHash(link: Omit<ClaimEvidenceLink, \"link_hash\" | \"link_signature\">): string {\n return sha256Hex(canonicalize(link));\n}\n\n// ── Slot converters ───────────────────────────────────────────────────────────\n\nfunction slotStatus(\n input: unknown | NotApplicable | undefined,\n slot: DeployEvidenceSlot | IntegrationEvidenceSlot | ApprovalArtifactSlot | null,\n): EvidenceSlotStatus {\n if (isNotApplicable(input)) return \"not_applicable\";\n if (slot !== null) return \"present\";\n return \"missing\";\n}\n\nfunction toDeploySlot(input: DeployEvidenceInput | NotApplicable | undefined): DeployEvidenceSlot | null {\n if (input === undefined || isNotApplicable(input)) return null;\n return {\n deploy_id: input.deploy_id,\n environment: input.environment,\n sha: input.sha,\n actor_id: input.actor_id,\n deployed_at: input.deployed_at,\n gate_permit_token: input.gate_permit_token,\n };\n}\n\nfunction toIntegrationSlot(\n input: ComplianceEvidenceRun | NotApplicable | undefined,\n): IntegrationEvidenceSlot | null {\n if (input === undefined || isNotApplicable(input)) return null;\n const run = input as ComplianceEvidenceRun;\n return {\n run_id: run.id,\n framework: run.framework as IntegrationEvidenceSlot[\"framework\"],\n period_start: run.period_start,\n period_end: run.period_end,\n status: run.status as IntegrationEvidenceSlot[\"status\"],\n passing_control_count: (run.controls ?? []).filter((c) => c.status === \"pass\").length,\n failing_control_count: (run.controls ?? []).filter((c) => c.status !== \"pass\").length,\n run_completed_at: run.created_at,\n };\n}\n\nfunction toApprovalSlot(\n input: HitlChainSummary | SignedApprovalArtifact | NotApplicable | undefined,\n): ApprovalArtifactSlot | null {\n if (input === undefined || isNotApplicable(input)) return null;\n\n if (\"escalation\" in input) {\n const chain = input as HitlChainSummary;\n const approvals = chain.approvals;\n const lastApproved = approvals\n .filter((a) => a.decision === \"approve\")\n .map((a) => a.created_at)\n .sort()\n .at(-1) ?? chain.escalation.created_at;\n return {\n approval_id: chain.escalation.id,\n approval_kind: \"hitl_chain\",\n quorum_type: hitlQuorumToSlotQuorum(chain.escalation.quorum_required),\n approver_count: approvals.filter((a) => a.decision === \"approve\").length,\n approver_ids: approvals\n .filter((a) => a.decision === \"approve\")\n .map((a) => a.user_id ?? a.actor_label ?? \"unknown\"),\n approved_at: lastApproved,\n artifact_hash: chain.artifact_hash,\n };\n }\n\n const artifact = input as SignedApprovalArtifact;\n return {\n approval_id: artifact.approval_id,\n approval_kind: \"approval_artifact\",\n quorum_type: artifact.quorum_type,\n approver_count: artifact.approver_ids.length,\n approver_ids: artifact.approver_ids,\n approved_at: artifact.approved_at,\n artifact_hash: artifact.artifact_hash,\n };\n}\n\nfunction hitlQuorumToSlotQuorum(\n tier: string,\n): ApprovalArtifactSlot[\"quorum_type\"] {\n switch (tier) {\n case \"single_approver\": return \"single_approver\";\n case \"two_thirds\": return \"two_thirds\";\n case \"unanimous\": return \"unanimous\";\n default: return \"simple_majority\";\n }\n}\n\nfunction toRuntimeSlot(receipt: DecisionReceipt, verifiedAtCreation: boolean): RuntimeEvidenceSlot {\n return {\n permit_token: receipt.permit_id ?? receipt.receipt_id,\n audit_hash: receipt.audit_hash,\n decision: receipt.decision === \"allow\" ? \"allow\"\n : receipt.decision === \"escalate\" ? \"escalate\"\n : \"deny\",\n decision_id: receipt.evaluation_id,\n evaluated_at: receipt.issued_at,\n algorithm: receipt.algorithm,\n signature: receipt.signature,\n permit_revoked_at: null,\n verified_at_claim_time: receipt.decision === \"allow\",\n verified_at_link_creation: verifiedAtCreation,\n };\n}\n\n// ── Checklist builder ─────────────────────────────────────────────────────────\n\nfunction buildChecklist(\n runtime: RuntimeEvidenceSlot,\n deployStatus: EvidenceSlotStatus,\n integrationStatus: EvidenceSlotStatus,\n approvalStatus: EvidenceSlotStatus,\n delta: DeltaSlot,\n lastVerifiedAt: string | null,\n now: string,\n): VerificationChecklist {\n const deltaComputed = delta.status === \"computed\";\n const policyDriftClean = deltaComputed ? !delta.policy_drift_detected : null;\n const schemaDriftClean = !delta.schema_drift_detected;\n\n const allPass =\n runtime.verified_at_claim_time &&\n runtime.verified_at_link_creation &&\n deltaComputed &&\n policyDriftClean === true &&\n schemaDriftClean &&\n deployStatus !== \"missing\" &&\n integrationStatus !== \"missing\" &&\n approvalStatus !== \"missing\";\n\n return {\n runtime_evidence_present: true,\n verified_at_claim_time: runtime.verified_at_claim_time,\n verified_at_link_creation: runtime.verified_at_link_creation,\n deploy_evidence_status: deployStatus,\n integration_evidence_status: integrationStatus,\n approval_artifact_status: approvalStatus,\n delta_computed: deltaComputed,\n policy_drift_clean: policyDriftClean,\n schema_drift_clean: schemaDriftClean,\n all_pass: allPass,\n last_verified_at: lastVerifiedAt,\n computed_at: now,\n };\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Assemble a {@link ClaimEvidenceLink} from already-fetched SDK artifacts.\n *\n * - Generates a client-side `link_id` (`cel_` + UUID v4).\n * - Computes schema drift from the SDK version; policy drift is set to\n * `delta.status: \"pending\"` (server-side, async).\n * - Signs the link with HMAC-SHA256 when `signingSecret` is provided.\n * - `verified_at_link_creation` is set to `true` when the receipt carries a\n * `decision === \"allow\"` (the permit was valid at the moment we're building\n * the link, since it was just produced by `protectWithEvidence()`).\n *\n * The returned link has `revision: 1`. Subsequent calls to\n * {@link verifyClaimEvidenceLink} increment `revision` and recompute\n * `link_hash` / `link_signature`.\n */\nexport function buildClaimEvidenceLink(opts: BuildClaimEvidenceLinkOpts): ClaimEvidenceLink {\n const now = new Date().toISOString();\n const linkId = `cel_${randomUUID().replace(/-/g, \"\")}`;\n const orgId = opts.orgId ?? opts.runtimeEvidence.org_id;\n const schemaVersion = opts.schemaVersion ?? SDK_VERSION;\n\n const deploySlot = toDeploySlot(opts.deployEvidence);\n const integrationSlot = toIntegrationSlot(opts.integrationEvidence);\n const approvalSlot = toApprovalSlot(opts.approvalArtifact);\n\n const deployStatus = slotStatus(opts.deployEvidence, deploySlot);\n const integrationStatus = slotStatus(opts.integrationEvidence, integrationSlot);\n const approvalStatus = slotStatus(opts.approvalArtifact, approvalSlot);\n\n // verified_at_link_creation: true only if the decision was allow (permit is fresh)\n const verifiedAtCreation = opts.runtimeEvidence.decision === \"allow\";\n const runtime = toRuntimeSlot(opts.runtimeEvidence, verifiedAtCreation);\n\n const delta: DeltaSlot = {\n status: \"pending\",\n computed_at: null,\n policy_version_at_claim: null,\n policy_version_current: null,\n policy_drift_detected: null,\n schema_version_at_claim: schemaVersion,\n schema_version_current: schemaVersion,\n schema_drift_detected: false,\n drift_details: [],\n };\n\n const lastVerifiedAt = verifiedAtCreation ? now : null;\n const checklist = buildChecklist(\n runtime, deployStatus, integrationStatus, approvalStatus, delta, lastVerifiedAt, now,\n );\n\n const linkAlgorithm: ClaimEvidenceLink[\"link_algorithm\"] =\n opts.signingSecret ? \"hmac-sha256\" : \"none\";\n\n // Build the signable body (everything except link_hash + link_signature)\n const body = {\n version: \"claim_evidence_link.v1\" as const,\n link_id: linkId,\n claim_id: opts.claimId,\n org_id: orgId,\n linked_at: now,\n updated_at: now,\n revision: 1,\n link_algorithm: linkAlgorithm,\n runtime_evidence: runtime,\n deploy_evidence: deploySlot,\n integration_evidence: integrationSlot,\n approval_artifact: approvalSlot,\n delta,\n verification_checklist: checklist,\n };\n\n const linkHash = computeLinkHash(body);\n const linkSignature = opts.signingSecret\n ? hmacSha256Base64url(linkHash, opts.signingSecret)\n : null;\n\n return { ...body, link_hash: linkHash, link_signature: linkSignature };\n}\n\n/**\n * Verify the structural integrity and checklist freshness of a\n * {@link ClaimEvidenceLink}.\n *\n * Checks:\n * 1. `link_hash` matches a canonical re-serialisation of the link content.\n * 2. `link_signature` verifies under `link_algorithm` (when not `\"none\"`).\n * 3. Recomputes the `verification_checklist` from the current slot state.\n *\n * Returns a new `ClaimEvidenceLink` with:\n * - Updated `verified_at_link_creation` / `last_verified_at` (permit may have\n * expired since the link was built — reflected in the updated checklist).\n * - Incremented `revision`.\n * - Recomputed `link_hash` / `link_signature` over the mutated content.\n *\n * Does **not** mutate the input. Does **not** make network calls (permit\n * re-verification via `/v1-verify-permit` is scoped for v2 once the server\n * endpoint ships).\n *\n * @throws {@link AtlaSentError} with `code: \"claim_evidence_incomplete\"` when\n * `all_pass` is false on the refreshed checklist.\n */\nexport function verifyClaimEvidenceLink(\n link: ClaimEvidenceLink,\n opts: VerifyClaimEvidenceLinkOpts = {},\n): VerifyClaimEvidenceLinkResult {\n const now = new Date().toISOString();\n\n // 1. Verify link_hash\n const { link_hash: _lh, link_signature: _ls, ...body } = link as unknown as Record<string, unknown>;\n const expectedHash = computeLinkHash(\n body as Omit<ClaimEvidenceLink, \"link_hash\" | \"link_signature\">,\n );\n const hashValid = expectedHash === link.link_hash;\n\n // 2. Verify signature\n let sigValid = true;\n if (link.link_algorithm === \"hmac-sha256\") {\n if (!opts.signingSecret) {\n sigValid = false;\n } else {\n const expected = hmacSha256Base64url(link.link_hash, opts.signingSecret);\n sigValid = expected === link.link_signature;\n }\n }\n\n // 3. Recompute checklist (permit re-verification deferred to v2)\n const runtime: RuntimeEvidenceSlot = {\n ...link.runtime_evidence,\n // If the link hash or signature is invalid, mark creation-time verification as failed\n verified_at_link_creation: hashValid && sigValid\n ? link.runtime_evidence.verified_at_link_creation\n : false,\n };\n\n const checklist = buildChecklist(\n runtime,\n link.verification_checklist.deploy_evidence_status,\n link.verification_checklist.integration_evidence_status,\n link.verification_checklist.approval_artifact_status,\n link.delta,\n runtime.verified_at_link_creation ? (link.verification_checklist.last_verified_at ?? now) : null,\n now,\n );\n\n // 4. Build updated link\n const updatedBody = {\n version: link.version,\n link_id: link.link_id,\n claim_id: link.claim_id,\n org_id: link.org_id,\n linked_at: link.linked_at,\n updated_at: now,\n revision: link.revision + 1,\n link_algorithm: link.link_algorithm,\n runtime_evidence: runtime,\n deploy_evidence: link.deploy_evidence,\n integration_evidence: link.integration_evidence,\n approval_artifact: link.approval_artifact,\n delta: link.delta,\n verification_checklist: checklist,\n };\n\n const newHash = computeLinkHash(updatedBody);\n const newSignature = opts.signingSecret\n ? hmacSha256Base64url(newHash, opts.signingSecret)\n : link.link_algorithm === \"none\" ? null : link.link_signature;\n\n const updatedLink: ClaimEvidenceLink = {\n ...updatedBody,\n link_hash: newHash,\n link_signature: newSignature,\n };\n\n // 5. Collect failed slots\n const failedSlots: string[] = [];\n if (!hashValid) failedSlots.push(\"link_hash\");\n if (!sigValid) failedSlots.push(\"link_signature\");\n if (!checklist.verified_at_claim_time) failedSlots.push(\"verified_at_claim_time\");\n if (!checklist.verified_at_link_creation) failedSlots.push(\"verified_at_link_creation\");\n if (!checklist.delta_computed) failedSlots.push(\"delta_computed\");\n if (checklist.policy_drift_clean === false) failedSlots.push(\"policy_drift_clean\");\n if (!checklist.schema_drift_clean) failedSlots.push(\"schema_drift_clean\");\n if (checklist.deploy_evidence_status === \"missing\") failedSlots.push(\"deploy_evidence_status\");\n if (checklist.integration_evidence_status === \"missing\") failedSlots.push(\"integration_evidence_status\");\n if (checklist.approval_artifact_status === \"missing\") failedSlots.push(\"approval_artifact_status\");\n\n const valid = failedSlots.length === 0;\n\n if (!valid) {\n throw new AtlaSentError(\n `ClaimEvidenceLink verification failed: ${failedSlots.join(\", \")}`,\n { code: \"claim_evidence_incomplete\" as never },\n );\n }\n\n return { link: updatedLink, valid, failedSlots };\n}\n\n/**\n * Build a {@link ClaimEvidenceLink} directly from the `evidence-bundle`\n * JSON emitted by the AtlaSent GitHub Action.\n *\n * ```ts\n * import { buildClaimEvidenceLinkFromActionBundle } from \"@atlasent/sdk\";\n *\n * const bundle = JSON.parse(process.env.ATLASENT_EVIDENCE_BUNDLE!);\n * const link = buildClaimEvidenceLinkFromActionBundle(bundle, {\n * claimId: myClaimId,\n * signingSecret: process.env.ATLASENT_SIGNING_SECRET,\n * });\n * ```\n *\n * The `receipt` fields map directly to the `runtime_evidence` slot. The\n * `bundle.sha` / `bundle.environment` / `bundle.actor` are used to\n * auto-populate the `deploy_evidence` slot — pass `deployNotApplicable: true`\n * to suppress this for non-deploy actions.\n */\nexport function buildClaimEvidenceLinkFromActionBundle(\n bundle: ActionBundleInput,\n opts: BuildFromActionBundleOpts,\n): ClaimEvidenceLink {\n const runtimeEvidence: DecisionReceipt = {\n receipt_id: bundle.receipt.receipt_id,\n evaluation_id: bundle.receipt.evaluation_id,\n org_id: opts.orgId ?? \"\",\n decision: bundle.receipt.decision as \"allow\",\n action: bundle.action,\n actor: bundle.actor,\n resource_type: null,\n resource_id: null,\n reasons: [],\n why_trace: null,\n permit_id: bundle.receipt.permit_id,\n permit_hash: null,\n audit_hash: bundle.receipt.audit_hash ?? \"\",\n context_hash: \"\",\n issued_at: bundle.receipt.issued_at,\n expires_at: null,\n algorithm: bundle.receipt.algorithm as DecisionReceiptAlgorithm,\n signature: bundle.receipt.signature,\n signing_key_id: null,\n payload: {\n receipt_id: bundle.receipt.receipt_id,\n evaluation_id: bundle.receipt.evaluation_id,\n org_id: opts.orgId ?? \"\",\n decision: bundle.receipt.decision as \"allow\",\n action: bundle.action,\n actor: bundle.actor,\n resource_type: null,\n resource_id: null,\n reasons: [],\n why_summary: \"\",\n permit_id: bundle.receipt.permit_id,\n permit_hash: null,\n audit_hash: bundle.receipt.audit_hash ?? \"\",\n context_hash: \"\",\n issued_at: bundle.receipt.issued_at,\n expires_at: null,\n },\n };\n\n const deployEvidence: DeployEvidenceInput | NotApplicable = opts.deployNotApplicable\n ? NOT_APPLICABLE\n : {\n deploy_id: bundle.bundle_id,\n environment: bundle.environment,\n sha: bundle.sha,\n actor_id: bundle.actor,\n deployed_at: bundle.generated_at,\n gate_permit_token: bundle.receipt.permit_id ?? bundle.receipt.receipt_id,\n };\n\n return buildClaimEvidenceLink({\n claimId: opts.claimId,\n ...(opts.orgId !== undefined ? { orgId: opts.orgId } : {}),\n runtimeEvidence,\n deployEvidence,\n ...(opts.signingSecret !== undefined ? { signingSecret: opts.signingSecret } : {}),\n ...(opts.schemaVersion !== undefined ? { schemaVersion: opts.schemaVersion } : {}),\n });\n}\n","/**\n * BCCAE V1 — TypeScript client.\n *\n * BCCAEClient wraps the four BCCAE Phase 3 endpoints:\n * evaluate → POST /v1/bccae/evaluations (bccae:evaluate scope)\n * execute → POST /v1/bccae/execute (bccae:execute scope)\n * revoke → POST /v1/bccae/revocations (bccae:revoke scope)\n * getEvidence → GET /v1/bccae/evidence/:id (bccae:audit scope)\n *\n * Spec: atlasent-internal/architecture/BCCAE-architecture.md\n * Phase 3 — Execution Assurance. Not a Deploy Gate V1 customer API.\n */\n\nimport { AtlaSentError } from \"./errors.js\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type BccaeActorType = \"HUMAN\" | \"AGENT\" | \"SERVICE\" | \"EXTERNAL\";\nexport type BccaeTrustLevel = \"L0\" | \"L1\" | \"L2\" | \"L3\";\nexport type BccaeResourceClassification =\n | \"PUBLIC\"\n | \"INTERNAL\"\n | \"CONFIDENTIAL\"\n | \"RESTRICTED\";\nexport type BccaeDeploymentEnv = \"PROD\" | \"STAGING\" | \"DEV\" | \"TEST\";\nexport type BccaeSecurityPosture = \"STANDARD\" | \"ELEVATED\" | \"LOCKED\";\nexport type BccaeRequestSource =\n | \"AGENT\"\n | \"API\"\n | \"INTERNAL\"\n | \"SCHEDULED\"\n | \"TRIGGERED\";\nexport type BccaeRevocationTargetType =\n | \"PERMIT\"\n | \"EVALUATION\"\n | \"ACTOR\"\n | \"RESOURCE\";\n\nexport interface BccaeEvaluateInput {\n actor_id: string;\n actor_type: BccaeActorType;\n actor_trust_level: BccaeTrustLevel;\n actor_claims?: Record<string, unknown>;\n action_id: string;\n execution_intent: string;\n /** 64 lowercase hex characters (32 random bytes). */\n caller_nonce: string;\n resource_ref: string;\n resource_type: string;\n resource_classification: BccaeResourceClassification;\n organization_version?: number;\n deployment_env: BccaeDeploymentEnv;\n deployment_region: string;\n security_posture: BccaeSecurityPosture;\n external_signals?: unknown[];\n dependencies?: unknown[];\n policy_version_set?: unknown[];\n request_source?: BccaeRequestSource;\n request_chain_id?: string;\n parent_eval_id?: string;\n}\n\nexport interface BccaeEvaluateResponse {\n evaluation_id: string;\n envelope_hash: string;\n permit_token: string;\n permit_id: string;\n expires_at: string;\n outcome: \"PERMIT\" | \"PERMIT_WITH_CONDITIONS\";\n}\n\nexport interface BccaeExecuteInput {\n permit_token: string;\n action_id: string;\n resource_ref: string;\n}\n\nexport interface BccaeExecuteResponse {\n authorized: boolean;\n outcome: \"EXECUTION_AUTHORIZED\" | \"EXECUTION_DENIED\";\n permit_id?: string;\n evaluation_id?: string;\n envelope_hash?: string;\n evidence_id?: string | null;\n /** Populated on denial — identifies which gate check failed. */\n check?: string;\n reason?: string;\n}\n\nexport interface BccaeRevokeInput {\n target_type: BccaeRevocationTargetType;\n target_id: string;\n reason: string;\n}\n\nexport interface BccaeRevokeResponse {\n revocation_id: string;\n target_type: BccaeRevocationTargetType;\n target_id: string;\n effective_at: string;\n}\n\nexport interface BccaeEvidenceResponse {\n evidence_id: string;\n org_id: string;\n event_type: string;\n evaluation_id: string | null;\n permit_id: string | null;\n envelope_hash: string | null;\n actor_id: string;\n action_id: string | null;\n resource_ref: string | null;\n outcome: string;\n detail: Record<string, unknown>;\n previous_evidence_id: string | null;\n previous_hash: string | null;\n record_hash: string;\n sequence: number;\n recorded_at: string;\n chain_integrity: {\n hash_intact: boolean;\n expected_hash?: string;\n };\n}\n\nexport interface BccaeClientOptions {\n /** API key with appropriate bccae:* scopes. */\n apiKey: string;\n /** Override base URL. Defaults to https://api.atlasent.io */\n baseUrl?: string;\n /** Request timeout in ms. Defaults to 10000. */\n timeoutMs?: number;\n /** Inject a custom fetch implementation (testing / edge runtimes). */\n fetch?: typeof globalThis.fetch;\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nconst DEFAULT_BASE_URL = \"https://api.atlasent.io\";\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\n/**\n * Validates the caller-supplied base URL and returns its normalized origin\n * (scheme://host[:port]). Using parsed.origin rather than the raw string\n * breaks the taint path from caller input to the outbound fetch call.\n */\nfunction enforceTls(raw: string): string {\n let parsed: URL;\n try {\n parsed = new URL(raw);\n } catch {\n throw new AtlaSentError(\n \"BCCAEClient baseUrl is not a valid URL\",\n { code: \"network\" },\n );\n }\n if (parsed.protocol === \"http:\") {\n // Exact hostname comparison via parsed.hostname avoids\n // false positives from query strings containing 'localhost'.\n const h = parsed.hostname;\n if (h !== \"localhost\" && h !== \"127.0.0.1\" && h !== \"[::1]\") {\n throw new AtlaSentError(\n \"BCCAEClient baseUrl must use https:// for non-local endpoints\",\n { code: \"network\" },\n );\n }\n }\n // Return the URL's origin (scheme + host + port) — any path/query\n // component in the raw input is intentionally dropped here.\n return parsed.origin;\n}\n\n/** Generate a cryptographically random 64-char hex nonce (32 bytes). */\nexport function generateBccaeNonce(): string {\n const bytes = new Uint8Array(32);\n globalThis.crypto.getRandomValues(bytes);\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n// ─── BCCAEClient ──────────────────────────────────────────────────────────────\n\n/**\n * Thin HTTP client for the BCCAE V1 Phase 3 endpoints.\n *\n * Each method maps 1:1 to an edge function:\n * - {@link BCCAEClient.evaluate} → v1-bccae-evaluate\n * - {@link BCCAEClient.execute} → v1-bccae-execute\n * - {@link BCCAEClient.revoke} → v1-bccae-revoke\n * - {@link BCCAEClient.getEvidence} → v1-bccae-evidence\n *\n * Authorization denials are returned (not thrown). Network errors,\n * invalid API keys, and 5xx responses throw {@link AtlaSentError}.\n *\n * Use {@link generateBccaeNonce} to produce a valid `caller_nonce`.\n */\nexport class BCCAEClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly timeoutMs: number;\n private readonly fetchImpl: typeof fetch;\n\n constructor(options: BccaeClientOptions) {\n if (!options.apiKey || typeof options.apiKey !== \"string\") {\n throw new AtlaSentError(\"BCCAEClient: apiKey is required\", {\n code: \"invalid_api_key\",\n });\n }\n this.apiKey = options.apiKey;\n // enforceTls validates scheme/host and returns parsed.origin,\n // severing any taint from the raw options.baseUrl string.\n this.baseUrl = enforceTls(options.baseUrl ?? DEFAULT_BASE_URL);\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n async evaluate(input: BccaeEvaluateInput): Promise<BccaeEvaluateResponse> {\n const { body } = await this.post<BccaeEvaluateResponse>(\n \"/v1/bccae/evaluations\",\n input,\n );\n return body;\n }\n\n async execute(input: BccaeExecuteInput): Promise<BccaeExecuteResponse> {\n const { body } = await this.post<BccaeExecuteResponse>(\n \"/v1/bccae/execute\",\n input,\n );\n return body;\n }\n\n async revoke(input: BccaeRevokeInput): Promise<BccaeRevokeResponse> {\n const { body } = await this.post<BccaeRevokeResponse>(\n \"/v1/bccae/revocations\",\n input,\n );\n return body;\n }\n\n async getEvidence(evidenceId: string): Promise<BccaeEvidenceResponse> {\n if (!evidenceId || typeof evidenceId !== \"string\") {\n throw new AtlaSentError(\"BCCAEClient: evidenceId is required\", {\n code: \"bad_request\",\n });\n }\n const { body } = await this.get<BccaeEvidenceResponse>(\n `/v1/bccae/evidence/${encodeURIComponent(evidenceId)}`,\n );\n return body;\n }\n\n // ── HTTP primitives ─────────────────────────────────────────────────────────\n\n private async post<T>(\n path: string,\n body: unknown,\n ): Promise<{ body: T }> {\n return this.request<T>(path, \"POST\", body);\n }\n\n private async get<T>(path: string): Promise<{ body: T }> {\n return this.request<T>(path, \"GET\", undefined);\n }\n\n private async request<T>(\n path: string,\n method: \"GET\" | \"POST\",\n body: unknown,\n ): Promise<{ body: T }> {\n const url = `${this.baseUrl}${path}`;\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n \"User-Agent\": \"atlasent-bccae-client/1.0\",\n };\n if (method === \"POST\") headers[\"Content-Type\"] = \"application/json\";\n\n let response: Response;\n try {\n response = await this.fetchImpl(url, {\n method,\n headers,\n signal: AbortSignal.timeout(this.timeoutMs),\n ...(method === \"POST\" ? { body: JSON.stringify(body) } : {}),\n });\n } catch (err) {\n throw new AtlaSentError(\n `BCCAEClient: network error on ${method} ${path}: ${err instanceof Error ? err.message : String(err)}`,\n { code: \"network\" },\n );\n }\n\n let responseBody: unknown;\n try {\n responseBody = await response.json();\n } catch {\n throw new AtlaSentError(\n `BCCAEClient: non-JSON response (status ${response.status}) from ${method} ${path}`,\n { code: \"network\" },\n );\n }\n\n if (!response.ok) {\n const err = responseBody as Record<string, unknown>;\n const message =\n typeof err?.message === \"string\"\n ? err.message\n : `BCCAE request failed with status ${response.status}`;\n const code =\n response.status === 401\n ? \"invalid_api_key\"\n : response.status === 403\n ? \"forbidden\"\n : response.status === 429\n ? \"rate_limited\"\n : response.status >= 500\n ? \"server_error\"\n : \"network\";\n throw new AtlaSentError(message, { code });\n }\n\n return { body: responseBody as T };\n }\n}\n","/**\n * Constrained governance agents — read-side SDK surface.\n *\n * Three endpoints, all GET, all org-scoped server-side:\n *\n * GET /v1/governance/agents — registry of advisory agents\n * GET /v1/governance/findings?change_id=… — findings against one change\n * GET /v1/governance/evaluations?change_id=… — agent run records\n *\n * **Doctrine — evaluation ≠ authorization ≠ execution.**\n * Every type in this module is read-only signal. `can_authorize` is\n * pinned `false` on the wire (DB-generated column on the registry,\n * CHECK on findings). The SDK does not expose an invocation method:\n * agent invocation is a CI concern (atlasent-action `governance-agents`\n * mode), not an application concern. This module is for surfaces that\n * want to render findings alongside the authority workflow.\n *\n * Wire schema source of truth lives in\n * atlasent-api/packages/types/src/governance-agents.ts\n * which is intentionally standalone (not re-exported from @atlasent/types).\n * The shapes mirrored below are the read-side subset.\n *\n * @module\n */\n\n// ─── enums (mirror SQL CHECK domains) ────────────────────────────────────────\n\nexport type AgentFindingSeverity =\n | \"info\"\n | \"low\"\n | \"medium\"\n | \"high\"\n | \"blocker\";\n\nexport type AgentEvaluationStatus =\n | \"running\"\n | \"completed\"\n | \"failed\"\n | \"timeout\";\n\nexport type AgentAuthorityDomain =\n | \"engineering\"\n | \"runtime_platform\"\n | \"security\"\n | \"compliance\"\n | \"release_management\"\n | \"operations\"\n | \"customer_impact\"\n | \"governance_office\";\n\nexport type AgentInvokerKind =\n | \"human\"\n | \"service_account\"\n | \"autonomous_agent\"\n | \"system\";\n\nexport type AgentSubjectKind =\n | \"pull_request\"\n | \"schema_migration\"\n | \"runtime_flag\"\n | \"deployment\"\n | \"operational_rollout\"\n | \"regulated_execution_change\"\n | \"policy_bundle\";\n\n// ─── records ─────────────────────────────────────────────────────────────────\n\n/**\n * A versioned advisory agent definition. `authority_class` is fixed to\n * `advisory` and `can_authorize` to `false` at the schema level — these\n * cannot be relaxed without a structural change to the runtime DB.\n */\nexport interface GovernanceAgent {\n readonly slug: string;\n readonly version: string;\n readonly name: string;\n readonly description: string;\n readonly applicable_subject_kinds: readonly AgentSubjectKind[];\n readonly authority_class: \"advisory\";\n /** Structurally false. Generated column on the runtime DB. */\n readonly can_authorize: false;\n readonly capabilities: readonly string[];\n readonly is_active: boolean;\n readonly created_at: string;\n readonly retired_at: string | null;\n}\n\n/** A typed evidence pointer attached to a finding. Free-form by design. */\nexport interface AgentEvidenceRef {\n readonly kind: string;\n readonly ref: string;\n readonly note?: string;\n}\n\n/**\n * One advisory finding produced by an agent run. `can_authorize` is\n * pinned `false` by a CHECK constraint on the underlying table — no\n * finding row in any environment can ever satisfy a gate.\n */\nexport interface GovernanceAgentFinding {\n readonly id: string;\n readonly org_id: string;\n readonly evaluation_id: string;\n readonly change_id: string;\n readonly agent_slug: string;\n readonly agent_version: string;\n readonly finding_type: string;\n readonly severity: AgentFindingSeverity;\n readonly confidence: number | null;\n readonly summary: string;\n readonly evidence_refs: readonly AgentEvidenceRef[];\n readonly required_authority: AgentAuthorityDomain | null;\n readonly recommended_action: string | null;\n /** Structurally false. CHECK constraint on the runtime DB. */\n readonly can_authorize: false;\n readonly supersedes_finding_id: string | null;\n readonly payload: Readonly<Record<string, unknown>>;\n readonly created_at: string;\n /**\n * Populated by the finding→gate routing trigger (atlasent-api #842).\n * Null when no matching gate exists at insertion time; can be\n * back-resolved by `governance_resolve_findings_for_gate(gate_id)`.\n */\n readonly routed_gate_id?: string | null;\n}\n\n/**\n * An append-only record of one agent run against one governed change.\n * The same (agent_slug, agent_version, input_hash) combination may\n * produce multiple rows across time — the runtime DB does not dedupe.\n */\nexport interface GovernanceAgentEvaluation {\n readonly id: string;\n readonly org_id: string;\n readonly change_id: string;\n readonly agent_slug: string;\n readonly agent_version: string;\n readonly input_hash: string;\n readonly status: AgentEvaluationStatus;\n readonly highest_severity: AgentFindingSeverity | null;\n readonly findings_count: number;\n readonly summary: string | null;\n readonly runtime_ms: number | null;\n readonly failure_reason: string | null;\n readonly invoked_by_kind: AgentInvokerKind;\n readonly invoked_by: string | null;\n readonly started_at: string;\n readonly completed_at: string | null;\n}\n\n// ─── response envelopes ──────────────────────────────────────────────────────\n\nexport interface ListGovernanceAgentsResponse {\n readonly agents: readonly GovernanceAgent[];\n}\n\nexport interface ListGovernanceFindingsResponse {\n readonly findings: readonly GovernanceAgentFinding[];\n}\n\nexport interface ListGovernanceEvaluationsResponse {\n readonly evaluations: readonly GovernanceAgentEvaluation[];\n}\n\n// ─── query shapes ────────────────────────────────────────────────────────────\n\nexport interface ListGovernanceFindingsQuery {\n readonly change_id: string;\n /** Optional: filter to one agent's findings. */\n readonly agent_slug?: string;\n}\n\nexport interface ListGovernanceEvaluationsQuery {\n readonly change_id: string;\n /** Optional: filter to one agent's runs. */\n readonly agent_slug?: string;\n}\n\n// ─── helpers ─────────────────────────────────────────────────────────────────\n\nconst SEVERITY_RANK: Record<AgentFindingSeverity, number> = {\n info: 1,\n low: 2,\n medium: 3,\n high: 4,\n blocker: 5,\n};\n\n/**\n * Return the worst severity across a set of findings, or `null` when\n * the input is empty. Pure function, exported because every consumer\n * needs the same rollup logic (Console finds panel, CI summary, etc.).\n */\nexport function highestAgentFindingSeverity(\n findings: readonly Pick<GovernanceAgentFinding, \"severity\">[],\n): AgentFindingSeverity | null {\n let best: AgentFindingSeverity | null = null;\n let rank = 0;\n for (const f of findings) {\n const r = SEVERITY_RANK[f.severity];\n if (r > rank) {\n rank = r;\n best = f.severity;\n }\n }\n return best;\n}\n","/**\n * Delta VQP — TypeScript client for the VQP re-derivation audit endpoints.\n *\n * VQPClient wraps two service-role-only edge functions:\n * generate → POST /functions/v1/v1-generate-vqp (creates snapshot + prompt_hash)\n * verify → POST /functions/v1/v1-verify-vqp (re-derives prompt, hashes, audits)\n *\n * These endpoints require a Supabase service_role key — not a user API key.\n * This client is for server-side admin tooling only.\n *\n * Spec: atlasent-api/supabase/functions/v1-generate-vqp, v1-verify-vqp\n * Phase 3 — Deterministic re-derivation audit.\n */\n\nimport { AtlaSentError } from \"./errors.js\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type VqpVerdict = \"qualified\" | \"conditionally_qualified\" | \"not_qualified\";\n\nexport interface VQPGenerateInput {\n bundle_id: string;\n org_id: string;\n /** Additional context embedded in the VQP prompt for this snapshot. */\n vqp_context?: Record<string, unknown>;\n}\n\nexport interface VQPGenerateResponse {\n snapshot_id: string;\n bundle_id: string;\n bundle_version: string;\n overall_verdict: VqpVerdict;\n quality_score: number;\n /** SHA-256 hex of the deterministic VQP prompt used to produce this snapshot. */\n prompt_hash: string;\n generation_model: string;\n generated_at: string;\n}\n\nexport interface VQPVerifyInput {\n snapshot_id: string;\n /**\n * Re-call the AI model with the re-derived prompt to detect score drift.\n * When false (default), only prompt hash integrity is checked.\n */\n rerun?: boolean;\n}\n\nexport interface VQPVerifyResponse {\n snapshot_id: string;\n /** True when the re-derived prompt hash matches the stored snapshot.prompt_hash. */\n hash_match: boolean;\n original_prompt_hash: string;\n rerun_prompt_hash: string;\n /** Score from the re-run AI call. Null when rerun was not requested. */\n rerun_score: number | null;\n /** Verdict from the re-run AI call. Null when rerun was not requested. */\n rerun_verdict: VqpVerdict | null;\n /** rerun_score - original quality_score. Null when rerun was not requested. */\n score_delta: number | null;\n /** True when rerun_verdict differs from the stored overall_verdict. */\n verdict_changed: boolean;\n /** UUID of the written vqp_audit_log row. */\n audit_log_id: string;\n}\n\nexport interface VQPClientOptions {\n /** Supabase service_role key. These endpoints are not accessible with user API keys. */\n serviceRoleKey: string;\n /** Supabase project URL, e.g. https://<ref>.supabase.co */\n supabaseUrl: string;\n /** Request timeout in ms. Defaults to 30000 (AI re-run calls can be slow). */\n timeoutMs?: number;\n /** Inject a custom fetch implementation (testing / edge runtimes). */\n fetch?: typeof globalThis.fetch;\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\nfunction enforceHttps(raw: string): string {\n let parsed: URL;\n try {\n parsed = new URL(raw);\n } catch {\n throw new AtlaSentError(\"VQPClient supabaseUrl is not a valid URL\", {\n code: \"network\",\n });\n }\n if (parsed.protocol === \"http:\") {\n const h = parsed.hostname;\n if (h !== \"localhost\" && h !== \"127.0.0.1\" && h !== \"[::1]\") {\n throw new AtlaSentError(\n \"VQPClient supabaseUrl must use https:// for non-local endpoints\",\n { code: \"network\" },\n );\n }\n }\n return parsed.origin;\n}\n\n// ─── VQPClient ────────────────────────────────────────────────────────────────\n\n/**\n * Thin HTTP client for the Delta VQP Phase 3 service-role endpoints.\n *\n * Each method maps 1:1 to an edge function:\n * - {@link VQPClient.generate} → v1-generate-vqp\n * - {@link VQPClient.verify} → v1-verify-vqp\n *\n * **Server-side only.** These endpoints require `SUPABASE_SERVICE_ROLE_KEY`.\n * Never expose a service_role key in browser or agent code.\n *\n * Network errors and 5xx responses throw {@link AtlaSentError}.\n */\nexport class VQPClient {\n private readonly serviceRoleKey: string;\n private readonly baseUrl: string;\n private readonly timeoutMs: number;\n private readonly fetchImpl: typeof fetch;\n\n constructor(options: VQPClientOptions) {\n if (!options.serviceRoleKey || typeof options.serviceRoleKey !== \"string\") {\n throw new AtlaSentError(\"VQPClient: serviceRoleKey is required\", {\n code: \"invalid_api_key\",\n });\n }\n this.serviceRoleKey = options.serviceRoleKey;\n this.baseUrl = enforceHttps(options.supabaseUrl);\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n async generate(input: VQPGenerateInput): Promise<VQPGenerateResponse> {\n const { body } = await this.post<VQPGenerateResponse>(\n \"/functions/v1/v1-generate-vqp\",\n input,\n );\n return body;\n }\n\n async verify(input: VQPVerifyInput): Promise<VQPVerifyResponse> {\n const { body } = await this.post<VQPVerifyResponse>(\n \"/functions/v1/v1-verify-vqp\",\n input,\n );\n return body;\n }\n\n // ── HTTP primitives ─────────────────────────────────────────────────────────\n\n private async post<T>(path: string, body: unknown): Promise<{ body: T }> {\n return this.request<T>(path, \"POST\", body);\n }\n\n private async request<T>(\n path: string,\n method: \"GET\" | \"POST\",\n body: unknown,\n ): Promise<{ body: T }> {\n const url = `${this.baseUrl}${path}`;\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n Authorization: `Bearer ${this.serviceRoleKey}`,\n \"User-Agent\": \"atlasent-vqp-client/1.0\",\n };\n if (method === \"POST\") headers[\"Content-Type\"] = \"application/json\";\n\n let response: Response;\n try {\n response = await this.fetchImpl(url, {\n method,\n headers,\n signal: AbortSignal.timeout(this.timeoutMs),\n ...(method === \"POST\" ? { body: JSON.stringify(body) } : {}),\n });\n } catch (err) {\n throw new AtlaSentError(\n `VQPClient: network error on ${method} ${path}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n { code: \"network\" },\n );\n }\n\n let responseBody: unknown;\n try {\n responseBody = await response.json();\n } catch {\n throw new AtlaSentError(\n `VQPClient: non-JSON response (status ${response.status}) from ${method} ${path}`,\n { code: \"network\" },\n );\n }\n\n if (!response.ok) {\n const err = responseBody as Record<string, unknown>;\n const message =\n typeof err?.message === \"string\"\n ? err.message\n : `VQP request failed with status ${response.status}`;\n const code =\n response.status === 401\n ? \"invalid_api_key\"\n : response.status === 403\n ? \"forbidden\"\n : response.status === 429\n ? \"rate_limited\"\n : response.status >= 500\n ? \"server_error\"\n : \"network\";\n throw new AtlaSentError(message, { code });\n }\n\n return { body: responseBody as T };\n }\n}\n"],"mappings":"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","names":["isNode","headers","varianceKind","resolve","sha256Hex","createHash","createHmac","createHash","overrides","sleep","resolve","escalation","outcome","start","MACHINE_EXECUTABLE_ACTIONS","pct","import_node_crypto","timingSafeEqual","createHmac","pickFetch","resolveConfig","apiGet","apiPost","import_node_crypto","SDK_VERSION","sha256Hex","createHash","DEFAULT_BASE_URL","DEFAULT_TIMEOUT_MS","headers","DEFAULT_TIMEOUT_MS","headers"]}
|