/** * Society Protocol — SQLite Storage Module v1.0 * * Local-first persistence: identity, rooms, messages, presence, * CoC chains/steps/events, adapters, reputation, and artifact lineage. * Uses better-sqlite3 for synchronous, fast SQLite access. */ import Database from 'better-sqlite3'; import type { TaskOutcome } from './reputation.js'; import type { Artifact } from './swp.js'; export interface StorageOptions { /** Path to the database file. Defaults to ~/.society/society.db */ dbPath?: string; /** Optional SQLCipher key (also read from SOCIETY_DB_KEY) */ encryptionKey?: string; /** Allow plaintext fallback when SQLCipher is unavailable */ allowPlaintextDev?: boolean; } export type FederationPeeringStatus = 'pending' | 'active' | 'rejected' | 'revoked'; export type FederationBridgeStatus = 'active' | 'closed'; export type FederationSyncDirection = 'in' | 'out'; export type PersonaCapabilityStatus = 'active' | 'revoked' | 'expired'; export interface PersonaVaultRecord { id: string; ownerDid: string; name: string; createdAt: number; updatedAt: number; settings?: Record; lifecycle?: Record; } export interface PersonaNodeRecord { id: string; vaultId: string; domain: string; type: string; title: string; content: string; tags: string[]; confidence: number; metadata: Record; source?: Record; validFrom?: number; validTo?: number; createdAt: number; updatedAt: number; deletedAt?: number; } export interface PersonaEdgeRecord { id: string; vaultId: string; sourceNodeId: string; targetNodeId: string; type: string; weight: number; confidence: number; metadata: Record; validFrom?: number; validTo?: number; updatedAt: number; deletedAt?: number; } export interface PersonaHyperEdgeRecord { id: string; vaultId: string; nodeIds: string[]; type: string; metadata: Record; updatedAt: number; deletedAt?: number; } export interface PersonaCrdtDocRecord { docId: string; vaultId: string; domain: string; data: Record; clock: Record; updatedAt: number; } export interface PersonaCapabilityRecord { id: string; vaultId: string; serviceDid: string; scope: string; caveats: Record; tokenHash: string; status: PersonaCapabilityStatus; issuedAt: number; expiresAt?: number; revokedAt?: number; parentTokenId?: string; } export interface PersonaEmbeddingRecord { nodeId: string; vaultId: string; model: string; dim: number; vector?: number[]; vecRowId?: number; updatedAt: number; } export interface PersonaClaimRecord { id: string; vaultId: string; subjectDid: string; issuerDid?: string; schema: string; payloadEnc: string; status: 'active' | 'revoked' | 'expired'; issuedAt: number; expiresAt?: number; revokedAt?: number; signature: string; } export interface PersonaZkpProofRecord { id: string; vaultId: string; circuitId: string; proofBlob: string; publicInputs: Record; claimIds: string[]; createdAt: number; expiresAt?: number; } export interface PersonaZkpCircuitRecord { circuitId: string; version: string; vkBlob?: string | null; metadata: Record; active: boolean; } export interface PersonaAccessLogRecord { id?: number; vaultId: string; tokenId?: string; serviceDid: string; operation: string; resource: string; result: 'allowed' | 'denied'; details?: Record; ts: number; signature?: string; signerDid?: string; sigAlg?: string; } export interface PersonaSyncStateRecord { peerDid: string; vaultId: string; cursorId: string; clock: Record; updatedAt: number; } export interface PersonaRetentionStateRecord { vaultId: string; domain: string; lastCleanupAt: number; } export interface PersonaGraphCacheRecord { vaultId: string; domain: string; graphVersion: string; ppr: Record; updatedAt: number; } export interface PersonaMetricRecord { ts: number; metric: string; value: number; labels?: Record; } export interface FederationPeeringRecord { peeringId: string; sourceFederationId: string; sourceFederationDid: string; targetFederationDid: string; policy: Record; status: FederationPeeringStatus; reason?: string; createdAt: number; updatedAt: number; respondedAt?: number; } export interface FederationBridgeRecord { bridgeId: string; peeringId: string; localFederationId: string; localRoomId: string; remoteRoomId: string; rules: Record; status: FederationBridgeStatus; eventsIn: number; eventsOut: number; lastSyncAt?: number; createdAt: number; updatedAt: number; } export interface FederationSyncCursorRecord { bridgeId: string; direction: FederationSyncDirection; cursorId: string; updatedAt: number; } export interface FederationSyncLogRecord { id?: number; bridgeId: string; envelopeId: string; direction: FederationSyncDirection; messageType: string; fromFederationId?: string; toFederationId?: string; status: 'processed' | 'rejected' | 'failed'; error?: string; ts: number; } export interface MissionRecord { missionId: string; roomId: string; goal: string; missionType: string; templateId?: string; mode: string; status: string; leaderDid: string; cadenceMs: number; policy: Record; research: Record; knowledge?: Record; activeChainIds: string[]; lastTickAt?: number; nextTickAt?: number; createdAt: number; updatedAt: number; } export interface MissionRunRecord { runId: string; missionId: string; cycle: number; chainId?: string; status: string; summary?: string; startedAt?: number; endedAt?: number; } export interface MissionCheckpointRecord { checkpointId: string; missionId: string; summary: string; frontier: Record; knowledge: Record; createdAt: number; } export interface MissionLeaseRecord { missionId: string; holderInstanceId: string; holderDid: string; expiresAt: number; updatedAt: number; } export interface SwarmWorkerRecord { did: string; peerId?: string; roomId: string; hostId: string; runtime: string; specialties: string[]; capabilities: string[]; kinds: string[]; maxConcurrency: number; load: number; health: 'healthy' | 'degraded' | 'unhealthy'; missionTags?: string[]; adapterId?: string; displayName?: string; endpoint?: string; successRate?: number; queueDepth?: number; lastSeen?: number; metadata?: Record; } export declare class Storage { db: Database.Database; constructor(options?: StorageOptions); /** * Run schema migrations. */ private migrate; private applyMigrations; private ensureColumn; transaction(fn: () => T): T; set(key: string, value: T): void; get(key: string): T | undefined; delete(key: string): void; query(sql: string, params?: any[]): any[]; saveIdentity(did: string, privateKeyHex: string, publicKeyHex: string, displayName: string): void; getIdentity(): { did: string; private_key_hex: string; public_key_hex: string; display_name: string; } | undefined; createRoom(roomId: string, name: string, createdBy: string): void; getRooms(): Array<{ room_id: string; name: string; created_by: string; created_at: number; }>; addRoomMember(roomId: string, memberDid: string, displayName?: string): void; getRoomMembers(roomId: string): Array<{ member_did: string; display_name: string | null; }>; saveMessage(id: string, roomId: string, fromDid: string, fromName: string | null, text: string, replyTo: string | null, ts: number): void; getMessages(roomId: string, limit?: number): Array<{ id: string; room_id: string; from_did: string; from_name: string | null; text: string; ts: number; }>; upsertPresence(peerDid: string, peerName: string | null, status: string, capabilities: string[] | null, load: number | null, roomId?: string): void; getOnlinePeers(staleSeconds?: number): Array<{ peer_did: string; peer_name: string | null; status: string; capabilities: string | null; last_seen: number; }>; hasReplay(fromDid: string, messageId: string): boolean; addReplay(fromDid: string, messageId: string): void; pruneReplayCache(maxAgeSeconds?: number): void; registerAdapter(adapterId: string, runtime: string, displayName: string, specialties: string[], kinds: string[], maxConcurrency: number, endpoint: string, authType?: string, options?: { ownerDid?: string; roomId?: string; missionTags?: string[]; health?: 'healthy' | 'degraded' | 'unhealthy'; queueDepth?: number; successRate?: number; hostId?: string; peerId?: string; }): void; getAdapters(): Array<{ adapter_id: string; runtime: string; display_name: string; specialties: string; kinds: string; max_concurrency: number; endpoint: string; }>; getAdapter(adapterId: string): any | undefined; updateAdapterHeartbeat(adapterId: string, health: 'healthy' | 'degraded' | 'unhealthy', queueDepth: number, successRate?: number): void; upsertSwarmWorker(worker: SwarmWorkerRecord): void; getSwarmWorker(workerDid: string): SwarmWorkerRecord | undefined; getVisibleWorkers(roomId?: string, maxAgeMs?: number): SwarmWorkerRecord[]; private mapSwarmWorker; createMission(input: { missionId: string; roomId: string; goal: string; missionType: string; templateId?: string; mode: string; status: string; leaderDid: string; cadenceMs: number; policy: Record; research: Record; knowledge?: Record; activeChainIds: string[]; lastTickAt?: number; nextTickAt?: number; }): void; getMission(missionId: string): MissionRecord | undefined; listMissions(roomId?: string): MissionRecord[]; updateMissionStatus(missionId: string, status: string, updates?: { activeChainIds?: string[]; lastTickAt?: number; nextTickAt?: number; }): void; appendMissionChain(missionId: string, chainId: string): void; findMissionByChain(chainId: string): MissionRecord | undefined; acquireMissionLease(missionId: string, holderInstanceId: string, holderDid: string, ttlMs: number, now?: number): boolean; renewMissionLease(missionId: string, holderInstanceId: string, holderDid: string, ttlMs: number, now?: number): boolean; releaseMissionLease(missionId: string, holderInstanceId: string): boolean; getMissionLease(missionId: string): MissionLeaseRecord | undefined; createMissionRun(run: MissionRunRecord): void; saveMissionCheckpoint(checkpoint: MissionCheckpointRecord): void; getLatestMissionCheckpoint(missionId: string): MissionCheckpointRecord | undefined; addMissionEvent(missionId: string, eventType: string, actorDid: string | null, payload?: Record): void; saveResearchArtifact(input: { artifactId: string; missionId?: string; workerDid?: string; artifactType: string; sourceUrl?: string; externalId?: string; contentHash?: string; metadata?: Record; }): void; private mapMission; createChain(chainId: string, roomId: string, goal: string, templateId: string | null, createdBy: string, priority?: string, timeoutAt?: number): void; updateChainStatus(chainId: string, status: string, finalReport?: string): void; createStep(stepId: string, chainId: string, kind: string, title: string, description: string | null, dependsOn: string[], requirements?: Record, timeoutMs?: number): void; updateStepStatus(stepId: string, status: string, updates?: { assigneeDid?: string | null; leaseMs?: number | null; memo?: string | null; artifacts?: Artifact[]; metrics?: Record; retryCount?: number; }): void; addCocEvent(chainId: string, stepId: string | null, eventType: string, actorDid: string | null, data: unknown): void; getChain(chainId: string): any | undefined; getChainSteps(chainId: string): any[]; getStepRecord(stepId: string): any | undefined; getAssignedStepsForDid(assigneeDid: string): any[]; getChainEvents(chainId: string): any[]; saveReputation(reputation: { did: string; overall: number; trust_tier: string; metrics: Record; specialties: Array>; first_seen: number; version: number; }): void; getReputationRecord(did: string): any | undefined; saveTaskOutcome(outcome: TaskOutcome): void; getAllTaskOutcomes(did: string): TaskOutcome[]; getTaskOutcomes(did: string, days: number): TaskOutcome[]; savePeerReview(review: { reviewer_did: string; subject_did: string; chain_id: string; step_id: string; rating: number; feedback?: string; timestamp: number; }): void; getPeerReviews(subjectDid: string): Array<{ rating: number; timestamp: number; }>; saveArtifact(artifact: Artifact & { created_by?: string; }): void; getArtifact(artifactId: string): any | undefined; getArtifactLineage(artifactId: string): string[]; trackLease(chainId: string, stepId: string, assigneeDid: string, leaseMs: number): void; getExpiredLeases(): Array<{ chain_id: string; step_id: string; assignee_did: string; }>; /** * Atomically claim an expired lease: marks it notified and resets the step * in a single transaction. Returns true if this call won the race. */ claimExpiredLease(chainId: string, stepId: string): boolean; markLeaseNotified(chainId: string, stepId: string): void; removeLease(chainId: string, stepId: string): void; saveFederation(federation: any): void; getFederations(): any[]; saveKnowledgeCard(card: any): void; saveKnowledgeSpace(space: any): void; getKnowledgeSpaces(): any[]; getKnowledgeCards(spaceId?: string): any[]; saveKnowledgeLink(link: any): void; getKnowledgeLinks(): any[]; saveCollectiveUnconscious(cu: any): void; getCollectiveUnconscious(spaceId?: string): any[]; saveCoCKnowledgeBinding(binding: any): void; getCoCKnowledgeBinding(cocId: string): any | undefined; saveFederationRoom(federationId: string, roomId: string, data: any): void; getFederationRooms(federationId: string): any[]; saveFederationProposal(proposalId: string, federationId: string, proposerDid: string, policy: any, status?: string): void; setFederationProposalStatus(proposalId: string, status: string): void; getFederationProposal(proposalId: string): any | undefined; getFederationProposals(federationId?: string): any[]; saveFederationVote(proposalId: string, voterDid: string, vote: 'yes' | 'no' | 'abstain', votingPower: number): void; getFederationVotes(proposalId: string): Array<{ voter_did: string; vote: 'yes' | 'no' | 'abstain'; voting_power: number; voted_at: number; }>; saveFederationPeering(peering: FederationPeeringRecord): void; updateFederationPeeringStatus(peeringId: string, status: FederationPeeringStatus, reason?: string, respondedAt?: number): void; getFederationPeering(peeringId: string): FederationPeeringRecord | undefined; listFederationPeerings(federationId?: string, status?: FederationPeeringStatus, federationDid?: string): FederationPeeringRecord[]; saveFederationBridge(bridge: FederationBridgeRecord): void; updateFederationBridgeStatus(bridgeId: string, status: FederationBridgeStatus, lastSyncAt?: number): void; incrementFederationBridgeCounters(bridgeId: string, direction: FederationSyncDirection, count?: number, lastSyncAt?: number): void; getFederationBridge(bridgeId: string): FederationBridgeRecord | undefined; listFederationBridges(federationId?: string, status?: FederationBridgeStatus): FederationBridgeRecord[]; saveFederationSyncCursor(cursor: FederationSyncCursorRecord): void; getFederationSyncCursor(bridgeId: string, direction: FederationSyncDirection): FederationSyncCursorRecord | undefined; appendFederationSyncLog(entry: FederationSyncLogRecord): void; hasFederationSyncLog(bridgeId: string, envelopeId: string, direction: FederationSyncDirection): boolean; listFederationSyncLog(bridgeId: string, limit?: number): FederationSyncLogRecord[]; getFederationMeshStats(federationId?: string): { bridgeCount: number; activeBridges: number; eventsIn: number; eventsOut: number; lastSyncAt?: number; }; savePersonaVault(vault: any): void; getPersonaVault(vaultId: string): any | undefined; getPersonaVaults(ownerDid?: string): any[]; upsertPersonaNode(node: any): void; getPersonaNode(nodeId: string): any | undefined; listPersonaNodes(vaultId: string, options?: { includeDeleted?: boolean; domain?: string; domains?: string[]; types?: string[]; tags?: string[]; }): any[]; searchPersonaNodes(vaultId: string, query: string, limit?: number): Array<{ id: string; score: number; }>; softDeletePersonaNode(nodeId: string, deletedAt?: number): void; upsertPersonaEdge(edge: any): void; getPersonaEdge(edgeId: string): any | undefined; listPersonaEdges(vaultId: string): any[]; softDeletePersonaEdge(edgeId: string, deletedAt?: number): void; upsertPersonaHyperEdge(edge: any): void; listPersonaHyperEdges(vaultId: string): any[]; upsertPersonaCrdtDoc(doc: any): void; getPersonaCrdtDoc(docId: string): any | undefined; upsertPersonaEmbedding(record: PersonaEmbeddingRecord): void; upsertPersonaVector(rowId: number, vector: number[]): void; deletePersonaEmbedding(nodeId: string): void; getPersonaEmbedding(nodeId: string): PersonaEmbeddingRecord | undefined; searchPersonaVector(vaultId: string, vector: number[], limit?: number): Array<{ nodeId: string; distance: number; score: number; }>; savePersonaCapability(capability: any): void; updatePersonaCapabilityStatus(tokenId: string, status: PersonaCapabilityStatus, reason?: string, updatedAt?: number): void; getPersonaCapabilityByHash(tokenHash: string): any | undefined; getPersonaCapability(tokenId: string): any | undefined; listPersonaCapabilities(vaultId: string): any[]; appendPersonaAccessLog(entry: PersonaAccessLogRecord): void; listPersonaAccessLogs(vaultId: string, limit?: number): PersonaAccessLogRecord[]; getPersonaAccessLog(logId: number): PersonaAccessLogRecord | undefined; savePersonaSyncState(state: PersonaSyncStateRecord): void; getPersonaSyncState(peerDid: string, vaultId: string): PersonaSyncStateRecord | undefined; markPersonaSyncApplied(fromDid: string, deltaId: string, vaultId: string): boolean; hasPersonaSyncApplied(fromDid: string, deltaId: string): boolean; upsertPersonaRetentionState(record: PersonaRetentionStateRecord): void; getPersonaRetentionState(vaultId: string, domain: string): PersonaRetentionStateRecord | undefined; listPersonaRetentionStates(vaultId?: string): PersonaRetentionStateRecord[]; upsertPersonaGraphCache(record: PersonaGraphCacheRecord): void; getPersonaGraphCache(vaultId: string, domain: string, graphVersion: string): PersonaGraphCacheRecord | undefined; prunePersonaGraphCache(vaultId: string, domain: string, keep?: number): void; appendPersonaMetric(record: PersonaMetricRecord): void; listPersonaMetrics(metric: string, limit?: number, sinceTs?: number): PersonaMetricRecord[]; savePersonaClaim(record: PersonaClaimRecord): void; getPersonaClaim(claimId: string): PersonaClaimRecord | undefined; listPersonaClaims(vaultId: string, options?: { includeRevoked?: boolean; }): PersonaClaimRecord[]; updatePersonaClaimStatus(claimId: string, status: 'active' | 'revoked' | 'expired'): void; savePersonaZkpProof(record: PersonaZkpProofRecord): void; getPersonaZkpProof(proofId: string): PersonaZkpProofRecord | undefined; listPersonaZkpProofs(vaultId: string): PersonaZkpProofRecord[]; savePersonaZkpCircuit(record: PersonaZkpCircuitRecord): void; getPersonaZkpCircuit(circuitId: string): PersonaZkpCircuitRecord | undefined; listPersonaZkpCircuits(): PersonaZkpCircuitRecord[]; private safeAddColumn; private ensurePersonaVectorIndex; close(): void; private encode; private decode; private toStorable; private fromStorable; } //# sourceMappingURL=storage.d.ts.map