export declare const VC_MEETING_ACTION_SINKS: readonly ["listener_chat", "listener_notice", "meeting_text", "meeting_voice", "attention_dm", "task"]; export type VcMeetingActionSink = typeof VC_MEETING_ACTION_SINKS[number]; /** v1 intentionally has no agent-controlled free-form slots. */ export declare const VC_MEETING_ACTION_SLOTS: readonly ["primary"]; export type VcMeetingActionSlot = typeof VC_MEETING_ACTION_SLOTS[number]; export type VcMeetingActionSource = { kind: 'delivery'; key: string; deliverySeq: number; } | { kind: 'im_turn'; key: string; larkMessageId: string; }; export type VcMeetingActionStatus = 'requested' | 'pendingApproval' | 'approved' | 'attempting' | 'succeeded' | 'failed' | 'rejected' | 'expired' | 'unknown'; export type VcMeetingApprovalCardStatus = 'requested' | 'attempting' | 'presented' | 'failed' | 'unknown'; export interface VcMeetingApprovalCardRecord { /** Stable Lark card UUID/idempotency key derived from actionId. */ providerKey: string; status: VcMeetingApprovalCardStatus; attemptCount: number; attemptedAt?: number; finishedAt?: number; externalRefs?: Record; errorCode?: string; createdAt: number; updatedAt: number; } export declare const VC_MEETING_ACTION_TERMINAL_STATUSES: readonly ["succeeded", "failed", "rejected", "expired", "unknown"]; export interface VcMeetingActionScope { listenerAppId: string; meetingId: string; } export interface VcMeetingActionBeginInput extends VcMeetingActionScope { memberId: string; memberEpoch: number; agentAppId: string; /** Sink-owner-generation authorization snapshot; intentionally excluded from actionId. */ ownerGeneration: number; source: VcMeetingActionSource; sink: VcMeetingActionSink; /** Runtime validation remains strict even if an untyped caller supplies a string. */ actionSlot?: VcMeetingActionSlot; /** Provider-facing, normalized payload. Transport/reason fields do not belong here. */ canonicalInput: unknown; } export interface VcMeetingActionRecord extends VcMeetingActionScope { actionId: string; actionSlot: VcMeetingActionSlot; source: VcMeetingActionSource; memberId: string; memberEpoch: number; agentAppId: string; sink: VcMeetingActionSink; /** Durable sinkOwnerGeneration snapshot used by the action gate's fencing check. */ ownerGeneration: number; inputHash: string; /** Stable provider idempotency token, independent from provider content. */ providerKey: string; status: VcMeetingActionStatus; canonicalInput: unknown; attemptCount: number; attemptedAt?: number; finishedAt?: number; externalRefs?: Record; errorCode?: string; /** Present iff this action entered pending approval. The card is an effect too. */ approvalCard?: VcMeetingApprovalCardRecord; createdAt: number; updatedAt: number; } export type VcMeetingActionBeginResult = { kind: 'created'; record: VcMeetingActionRecord; } /** Exact identity + content replay. Returned before any current fencing checks. */ | { kind: 'existing'; record: VcMeetingActionRecord; } | { kind: 'conflict'; reason: 'invalid' | 'unsupported_slot' | 'input_mismatch'; actionId?: string; record?: VcMeetingActionRecord; detail?: string; }; export interface VcMeetingActionRef extends VcMeetingActionScope { actionId: string; inputHash: string; } export type VcMeetingActionTransitionResult = { kind: 'updated'; record: VcMeetingActionRecord; } | { kind: 'existing'; record: VcMeetingActionRecord; } | { kind: 'conflict'; reason: 'not_found' | 'input_mismatch' | 'invalid_transition' | 'invalid'; record?: VcMeetingActionRecord; }; export type VcMeetingActionClaimResult = { kind: 'claimed'; record: VcMeetingActionRecord; } | { kind: 'existing'; record: VcMeetingActionRecord; } | { kind: 'conflict'; reason: 'not_found' | 'input_mismatch' | 'invalid_transition' | 'invalid'; record?: VcMeetingActionRecord; }; export type VcMeetingApprovalCardClaimResult = VcMeetingActionClaimResult; export interface VcMeetingProviderReconcileRef extends VcMeetingActionRef { sink: VcMeetingActionSink; providerKey: string; attemptedAt: number; externalRefs?: Record; /** Caller must lookup or idempotently retry with providerKey, then finish. */ mode: 'lookup_or_idempotent_retry'; } export interface VcMeetingApprovalCardReconcileRef extends VcMeetingActionRef { approvalProviderKey: string; status: 'requested' | 'attempting'; attemptedAt?: number; externalRefs?: Record; /** requested = send after claim; attempting = lookup/retry with the same key. */ mode: 'claim_then_send' | 'lookup_or_idempotent_retry'; } export interface VcMeetingActionBootReconcileResult { providerAttempts: VcMeetingProviderReconcileRef[]; approvalCards: VcMeetingApprovalCardReconcileRef[]; terminalizedUnknown: VcMeetingActionRecord[]; terminalizedExpired: VcMeetingActionRecord[]; } /** * The effect identity is content- and owner-generation-independent. With the * `vca_` namespace the 50-character key retains 184 bits of SHA-256 entropy. */ export declare function deriveVcMeetingActionId(input: Omit): string; /** Stable provider UUID/client-token derived only from action identity. */ export declare function deriveVcMeetingProviderKey(actionId: string): string; /** Approval presentation is a separate provider effect with its own stable key. */ export declare function deriveVcMeetingApprovalCardKey(actionId: string): string; export declare function isVcMeetingActionTerminal(status: VcMeetingActionStatus): boolean; /** * These providers have a stable providerKey that the gate can use for lookup or * an idempotent retry. Voice deliberately remains excluded: replaying speech * after an ambiguous crash is not safe. */ export declare function canReconcileVcMeetingActionProvider(sink: VcMeetingActionSink): boolean; /** * Persist an immutable action intent. Exact replays return the original record * even when the caller now carries a stale sink-owner generation or agent * snapshot; the action gate can therefore replay terminal results before * current fencing. */ export declare function beginVcMeetingAction(dataDir: string, input: VcMeetingActionBeginInput, now?: number): VcMeetingActionBeginResult; export declare function markVcMeetingActionPendingApproval(dataDir: string, ref: VcMeetingActionRef, now?: number): VcMeetingActionTransitionResult; /** * Write-ahead claim for the approval card provider effect. `claimed` means the * card's attempting state is durable; the caller may now send with providerKey. */ export declare function claimVcMeetingApprovalCardAttempt(dataDir: string, ref: VcMeetingActionRef, now?: number): VcMeetingApprovalCardClaimResult; export declare function finishVcMeetingApprovalCard(dataDir: string, ref: VcMeetingActionRef, finish: { status: 'presented' | 'failed' | 'unknown'; externalRefs?: Record; errorCode?: string; }, now?: number): VcMeetingActionTransitionResult; export declare function resolveVcMeetingActionApproval(dataDir: string, ref: VcMeetingActionRef, decision: 'approved' | 'rejected' | 'expired', opts?: { externalRefs?: Record; errorCode?: string; }, now?: number): VcMeetingActionTransitionResult; /** * Atomically apply an approval and claim the provider attempt in one file-lock * transaction. There is deliberately no durable `approved` crash window: once * this returns `claimed`, the write-ahead `attempting` record is already the * only observable state. A legacy/crash residue already in `approved` is also * claimed so startup can heal older records. */ export declare function approveAndClaimVcMeetingAction(dataDir: string, ref: VcMeetingActionRef, opts?: { externalRefs?: Record; }, now?: number): VcMeetingActionClaimResult; /** * Deterministically reject an action before any provider attempt. This is kept * separate from approval resolution: capability/fencing/policy denial is not * an approval-card effect and must not manufacture one merely to reach the * terminal `rejected` state. */ export declare function rejectVcMeetingAction(dataDir: string, ref: VcMeetingActionRef, opts: { errorCode: string; externalRefs?: Record; }, now?: number): VcMeetingActionTransitionResult; /** * Atomically claims provider execution. `claimed` means the attempting record * is already durable and the caller may now invoke the provider. Every other * result means the caller must not invoke it. */ export declare function claimVcMeetingActionAttempt(dataDir: string, ref: VcMeetingActionRef, now?: number): VcMeetingActionClaimResult; export declare function finishVcMeetingAction(dataDir: string, ref: VcMeetingActionRef, finish: { status: 'succeeded' | 'failed' | 'unknown'; externalRefs?: Record; errorCode?: string; }, now?: number): VcMeetingActionTransitionResult; export declare function findVcMeetingAction(dataDir: string, scope: VcMeetingActionScope, actionId: string): VcMeetingActionRecord | undefined; export declare function listVcMeetingActions(dataDir: string, scope: VcMeetingActionScope, filter?: { status?: VcMeetingActionStatus; memberId?: string; sink?: VcMeetingActionSink; }): VcMeetingActionRecord[]; /** Enumerate durable meeting scopes so daemon boot can reconcile every ledger. */ export declare function listVcMeetingActionScopes(dataDir: string): VcMeetingActionScope[]; /** * Provider-aware boot recovery. Voice is terminalized as unknown/manual because * replay is unsafe. Sinks with a stable provider key remain attempting and are * returned as work for lookup/idempotent retry. Approval-card presentation is * independently returned as work: `requested` covers a crash after durable * pendingApproval but before card claim, while `attempting` covers an ambiguous * post-send crash. This function itself never invokes a provider. */ export declare function reconcileVcMeetingActionsOnBoot(dataDir: string, scope: VcMeetingActionScope, now?: number): VcMeetingActionBootReconcileResult; //# sourceMappingURL=vc-meeting-action-store.d.ts.map