@codemem/server 0.47.0-beta.3 → 0.47.0-beta.4

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/dist/index.js CHANGED
@@ -1,16 +1,19 @@
1
- import { existsSync, readFileSync, statSync } from "node:fs";
2
- import { dirname, isAbsolute, join, posix, resolve, win32 } from "node:path";
3
- import { ACCESS_CLEANUP_OP_TYPE, CodememConfigMutationError, CoordinatorAccountLinkError, CoordinatorReciprocalApprovalRequestChangedError, DEFAULT_TIME_WINDOW_S, FILE_CONTEXT_TRANSPORT_MAX_BYTES, LEGACY_SHARED_REVIEW_SCOPE_ID, LOCAL_DEFAULT_SCOPE_ID, LOCAL_SYNC_CAPABILITY, LOCAL_SYNC_FEATURES, LegacyTeamSetupAdditiveConvergenceError, LegacyTeamSetupRosterCapacityError, MEMORY_FILTER_FIELD_TYPES, MEMORY_FILTER_NAMES, MEMORY_KIND_DESCRIPTIONS, MemoryStore, ObserverClient, PROMPT_TRANSPORT_PROTOCOL_RANGE, REMEMBER_MEMORY_KINDS, RICH_TIER_ANTHROPIC_DEFAULTS, RICH_TIER_DEFAULTS, RawEventIngestValidationError, RecipientPolicyEdgeRequestError, RecipientPolicyTeamRenameError, RemoteCoordinatorRequestError, SCOPE_MEMBERSHIP_REVOCATION_LIMITATION, SIMPLE_TIER_ANTHROPIC_DEFAULTS, SIMPLE_TIER_DEFAULTS, SYNC_AUTHORIZATION_REFRESH_HEADER, SYNC_CAPABILITY_HEADER, SYNC_FEATURES_HEADER, SYNC_SCOPE_QUERY_PARAM, VERSION, VERSION as VERSION$1, VIEWER_IDENTITY_TARGET_KEYS, VIEWER_SERVICE_DISCRIMINATOR, addSyncScopeToBoundary, analyzeProjectScopeMappingChangeGuardrails, analyzeProjectScopeMappingChangesGuardrails, analyzeProjectScopeMappingDeletionGuardrails, applyLegacyTeamSetupCompletionManifest, applyLegacyTeamSetupCompletionManifestAndReturnActivation, applyReplicationOps, areLegacyTeamSetupCompletionPolicyFactsAdditivelyCompatible, automaticRecallHealth, buildAuthHeaders, buildBaseUrl, buildDirectPeerAuthHeaders, buildDistillReport, buildFilterBranchesWithContext, buildFilterClausesWithContext, buildPiFlushSignalFromEvent, buildRawEventEnvelopeFromCodexHook, buildRawEventEnvelopeFromHook, buildRawEventEnvelopeFromPiEvent, buildViewerIdentityTarget, canonicalCoordinatorLegacyTeamCompletionManifestJson, canonicalMemoryKind, canonicalRepositoryProjectIdentity, canonicalWorkspaceIdentity, changeCoordinatorAccount, claimRecipientPolicyActorMutations, claimRecipientPolicyPublicationMutation, classifyRecordedSyncFailure, cleanupNonces, clearLegacyTeamSetupDeviceDecision, clonePromptPackAttempt, coerceObserverCommand, commitDeviceIdentityBindings, commitRecipientPolicyEdges, containLegacyTeamSetupCompletionConflict, coordinatorArchiveGroupAction, coordinatorCreateAddDeviceInviteAction, coordinatorCreateGroupAction, coordinatorCreateInviteAction, coordinatorCreateLegacyTeamCompletionAction, coordinatorCreateScopeAction, coordinatorDisableDeviceAction, coordinatorEnableDeviceAction, coordinatorGetLegacyTeamCompletionAction, coordinatorGrantScopeMembershipAction, coordinatorImportInviteAction, coordinatorListBootstrapGrantsAction, coordinatorListConsumedTeamInvitesAction, coordinatorListDevicesAction, coordinatorListGroupsAction, coordinatorListJoinRequestsAction, coordinatorListLegacyTeamCompletionsAction, coordinatorListReviewedRecipientInviteEvidenceAction, coordinatorListScopeMembershipsAction, coordinatorListScopesAction, coordinatorRemoveDeviceAction, coordinatorRenameDeviceAction, coordinatorRenameGroupAction, coordinatorReviewJoinRequestAction, coordinatorRevokeBootstrapGrantAction, coordinatorRevokeScopeMembershipAction, coordinatorStatusSnapshot, coordinatorUnarchiveGroupAction, coordinatorUpdateScopeAction, countShareableProjectMemories, createCoordinatorReciprocalApproval, decodeInvitePayload, dedupeOrderedIds, defaultSpaceScopeIdForGroup, deleteProjectScopeSettingsMapping, deriveLegacyTeamSetupCompletionManifest, detectInstallKind, deterministicPolicyTeamId, diagnoseStalePeerReceivedRows, discoverLegacyTeamCandidates, dispatchFileContextTransport, ensureDeviceIdentity, executeShareProvisioning, extractInvitePayload, extractReplicationOps, filterReplicationOpsForSyncWithStatus, fingerprintPublicKey, formatHostPort, friendlyDeviceName, fromJson, generateWithOpenCodeV2, getCodememConfigPath, getCodememEnvOverrideValues, getCodememEnvOverrides, getCoordinatorEnrollmentReconciliationIssueSummary, getCoordinatorGroupPreference, getEffectiveCachedScopeAuthorization, getLegacyTeamSetupDraft, getRecipientPolicyAuthorityState, getSemanticIndexDiagnostics, getSyncResetState, getUpdateStatus, ingestRawEvents, inspectFreshLegacyTeamSetupActivation, inspectLegacyTeamSetupActivation, inviteTokenDigest, isAutomaticRecallMeasurement, isLegacyTeamCandidateSelectable, isLegacyTeamSetupProjectMappingIdentity, isPeerTrustBindingCompatible, isProjectSyncEnablementError, isScopedSyncCapability, judgeDistillReport, legacyTeamCandidateId, legacyTeamCandidateProjectInventory, legacyTeamCanonicalProjectRef, legacyTeamDeviceRef, legacyTeamResolvedProjectRef, legacyTeamSetupApiErrorCode, linkCoordinatorAccount, listAuthorizedScopesForPeer, listCoordinatorJoinRequests, listDeviceIdentityInventory, listInboundScopeRejections, listLegacyRecipientPolicyProjections, listMaintenanceJobs, listObserverProviderOptions, listOpenCodeV2Models, listPerPeerScopeSyncState, listProjectScopeCandidates, listProjectScopeInventory, listProjectScopeSettingsMappings, listRecipientPolicyIntent, listRecipientPolicyReview, listSharingDomainSettingsScopes, loadMemorySnapshotPageForPeer, loadPublicKey, loadReplicationOpsForPeer, loadRuntimeSigningPublicKey, lookupCoordinatorPeers, memoryFilterValueMatchesType, mergeAddresses, migrateRecipientPolicyIntent, mutateCodememConfigFile, negotiateSyncCapability, normalizeAddress, normalizeCoordinatorAccountLinkOrigin, normalizeHumanPresentationName, normalizeSyncCapability, normalizeSyncFeatures, normalizeTeammateName, parseAcceptedProjectIntent, parseBootstrapExpiry, parseFileContextTransportRequest, parsePositiveMemoryId, parseReassignScopePayload, parseRecipientPolicyEdgeCommitRequest, parseStrictInteger, parseSyncScopeRequest, persistShareOperation, personalScopeGrantStatusForPeer, planShareOperation, previewDeviceIdentityBindings, previewLegacyTeamSetupActivation, previewRecipientPolicyEdges, previewRecipientPolicyOnboarding, previewRecipientPolicyOnboardingFromReviewedIntent, probeAvailableCredentials, projectMatchesFilter, projectShareLifecycle, promptPackArtifactFingerprint, readAccountLinkDevice, readCodememConfigFile, readCoordinatorAccountChangeCapabilities, readCoordinatorAccountLinkStatus, readCoordinatorSyncConfig, reassignProjectScopeInventoryProject, recipientInviteAuthoritativeIdentityId, recipientPolicyDigest, recipientReviewedIntentDigest, reconcileCoordinatorEnrollmentSnapshot, reconcileRecipientPolicyProject, reconcileShareOperationAcceptance, reconstructLegacyTeamSetupCompletionManifest, recordAutomaticRecall, recordHighestObservedDirectSignatureVersion, recordNonce, recordPromptPackArtifacts, recordPromptPackTerminal, refreshAuthorizedCoordinatorPeerTrust, refreshConfiguredScopeMembershipCache, refreshLegacyTeamCandidate, rejectInboundScopeFailures, renameRecipientPolicyTeam, replayLegacyTeamSetupActivation, repositoryIdentitiesByWorkspace, repositoryIdentityForWorkspace, requestJson, requireLegacyTeamSetupAccessDeltaWithinLimit, resolveCodememConfigPath, resolveDbPath, resolveObserverDefaultModel, resolveObserverRuntime, resolveProject, resolveProjectRoot, resolveRecipientPolicyReview, resolveRecipientPolicyReviewBulk, resolveVisibleScopeIds, runSyncPass, schema, scopeAuthorizationFailureReason, serializeRecipientPolicyCoordinatorGroupMutation, serializeRecipientPolicyPublicationMutation, serializeRecipientPolicyTeamMutation, setLegacyTeamSetupDeviceAssignment, setLegacyTeamSetupDeviceDecision, setLegacyTeamSetupProjectMapping, summarizeInboundScopeRejections, summaryLikeSqlPredicate, supportsSyncFeature, syncScopeResetRequiredPayload, toJson, tryUpdateRetrievalDelivery, updatePeerAddresses, upsertCoordinatorGroupPreference, upsertProjectScopeSettingsMappings, validateLegacyTeamSetupCompletionManifest, validateLegacyTeamSetupCompletionManifestBinding, validateRawEvents, verifyDirectPeerSignature, verifyRecipientReviewedIntent, verifySignature, wakeRecipientPoliciesForIdentities, wakeRecipientPoliciesForProjectIdentities } from "@codemem/core";
1
+ import { closeSync, existsSync, fstatSync, fsyncSync, linkSync, lstatSync, mkdirSync, openSync, readFileSync, statSync, unlinkSync, writeFileSync } from "node:fs";
2
+ import { basename, dirname, isAbsolute, join, posix, resolve, win32 } from "node:path";
3
+ import { ACCESS_CLEANUP_OP_TYPE, CodememConfigMutationError, CoordinatorAccountLinkError, CoordinatorReciprocalApprovalRequestChangedError, DEFAULT_TIME_WINDOW_S, FILE_CONTEXT_TRANSPORT_MAX_BYTES, LEGACY_SHARED_REVIEW_SCOPE_ID, LOCAL_DEFAULT_SCOPE_ID, LOCAL_SYNC_CAPABILITY, LOCAL_SYNC_FEATURES, LegacyTeamSetupAdditiveConvergenceError, LegacyTeamSetupRosterCapacityError, MEMORY_FILTER_FIELD_TYPES, MEMORY_FILTER_NAMES, MEMORY_KIND_DESCRIPTIONS, MemoryStore, ObserverClient, PROMPT_TRANSPORT_PROTOCOL_RANGE, REMEMBER_MEMORY_KINDS, RICH_TIER_ANTHROPIC_DEFAULTS, RICH_TIER_DEFAULTS, RawEventIngestValidationError, RecipientPolicyEdgeRequestError, RecipientPolicyTeamRenameError, RemoteCoordinatorRequestError, SCOPE_MEMBERSHIP_REVOCATION_LIMITATION, SIMPLE_TIER_ANTHROPIC_DEFAULTS, SIMPLE_TIER_DEFAULTS, SYNC_AUTHORIZATION_REFRESH_HEADER, SYNC_CAPABILITY_HEADER, SYNC_FEATURES_HEADER, SYNC_SCOPE_QUERY_PARAM, VERSION, VERSION as VERSION$1, VIEWER_IDENTITY_TARGET_KEYS, VIEWER_SERVICE_DISCRIMINATOR, addSyncScopeToBoundary, analyzeProjectScopeMappingChangeGuardrails, analyzeProjectScopeMappingChangesGuardrails, analyzeProjectScopeMappingDeletionGuardrails, applyLegacyTeamSetupCompletionManifest, applyLegacyTeamSetupCompletionManifestAndReturnActivation, applyReplicationOps, areLegacyTeamSetupCompletionPolicyFactsAdditivelyCompatible, automaticRecallHealth, buildAuthHeaders, buildBaseUrl, buildDirectPeerAuthHeaders, buildDistillReport, buildFilterBranchesWithContext, buildFilterClausesWithContext, buildPiFlushSignalFromEvent, buildRawEventEnvelopeFromCodexHook, buildRawEventEnvelopeFromHook, buildRawEventEnvelopeFromPiEvent, buildViewerIdentityTarget, canonicalCoordinatorLegacyTeamCompletionManifestJson, canonicalMemoryKind, canonicalRepositoryProjectIdentity, canonicalWorkspaceIdentity, captureAccountOwnerProfilePins, changeCoordinatorAccount, claimRecipientPolicyActorMutations, claimRecipientPolicyPublicationMutation, classifyRecordedSyncFailure, cleanupNonces, clearLegacyTeamSetupDeviceDecision, clonePromptPackAttempt, coerceObserverCommand, commitDeviceIdentityBindings, commitRecipientPolicyEdges, containLegacyTeamSetupCompletionConflict, coordinatorArchiveGroupAction, coordinatorAuthControllerReviewAction, coordinatorCreateAddDeviceInviteAction, coordinatorCreateGroupAction, coordinatorCreateInviteAction, coordinatorCreateLegacyTeamCompletionAction, coordinatorCreateScopeAction, coordinatorDisableDeviceAction, coordinatorEnableDeviceAction, coordinatorGetLegacyTeamCompletionAction, coordinatorGrantScopeMembershipAction, coordinatorImportInviteAction, coordinatorListBootstrapGrantsAction, coordinatorListConsumedTeamInvitesAction, coordinatorListDevicesAction, coordinatorListGroupsAction, coordinatorListJoinRequestsAction, coordinatorListLegacyTeamCompletionsAction, coordinatorListReviewedRecipientInviteEvidenceAction, coordinatorListScopeMembershipsAction, coordinatorListScopesAction, coordinatorRemoveDeviceAction, coordinatorRenameDeviceAction, coordinatorRenameGroupAction, coordinatorReviewJoinRequestAction, coordinatorRevokeBootstrapGrantAction, coordinatorRevokeScopeMembershipAction, coordinatorStatusSnapshot, coordinatorUnarchiveGroupAction, coordinatorUpdateScopeAction, countShareableProjectMemories, createCoordinatorReciprocalApproval, decodeInvitePayload, dedupeOrderedIds, defaultSpaceScopeIdForGroup, deleteProjectScopeSettingsMapping, deriveLegacyTeamSetupCompletionManifest, detectInstallKind, deterministicPolicyTeamId, diagnoseStalePeerReceivedRows, discoverLegacyTeamCandidates, dispatchFileContextTransport, ensureDeviceIdentity, executeShareProvisioning, extractInvitePayload, extractReplicationOps, filterReplicationOpsForSyncWithStatus, fingerprintPublicKey, formatHostPort, friendlyDeviceName, fromJson, generateWithOpenCodeV2, getCodememConfigPath, getCodememEnvOverrideValues, getCodememEnvOverrides, getCoordinatorEnrollmentReconciliationIssueSummary, getCoordinatorGroupPreference, getEffectiveCachedScopeAuthorization, getLegacyTeamSetupDraft, getRecipientPolicyAuthorityState, getSemanticIndexDiagnostics, getSyncResetState, getUpdateStatus, ingestRawEvents, inspectFreshLegacyTeamSetupActivation, inspectLegacyTeamSetupActivation, inviteTokenDigest, isAutomaticRecallMeasurement, isLegacyTeamCandidateSelectable, isLegacyTeamSetupProjectMappingIdentity, isPeerTrustBindingCompatible, isProjectSyncEnablementError, isScopedSyncCapability, judgeDistillReport, legacyTeamCandidateId, legacyTeamCandidateProjectInventory, legacyTeamCanonicalProjectRef, legacyTeamDeviceRef, legacyTeamResolvedProjectRef, legacyTeamSetupApiErrorCode, linkCoordinatorAccount, listAuthorizedScopesForPeer, listCoordinatorJoinRequests, listDeviceIdentityInventory, listInboundScopeRejections, listLegacyRecipientPolicyProjections, listMaintenanceJobs, listObserverProviderOptions, listOpenCodeV2Models, listPerPeerScopeSyncState, listProjectScopeCandidates, listProjectScopeInventory, listProjectScopeSettingsMappings, listRecipientPolicyIntent, listRecipientPolicyReview, listSharingDomainSettingsScopes, loadMemorySnapshotPageForPeer, loadPublicKey, loadReplicationOpsForPeer, loadRuntimeSigningPublicKey, lookupCoordinatorPeers, memoryFilterValueMatchesType, mergeAddresses, migrateRecipientPolicyIntent, mutateCodememConfigFile, negotiateSyncCapability, normalizeAddress, normalizeCoordinatorAccountLinkOrigin, normalizeCoordinatorLegacyTeamCompletionManifest, normalizeHumanPresentationName, normalizeSyncCapability, normalizeSyncFeatures, normalizeTeammateName, parseAcceptedProjectIntent, parseBootstrapExpiry, parseFileContextTransportRequest, parsePositiveMemoryId, parseReassignScopePayload, parseRecipientPolicyEdgeCommitRequest, parseStrictInteger, parseSyncScopeRequest, persistShareOperation, personalScopeGrantStatusForPeer, planShareOperation, previewDeviceIdentityBindings, previewLegacyTeamSetupActivation, previewRecipientPolicyEdges, previewRecipientPolicyOnboarding, previewRecipientPolicyOnboardingFromReviewedIntent, probeAvailableCredentials, projectMatchesFilter, projectShareLifecycle, promptPackArtifactFingerprint, readAccountLinkDevice, readAccountOwnerAssociation, readCodememConfigFile, readCoordinatorAccountChangeCapabilities, readCoordinatorAccountLinkStatus, readCoordinatorResolvedAccountOwnerReceiptStatus, readCoordinatorResolvedAccountOwnerStatus, readCoordinatorSyncConfig, reassignProjectScopeInventoryProject, recipientInviteAuthoritativeIdentityId, recipientPolicyDigest, recipientReviewedIntentDigest, reconcileCoordinatorEnrollmentSnapshot, reconcileRecipientPolicyProject, reconcileShareOperationAcceptance, reconstructLegacyTeamSetupCompletionManifest, recordAutomaticRecall, recordHighestObservedDirectSignatureVersion, recordNonce, recordPromptPackArtifacts, recordPromptPackTerminal, refreshAuthorizedCoordinatorPeerTrust, refreshConfiguredScopeMembershipCache, refreshLegacyTeamCandidate, rejectInboundScopeFailures, renameRecipientPolicyTeam, replayLegacyTeamSetupActivation, repositoryIdentitiesByWorkspace, repositoryIdentityForWorkspace, requestJson, requireLegacyTeamSetupAccessDeltaWithinLimit, resolveCodememConfigPath, resolveDbPath, resolveObserverDefaultModel, resolveObserverRuntime, resolveProject, resolveProjectRoot, resolveRecipientPolicyReview, resolveRecipientPolicyReviewBulk, resolveVisibleScopeIds, runSyncPass, schema, scopeAuthorizationFailureReason, searchPiSessions, serializeRecipientPolicyCoordinatorGroupMutation, serializeRecipientPolicyPublicationMutation, serializeRecipientPolicyTeamMutation, setLegacyTeamSetupDeviceAssignment, setLegacyTeamSetupDeviceDecision, setLegacyTeamSetupProjectMapping, summarizeInboundScopeRejections, summaryLikeSqlPredicate, supportsSyncFeature, syncScopeResetRequiredPayload, toJson, tryUpdateRetrievalDelivery, updatePeerAddresses, upsertCoordinatorGroupPreference, upsertProjectScopeSettingsMappings, validateLegacyTeamSetupCompletionManifest, validateLegacyTeamSetupCompletionManifestBinding, validateRawEvents, verifyDirectPeerSignature, verifyRecipientReviewedIntent, verifySignature, wakeRecipientPoliciesForIdentities, wakeRecipientPoliciesForProjectIdentities } from "@codemem/core";
4
4
  import { serveStatic } from "@hono/node-server/serve-static";
5
5
  import { Hono } from "hono";
6
6
  import { createCipheriv, createDecipheriv, createHash, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
7
7
  import { createMiddleware } from "hono/factory";
8
8
  import { RateLimiter } from "limiter";
9
- import { and, count, desc, eq, inArray, max, ne } from "drizzle-orm";
9
+ import { and, count, desc, eq, inArray, max, ne, sql } from "drizzle-orm";
10
10
  import { drizzle } from "drizzle-orm/better-sqlite3";
11
11
  import { homedir, hostname, networkInterfaces } from "node:os";
12
12
  import * as z from "zod";
13
13
  import { chmod, link, mkdir, open, readFile, readdir, rm, stat } from "node:fs/promises";
14
+ import "better-sqlite3";
15
+ import "sqlite-vec";
16
+ import { index, integer, primaryKey, real, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
14
17
  //#region src/routes/account.ts
15
18
  /** Mounted only alongside the account request middleware. */
16
19
  function accountRoutes(getSession) {
@@ -329,6 +332,7 @@ var InProcessAccountLinkRegistry = class {
329
332
  #shuttingDown = false;
330
333
  #closing = null;
331
334
  #uncertainOwner = null;
335
+ #recoveryOwner = null;
332
336
  constructor(options) {
333
337
  this.#options = options;
334
338
  this.#now = options.now ?? Date.now;
@@ -484,6 +488,22 @@ var InProcessAccountLinkRegistry = class {
484
488
  busySlot.lifecycle ??= Symbol();
485
489
  return busySlot.lifecycle;
486
490
  }
491
+ tryReserveRecovery() {
492
+ if (this.#shuttingDown || this.#inProgress()) return null;
493
+ if (this.#shuttingDown || busySlot.owner) return null;
494
+ const owner = Symbol();
495
+ busySlot.owner = owner;
496
+ busySlot.lifecycle = Symbol();
497
+ this.#recoveryOwner = owner;
498
+ return {
499
+ isCurrent: () => !this.#shuttingDown && this.#recoveryOwner === owner && busySlot.owner === owner,
500
+ release: () => {
501
+ if (this.#recoveryOwner !== owner) return;
502
+ this.#recoveryOwner = null;
503
+ releaseBusyOwner(owner);
504
+ }
505
+ };
506
+ }
487
507
  get(operationId) {
488
508
  this.#cleanup();
489
509
  const job = this.#jobs.get(operationId);
@@ -529,6 +549,10 @@ var InProcessAccountLinkRegistry = class {
529
549
  close() {
530
550
  if (this.#closing) return this.#closing;
531
551
  this.#shuttingDown = true;
552
+ if (this.#recoveryOwner) {
553
+ releaseBusyOwner(this.#recoveryOwner);
554
+ this.#recoveryOwner = null;
555
+ }
532
556
  for (const job of this.#jobs.values()) {
533
557
  this.#clearUrl(job);
534
558
  if (!terminal(job)) {
@@ -554,17 +578,129 @@ function createAccountLinkRegistry(options) {
554
578
  return new InProcessAccountLinkRegistry(options);
555
579
  }
556
580
  //#endregion
581
+ //#region src/account/owner-status.ts
582
+ /** The coordinator ID comes from the first signed actor-status read, never the origin. */
583
+ function readOwnerAssociation(context, coordinatorId) {
584
+ if (context.publicKeyHash === void 0) return null;
585
+ const before = statSync(context.dbPath, { bigint: true });
586
+ const device = readAccountLinkDevice(context.dbPath);
587
+ const profile = {
588
+ ...context,
589
+ publicKey: device.publicKey,
590
+ actorId: context.identityId,
591
+ coordinatorId
592
+ };
593
+ const expectedProfilePins = captureAccountOwnerProfilePins(profile);
594
+ const association = readAccountOwnerAssociation(profile, { expectedProfilePins }) ?? readAccountOwnerAssociation(profile);
595
+ const after = statSync(context.dbPath, { bigint: true });
596
+ if (!before.isFile() || before.dev !== after.dev || before.ino !== after.ino || after.dev.toString() !== context.fileIdentity.dev || after.ino.toString() !== context.fileIdentity.ino || device.deviceId !== context.deviceId || createHash("sha256").update(device.publicKey).digest("hex") !== context.publicKeyHash || device.fingerprint !== context.fingerprint) throw new Error("account_owner_association_invalid");
597
+ return association;
598
+ }
599
+ function ownerUnavailable(view, code) {
600
+ return {
601
+ ...withoutOwnerCapabilities(view),
602
+ remote: {
603
+ kind: "unavailable",
604
+ code
605
+ },
606
+ canLink: false,
607
+ blockedReason: code === "context_changed" ? "status_unavailable" : "review_required"
608
+ };
609
+ }
610
+ function withoutOwnerCapabilities(view) {
611
+ const { managementActions, unlinkTarget, accountOwner, ownerProjection, ...local } = view;
612
+ return local;
613
+ }
614
+ function ownerProfile(value) {
615
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
616
+ const source = value;
617
+ const profile = {};
618
+ for (const [field, limit] of [
619
+ ["displayName", 256],
620
+ ["email", 320],
621
+ ["pictureUrl", 2048]
622
+ ]) {
623
+ const text = source[field];
624
+ if (text === void 0) continue;
625
+ if (typeof text !== "string" || !text.trim() || text.length > limit || /[\p{Cc}\p{Cf}\p{Cs}]/u.test(text)) return null;
626
+ if (field === "pictureUrl" && !safeOwnerPicture(text)) return null;
627
+ profile[field] = text;
628
+ }
629
+ return profile;
630
+ }
631
+ function safeOwnerPicture(text) {
632
+ try {
633
+ const url = new URL(text);
634
+ return url.protocol === "https:" && url.hostname === "lh3.googleusercontent.com" && !url.username && !url.password && !url.port;
635
+ } catch {
636
+ return false;
637
+ }
638
+ }
639
+ function associatedOwnerView(view, context, association, remote) {
640
+ const contextId = createHash("sha256").update(JSON.stringify({
641
+ version: "account-owner-view-v1",
642
+ context,
643
+ association
644
+ })).digest("hex");
645
+ const base = {
646
+ ...withoutOwnerCapabilities(view),
647
+ contextId
648
+ };
649
+ if (remote?.kind !== "owner_status" || !remote.status || remote.status.version !== 1 || remote.status.coordinatorId !== association.coordinatorId || remote.status.groupId !== context.groupId || remote.status.deviceId !== context.deviceId || remote.status.fingerprint !== context.fingerprint || remote.status.ownerIdentity !== association.ownerIdentityId || remote.status.state !== "owner_confirmed") return ownerUnavailable(base, "account_owner_association_invalid");
650
+ const status = remote.status;
651
+ const profile = status.profileState === "linked" ? ownerProfile(status.profile) : null;
652
+ if (status.profileState === "linked" && profile === null || status.profileState !== "linked" && (status.profileState !== "account_unlinked" && status.profileState !== "unavailable" || status.profile !== null)) return ownerUnavailable(base, "account_owner_association_invalid");
653
+ const subject = {
654
+ version: 1,
655
+ coordinatorId: status.coordinatorId,
656
+ groupId: status.groupId,
657
+ deviceId: status.deviceId,
658
+ fingerprint: status.fingerprint,
659
+ state: "owner_confirmed",
660
+ ownerIdentity: status.ownerIdentity
661
+ };
662
+ let confirmed;
663
+ if (status.profileState === "linked" && profile) confirmed = {
664
+ ...subject,
665
+ profileState: "linked",
666
+ profile
667
+ };
668
+ else if (status.profileState === "account_unlinked" || status.profileState === "unavailable") confirmed = {
669
+ ...subject,
670
+ profileState: status.profileState,
671
+ profile: null
672
+ };
673
+ else return ownerUnavailable(base, "account_owner_association_invalid");
674
+ return {
675
+ ...base,
676
+ accountOwner: {
677
+ identityId: association.ownerIdentityId,
678
+ memoryActorId: context.identityId
679
+ },
680
+ remote: { kind: "not_checked" },
681
+ ownerProjection: {
682
+ kind: "resolved_account_owner",
683
+ status: confirmed
684
+ },
685
+ canLink: false,
686
+ blockedReason: profile ? "already_linked" : "status_unavailable"
687
+ };
688
+ }
689
+ //#endregion
557
690
  //#region src/account/status.ts
558
- function attachOperation(view, registry) {
559
- const operation = view.contextId ? registry?.forContext(view.contextId) ?? null : null;
691
+ function attachOperation(view, registry, operationContextId = view.contextId) {
692
+ const operation = operationContextId ? registry?.forContext(operationContextId) ?? null : null;
693
+ const operationContext = operation && operationContextId && operationContextId !== view.contextId ? { operationContextId } : {};
560
694
  if (registry?.hasActive()) return {
561
695
  ...view,
696
+ ...operationContext,
562
697
  operation,
563
698
  canLink: false,
564
699
  blockedReason: "operation_active"
565
700
  };
566
701
  return {
567
702
  ...view,
703
+ ...operationContext,
568
704
  operation
569
705
  };
570
706
  }
@@ -668,10 +804,57 @@ async function readAccountStatus(options, groupId, signal, readOptions = {}) {
668
804
  },
669
805
  blockedReason: "status_unavailable"
670
806
  }, options.registry);
807
+ return finishAccountStatus(options, initial.context, fresh, remote, signal);
808
+ }
809
+ async function finishAccountStatus(options, context, fresh, remote, signal) {
671
810
  const currentView = applyRemote(accountLocalView(fresh), remote);
672
- await attachManagementActions(options, initial.context, currentView, signal);
811
+ if (remote.kind === "status") {
812
+ const associated = await readAssociatedOwner(options, context, currentView, remote, signal);
813
+ if (associated) return attachOperation(associated, options.registry, context.contextId);
814
+ }
815
+ await attachManagementActions(options, context, currentView, signal);
816
+ if (remote.kind === "status") try {
817
+ if (readOwnerAssociation(context, remote.status.coordinatorId)) return attachOperation(ownerUnavailable(accountLocalView(fresh), "context_changed"), options.registry);
818
+ } catch {
819
+ return attachOperation(ownerUnavailable(accountLocalView(fresh), "account_owner_association_invalid"), options.registry);
820
+ }
673
821
  return attachOperation(currentView, options.registry);
674
822
  }
823
+ async function readAssociatedOwner(options, context, view, actorRemote, signal) {
824
+ const local = {
825
+ ...view,
826
+ remote: { kind: "not_checked" },
827
+ canLink: false
828
+ };
829
+ try {
830
+ const association = readOwnerAssociation(context, actorRemote.status.coordinatorId);
831
+ if (!association) return null;
832
+ const before = options.readContext(context.groupId);
833
+ if ("error" in before || !before.context || !sameAuthority(context, before.context)) return ownerUnavailable(local, "context_changed");
834
+ const { dbPath, keysDir, groupId, coordinatorUrl } = context;
835
+ let remote;
836
+ try {
837
+ remote = await (options.readRemoteOwnerStatus ?? readCoordinatorResolvedAccountOwnerStatus)({
838
+ dbPath,
839
+ keysDir,
840
+ groupId,
841
+ coordinatorUrl,
842
+ ownerIdentityId: association.ownerIdentityId,
843
+ signal
844
+ });
845
+ } catch {
846
+ remote = {
847
+ kind: "unavailable",
848
+ code: "coordinator_unreachable"
849
+ };
850
+ }
851
+ const after = options.readContext(context.groupId);
852
+ if (signal.aborted || JSON.stringify(before) !== JSON.stringify(after) || JSON.stringify(association) !== JSON.stringify(readOwnerAssociation(context, association.coordinatorId))) return ownerUnavailable(local, "context_changed");
853
+ return associatedOwnerView(local, context, association, remote);
854
+ } catch {
855
+ return ownerUnavailable(local, "account_owner_association_invalid");
856
+ }
857
+ }
675
858
  async function attachManagementActions(options, context, view, signal) {
676
859
  if (view.remote.kind !== "status" || view.remote.state !== "linked" || !view.remote.identityMatches) return;
677
860
  const read = options.readRemoteCapabilities ?? (options.readRemoteStatus ? null : readCoordinatorAccountChangeCapabilities);
@@ -711,7 +894,7 @@ async function attachManagementActions(options, context, view, signal) {
711
894
  }
712
895
  //#endregion
713
896
  //#region src/routes/account-operations.ts
714
- var ROOT = "/api/account/link-operations";
897
+ var ROOT$1 = "/api/account/link-operations";
715
898
  function validString(value) {
716
899
  return typeof value === "string" && value.length > 0 && value.length <= 256 && value.trim() === value && !/[\p{Cc}\p{Cf}\p{Cs}]/u.test(value);
717
900
  }
@@ -720,7 +903,7 @@ function noBody(request) {
720
903
  return request.body === null && (length === null || length === "0") && !request.headers.has("Transfer-Encoding");
721
904
  }
722
905
  /** Cap both bytes and elapsed time; cancellation must not wait on an uncooperative stream. */
723
- async function readBody(request, keys, optional = []) {
906
+ async function readBody$1(request, keys, optional = []) {
724
907
  if (!/^application\/json(?:\s*;\s*charset\s*=\s*(?:utf-8|"utf-8"))?\s*$/i.test(request.headers.get("Content-Type") ?? "")) return null;
725
908
  const reader = request.body?.getReader();
726
909
  if (!reader) return null;
@@ -767,7 +950,7 @@ function unlinkTargetChanged(body, view) {
767
950
  return body.intent === "disconnect" && body.expectedLinkId !== view.unlinkTarget;
768
951
  }
769
952
  async function startOperation(c, options) {
770
- const body = await readBody(c.req.raw, [
953
+ const body = await readBody$1(c.req.raw, [
771
954
  "groupId",
772
955
  "contextId",
773
956
  "authority",
@@ -823,7 +1006,7 @@ function beginCurrentOperation(c, options, body, view, expectedCoordinatorId, ch
823
1006
  }
824
1007
  async function performOperation(c, options) {
825
1008
  const { id, action } = c.req.param();
826
- if (!validString(id) || action !== "browser-url" && action !== "cancel" || !await readBody(c.req.raw, [])) return c.json({ error: "account_invalid_request" }, 400);
1009
+ if (!validString(id) || action !== "browser-url" && action !== "cancel" || !await readBody$1(c.req.raw, [])) return c.json({ error: "account_invalid_request" }, 400);
827
1010
  const operation = options.registry.get(id);
828
1011
  if (!operation) return c.json({ error: "account_operation_not_found" }, 404);
829
1012
  if (action === "cancel") {
@@ -849,10 +1032,10 @@ function accountOperationRoutes(options) {
849
1032
  if ([...new URL(c.req.url).searchParams].length) return c.json({ error: "account_invalid_request" }, 400);
850
1033
  await next();
851
1034
  };
852
- app.use(ROOT, rejectQuery);
853
- app.use(`${ROOT}/*`, rejectQuery);
854
- app.post(ROOT, (c) => startOperation(c, options));
855
- app.get(`${ROOT}/:id`, (c) => {
1035
+ app.use(ROOT$1, rejectQuery);
1036
+ app.use(`${ROOT$1}/*`, rejectQuery);
1037
+ app.post(ROOT$1, (c) => startOperation(c, options));
1038
+ app.get(`${ROOT$1}/:id`, (c) => {
856
1039
  if (!noBody(c.req.raw) || !validString(c.req.param("id"))) return c.json({ error: "account_invalid_request" }, 400);
857
1040
  const operation = options.registry.get(c.req.param("id"));
858
1041
  if (!operation) return c.json({ error: "account_operation_not_found" }, 404);
@@ -862,7 +1045,338 @@ function accountOperationRoutes(options) {
862
1045
  current: isCurrent(options, operation)
863
1046
  });
864
1047
  });
865
- app.post(`${ROOT}/:id/:action`, (c) => performOperation(c, options));
1048
+ app.post(`${ROOT$1}/:id/:action`, (c) => performOperation(c, options));
1049
+ return app;
1050
+ }
1051
+ //#endregion
1052
+ //#region src/account/owner-recovery-evidence.ts
1053
+ var RECOVERY_SCOPE = "historical_included_owner_labels_only";
1054
+ var RECOVERY_REASON = /^[a-z][a-z0-9_]{0,119}(?:: [\x20-\x7e]{1,240})?$/;
1055
+ var AccountOwnerRecoveryError = class extends Error {
1056
+ code;
1057
+ constructor(code = "invalid") {
1058
+ super("account_owner_recovery_invalid");
1059
+ this.code = code;
1060
+ }
1061
+ };
1062
+ function requireRecovery(condition, code = "invalid") {
1063
+ if (!condition) throw new AccountOwnerRecoveryError(code);
1064
+ }
1065
+ function recoveryId(value) {
1066
+ return typeof value === "string" && value.length > 0 && value.length <= 256 && value.trim() === value && !/[\p{Cc}\p{Cf}\p{Cs}]/u.test(value);
1067
+ }
1068
+ function recoveryHash(value) {
1069
+ return typeof value === "string" && /^[a-f0-9]{64}$/.test(value);
1070
+ }
1071
+ function recoveryRecord(value) {
1072
+ requireRecovery(value && typeof value === "object" && !Array.isArray(value));
1073
+ return value;
1074
+ }
1075
+ function exactRecoveryFields(row, fields) {
1076
+ requireRecovery(Object.keys(row).length === fields.length && fields.every((key) => Object.hasOwn(row, key)));
1077
+ }
1078
+ function timestamp(value) {
1079
+ return typeof value === "string" && Number.isFinite(Date.parse(value));
1080
+ }
1081
+ function readWeakLabel(value) {
1082
+ const row = recoveryRecord(value);
1083
+ exactRecoveryFields(row, [
1084
+ "label",
1085
+ "kind",
1086
+ "group_id",
1087
+ "device_id",
1088
+ "evidence_ref",
1089
+ "effect"
1090
+ ]);
1091
+ requireRecovery(recoveryId(row.label) && recoveryId(row.group_id) && recoveryId(row.device_id) && recoveryId(row.evidence_ref));
1092
+ requireRecovery(row.kind === "legacy_included_owner_label" || row.kind === "consumed_project_actor_label");
1093
+ requireRecovery(row.effect === "account_owner_display_only");
1094
+ return {
1095
+ label: row.label,
1096
+ kind: row.kind,
1097
+ group_id: row.group_id,
1098
+ device_id: row.device_id,
1099
+ evidence_ref: row.evidence_ref,
1100
+ effect: row.effect
1101
+ };
1102
+ }
1103
+ function historyRows(value, selection, labels) {
1104
+ const row = recoveryRecord(value);
1105
+ requireRecovery(recoveryId(row.group_id) && recoveryId(row.candidate_ref) && timestamp(row.created_at));
1106
+ const manifest = normalizeCoordinatorLegacyTeamCompletionManifest(row.manifest);
1107
+ requireRecovery(manifest.coordinator_id === selection.profile.coordinatorId && manifest.candidate_ref === row.candidate_ref && manifest.version === row.manifest_version && manifest.completed_at === row.completed_at && legacyTeamCandidateId(manifest.coordinator_id, row.group_id) === manifest.candidate_ref && canonicalCoordinatorLegacyTeamCompletionManifestJson(manifest) === row.manifest_json);
1108
+ const groupId = row.group_id;
1109
+ return manifest.device_decisions.map((decision) => {
1110
+ let relation = "other";
1111
+ if (decision.device_id === selection.profile.deviceId) relation = "exact_subject";
1112
+ else if (labels.some((label) => label.kind === "legacy_included_owner_label" && label.group_id === groupId && label.device_id === decision.device_id && label.label === decision.identity_id && label.evidence_ref === manifest.source_digest)) relation = "alias";
1113
+ return {
1114
+ id: `${manifest.candidate_ref}:${decision.device_id}`,
1115
+ groupId,
1116
+ deviceId: decision.device_id,
1117
+ fingerprint: decision.key_fingerprint,
1118
+ identityId: decision.identity_id ?? "",
1119
+ assignment: decision.decision,
1120
+ relation,
1121
+ reason: "Retained canonical Team decision; display metadata only."
1122
+ };
1123
+ });
1124
+ }
1125
+ function receiptPart(value, idField) {
1126
+ const row = recoveryRecord(value);
1127
+ exactRecoveryFields(row, [
1128
+ "disposition",
1129
+ idField,
1130
+ "evidence_digest",
1131
+ "created_at"
1132
+ ]);
1133
+ const id = row[idField];
1134
+ requireRecovery(recoveryId(id) && recoveryHash(row.evidence_digest) && timestamp(row.created_at) && (row.disposition === "created" || row.disposition === "reused"));
1135
+ return {
1136
+ id,
1137
+ digest: row.evidence_digest
1138
+ };
1139
+ }
1140
+ function reviewReceipt(row) {
1141
+ requireRecovery(recoveryId(row.attestation_id));
1142
+ const source = receiptPart(row.recovery_receipt, "review_receipt_id");
1143
+ const resolution = receiptPart(row.owner_resolution, "resolution_id");
1144
+ return {
1145
+ attestationId: row.attestation_id,
1146
+ reviewReceiptId: source.id,
1147
+ reviewEvidenceDigest: source.digest,
1148
+ resolutionId: resolution.id,
1149
+ resolutionEvidenceDigest: resolution.digest
1150
+ };
1151
+ }
1152
+ function validateRecoveryReview(value, selection, groupId) {
1153
+ const row = recoveryRecord(value);
1154
+ const profile = selection.profile;
1155
+ requireRecovery(row.purpose === "existing_account_owner" && row.resolution_scope === "historical_included_owner_labels_only" && row.coordinator_id === profile.coordinatorId && row.group_id === groupId && row.device_id === profile.deviceId && row.fingerprint === profile.fingerprint && row.identity_id === selection.existingOwnerId);
1156
+ requireRecovery(Array.isArray(row.legacy_history) && row.legacy_history.length <= 500 && Array.isArray(row.reviewed_weak_labels) && row.reviewed_weak_labels.length <= 256 && Array.isArray(row.reasons) && row.reasons.every((reason) => typeof reason === "string"));
1157
+ const labels = row.reviewed_weak_labels.map(readWeakLabel);
1158
+ requireRecovery(new Set(labels.map((label) => JSON.stringify(label))).size === labels.length);
1159
+ const rows = row.legacy_history.flatMap((history) => historyRows(history, selection, labels));
1160
+ requireRecovery(row.reasons.length <= 8 && row.reasons.every((reason) => typeof reason === "string" && RECOVERY_REASON.test(reason)));
1161
+ const reasons = row.reasons;
1162
+ if (row.state === "needs_review") {
1163
+ requireRecovery(row.reasons.length > 0 && !Object.hasOwn(row, "owner_resolution_digest"));
1164
+ return {
1165
+ state: row.state,
1166
+ rows,
1167
+ labels,
1168
+ reasons
1169
+ };
1170
+ }
1171
+ requireRecovery((row.state === "ready" || row.state === "restored") && recoveryHash(row.owner_resolution_digest) && row.reasons.length === 0);
1172
+ const target = recoveryRecord(row.account_owner_target);
1173
+ requireRecovery(target.identity_id === selection.existingOwnerId && recoveryId(target.link_id) && recoveryId(target.auth_config_revision) && typeof target.created_at_ms === "number" && Number.isSafeInteger(target.created_at_ms));
1174
+ let receipt;
1175
+ if (row.state === "restored" || Object.hasOwn(row, "owner_resolution")) receipt = reviewReceipt(row);
1176
+ return {
1177
+ state: row.state,
1178
+ digest: row.owner_resolution_digest,
1179
+ receipt,
1180
+ rows,
1181
+ labels,
1182
+ reasons
1183
+ };
1184
+ }
1185
+ function replyGroups(row, selection) {
1186
+ exactRecoveryFields(row, [
1187
+ "version",
1188
+ "purpose",
1189
+ "scope",
1190
+ "coordinatorOrigin",
1191
+ "coordinatorId",
1192
+ "deviceId",
1193
+ "fingerprint",
1194
+ "ownerIdentityId",
1195
+ "groups"
1196
+ ]);
1197
+ const p = selection.profile;
1198
+ requireRecovery(row.version === 1 && row.purpose === "existing_account_owner" && row.scope === "historical_included_owner_labels_only" && row.coordinatorOrigin === p.coordinatorOrigin && row.coordinatorId === p.coordinatorId && row.deviceId === p.deviceId && row.fingerprint === p.fingerprint && row.ownerIdentityId === selection.existingOwnerId && Array.isArray(row.groups) && row.groups.length === selection.groups.length);
1199
+ return row.groups;
1200
+ }
1201
+ function parseRecoveryReply(text, selection) {
1202
+ requireRecovery(typeof text === "string" && Buffer.byteLength(text) <= 32768);
1203
+ const groups = replyGroups(recoveryRecord(JSON.parse(text)), selection);
1204
+ const receipts = /* @__PURE__ */ new Map();
1205
+ for (const input of groups) {
1206
+ const group = recoveryRecord(input);
1207
+ exactRecoveryFields(group, [
1208
+ "groupId",
1209
+ "attestationId",
1210
+ "reviewReceiptId",
1211
+ "reviewEvidenceDigest",
1212
+ "resolutionId",
1213
+ "resolutionEvidenceDigest"
1214
+ ]);
1215
+ requireRecovery(typeof group.groupId === "string" && selection.groups.includes(group.groupId) && !receipts.has(group.groupId));
1216
+ requireRecovery(recoveryId(group.attestationId) && recoveryId(group.reviewReceiptId) && recoveryId(group.resolutionId) && recoveryHash(group.reviewEvidenceDigest) && recoveryHash(group.resolutionEvidenceDigest));
1217
+ receipts.set(group.groupId, {
1218
+ attestationId: group.attestationId,
1219
+ reviewReceiptId: group.reviewReceiptId,
1220
+ reviewEvidenceDigest: group.reviewEvidenceDigest,
1221
+ resolutionId: group.resolutionId,
1222
+ resolutionEvidenceDigest: group.resolutionEvidenceDigest
1223
+ });
1224
+ }
1225
+ return receipts;
1226
+ }
1227
+ //#endregion
1228
+ //#region src/routes/account-owner-recovery.ts
1229
+ var ROOT = "/api/account/owner-recovery";
1230
+ var LIMITS = {
1231
+ preview: 65536,
1232
+ confirm: 1048576,
1233
+ import: 65536
1234
+ };
1235
+ function bodyLength(request) {
1236
+ requireRecovery(!request.headers.has("Transfer-Encoding"));
1237
+ const length = request.headers.get("Content-Length");
1238
+ if (length === null) return null;
1239
+ requireRecovery(/^(0|[1-9][0-9]*)$/.test(length));
1240
+ const parsed = Number(length);
1241
+ requireRecovery(Number.isSafeInteger(parsed));
1242
+ return parsed;
1243
+ }
1244
+ /** Limit actual UTF-8 bytes and elapsed time, regardless of transport metadata. */
1245
+ async function readBody(request, cap) {
1246
+ const declared = bodyLength(request);
1247
+ requireRecovery(declared === null || declared <= cap);
1248
+ requireRecovery(/^application\/json(?:\s*;\s*charset\s*=\s*(?:utf-8|"utf-8"))?\s*$/i.test(request.headers.get("Content-Type") ?? ""));
1249
+ const reader = request.body?.getReader();
1250
+ requireRecovery(reader);
1251
+ let timer;
1252
+ let stop = () => {};
1253
+ try {
1254
+ const expired = new Promise((_, reject) => {
1255
+ stop = () => reject(new AccountOwnerRecoveryError());
1256
+ timer = setTimeout(stop, 1e4);
1257
+ request.signal.addEventListener("abort", stop, { once: true });
1258
+ if (request.signal.aborted) stop();
1259
+ });
1260
+ const bytes = new Uint8Array(cap);
1261
+ let length = 0;
1262
+ while (true) {
1263
+ const chunk = await Promise.race([reader.read(), expired]);
1264
+ if (chunk.done) break;
1265
+ requireRecovery(length + chunk.value.byteLength <= cap);
1266
+ bytes.set(chunk.value, length);
1267
+ length += chunk.value.byteLength;
1268
+ }
1269
+ requireRecovery(!request.signal.aborted && (declared === null || declared === length));
1270
+ return recoveryRecord(JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, length))));
1271
+ } catch {
1272
+ throw new AccountOwnerRecoveryError();
1273
+ } finally {
1274
+ clearTimeout(timer);
1275
+ request.signal.removeEventListener("abort", stop);
1276
+ reader.cancel().catch(() => {});
1277
+ reader.releaseLock();
1278
+ }
1279
+ }
1280
+ function stringList(value) {
1281
+ requireRecovery(Array.isArray(value) && value.every(recoveryId));
1282
+ return value;
1283
+ }
1284
+ function profile(value) {
1285
+ const row = recoveryRecord(value);
1286
+ exactRecoveryFields(row, [
1287
+ "contextId",
1288
+ "memoryActorId",
1289
+ "deviceId",
1290
+ "fingerprint",
1291
+ "coordinatorOrigin",
1292
+ "coordinatorId",
1293
+ "configuredGroups"
1294
+ ]);
1295
+ const { contextId, memoryActorId, deviceId, fingerprint, coordinatorOrigin, coordinatorId } = row;
1296
+ requireRecovery(recoveryId(contextId) && recoveryId(memoryActorId) && recoveryId(deviceId) && recoveryId(fingerprint) && recoveryId(coordinatorOrigin) && recoveryId(coordinatorId));
1297
+ return {
1298
+ contextId,
1299
+ memoryActorId,
1300
+ deviceId,
1301
+ fingerprint,
1302
+ coordinatorOrigin,
1303
+ coordinatorId,
1304
+ configuredGroups: stringList(row.configuredGroups)
1305
+ };
1306
+ }
1307
+ function selection(row) {
1308
+ requireRecovery(recoveryId(row.existingOwnerId));
1309
+ return {
1310
+ profile: profile(row.profile),
1311
+ existingOwnerId: row.existingOwnerId,
1312
+ groups: stringList(row.groups)
1313
+ };
1314
+ }
1315
+ async function dispatch(c, service) {
1316
+ const request = c.req.raw;
1317
+ requireRecovery(!new URL(request.url).search && !request.signal.aborted);
1318
+ if (c.req.path === ROOT && request.method === "GET") {
1319
+ const length = bodyLength(request);
1320
+ requireRecovery(request.body === null && (length === null || length === 0));
1321
+ return c.json(await service.getProfile());
1322
+ }
1323
+ if (request.method !== "POST") return c.json({ error: "account_owner_recovery_invalid" }, 405);
1324
+ if (c.req.path === `${ROOT}/preview`) {
1325
+ const body = await readBody(request, LIMITS.preview);
1326
+ exactRecoveryFields(body, [
1327
+ "profile",
1328
+ "existingOwnerId",
1329
+ "groups",
1330
+ "requestId",
1331
+ "purpose"
1332
+ ]);
1333
+ requireRecovery(recoveryId(body.requestId) && (body.purpose === "review" || body.purpose === "check_status"));
1334
+ return c.json(await service.preview({
1335
+ ...selection(body),
1336
+ requestId: body.requestId,
1337
+ purpose: body.purpose
1338
+ }));
1339
+ }
1340
+ if (c.req.path === `${ROOT}/confirm`) {
1341
+ const body = await readBody(request, LIMITS.confirm);
1342
+ exactRecoveryFields(body, ["preview", "approvalDigest"]);
1343
+ requireRecovery(recoveryId(body.approvalDigest));
1344
+ return c.json(await service.confirm({
1345
+ preview: body.preview,
1346
+ approvalDigest: body.approvalDigest
1347
+ }));
1348
+ }
1349
+ if (c.req.path === `${ROOT}/import`) {
1350
+ const body = await readBody(request, LIMITS.import);
1351
+ exactRecoveryFields(body, ["selection", "replyText"]);
1352
+ const selected = recoveryRecord(body.selection);
1353
+ exactRecoveryFields(selected, [
1354
+ "profile",
1355
+ "existingOwnerId",
1356
+ "groups"
1357
+ ]);
1358
+ requireRecovery(typeof body.replyText === "string");
1359
+ return c.json(await service.importReply({
1360
+ selection: selection(selected),
1361
+ replyText: body.replyText
1362
+ }));
1363
+ }
1364
+ return c.json({ error: "account_owner_recovery_invalid" }, 404);
1365
+ }
1366
+ /** Mount only after createAccountGuard: this router grants no independent authority. */
1367
+ function accountOwnerRecoveryRoutes(service) {
1368
+ const app = new Hono();
1369
+ app.onError((error, c) => {
1370
+ if (!(error instanceof AccountOwnerRecoveryError)) return c.json({ error: "account_owner_recovery_unavailable" }, 503);
1371
+ return c.json({ error: `account_owner_recovery_${error.code}` }, {
1372
+ invalid: 400,
1373
+ busy: 409,
1374
+ context_changed: 409,
1375
+ unavailable: 503
1376
+ }[error.code]);
1377
+ });
1378
+ app.all(ROOT, (c) => dispatch(c, service));
1379
+ app.all(`${ROOT}/*`, (c) => dispatch(c, service));
866
1380
  return app;
867
1381
  }
868
1382
  //#endregion
@@ -2306,6 +2820,23 @@ function queryMemoryPage(store, options) {
2306
2820
  const ownedBySelf = store.buildOwnershipPredicate();
2307
2821
  return rows.map((row) => serializeMemoryRow(ownedBySelf, row));
2308
2822
  }
2823
+ async function handleLegacyPackRequest(c, getStore) {
2824
+ const store = getStore();
2825
+ const context = c.req.query("context") || "";
2826
+ if (!context) return c.json({ error: "context required" }, 400);
2827
+ const limit = queryInt(c.req.query("limit"), 10);
2828
+ const tokenBudgetStr = c.req.query("token_budget");
2829
+ let tokenBudget;
2830
+ if (tokenBudgetStr) {
2831
+ tokenBudget = parseStrictInteger(tokenBudgetStr) ?? void 0;
2832
+ if (tokenBudget === void 0) return c.json({ error: "token_budget must be int" }, 400);
2833
+ }
2834
+ const project = c.req.query("project") || void 0;
2835
+ const filters = {};
2836
+ if (project) filters.project = project;
2837
+ const pack = await store.buildMemoryPackAsync(context, limit, tokenBudget ?? null, filters, void 0, void 0, { signal: c.req.raw.signal });
2838
+ return c.json(pack);
2839
+ }
2309
2840
  function memoryRoutes(getStore) {
2310
2841
  const app = new Hono();
2311
2842
  app.get("/api/sessions", (c) => {
@@ -2431,25 +2962,7 @@ function memoryRoutes(getStore) {
2431
2962
  });
2432
2963
  }
2433
2964
  });
2434
- app.get("/api/pack", async (c) => {
2435
- const store = getStore();
2436
- {
2437
- const context = c.req.query("context") || "";
2438
- if (!context) return c.json({ error: "context required" }, 400);
2439
- const limit = queryInt(c.req.query("limit"), 10);
2440
- const tokenBudgetStr = c.req.query("token_budget");
2441
- let tokenBudget;
2442
- if (tokenBudgetStr) {
2443
- tokenBudget = parseStrictInteger(tokenBudgetStr) ?? void 0;
2444
- if (tokenBudget === void 0) return c.json({ error: "token_budget must be int" }, 400);
2445
- }
2446
- const project = c.req.query("project") || void 0;
2447
- const filters = {};
2448
- if (project) filters.project = project;
2449
- const pack = await store.buildMemoryPackAsync(context, limit, tokenBudget ?? null, filters);
2450
- return c.json(pack);
2451
- }
2452
- });
2965
+ app.get("/api/pack", (c) => handleLegacyPackRequest(c, getStore));
2453
2966
  app.post("/api/pack/trace", async (c) => {
2454
2967
  const store = getStore();
2455
2968
  const parsed = await c.req.json().catch(() => Symbol.for("invalid-json"));
@@ -2471,7 +2984,11 @@ function memoryRoutes(getStore) {
2471
2984
  const filters = {};
2472
2985
  if (project) filters.project = project;
2473
2986
  if (workingSetFiles.length > 0) filters.working_set_paths = workingSetFiles;
2474
- const trace = await store.buildMemoryPackTraceAsync(context, limit, tokenBudget, filters);
2987
+ const trace = await store.buildMemoryPackTraceAsync(context, limit, tokenBudget, filters, ...[
2988
+ void 0,
2989
+ void 0,
2990
+ { signal: c.req.raw.signal }
2991
+ ]);
2475
2992
  return c.json(trace);
2476
2993
  });
2477
2994
  app.get("/api/memory", (c) => {
@@ -2893,6 +3410,22 @@ function expandMemories(store, args) {
2893
3410
  }
2894
3411
  };
2895
3412
  }
3413
+ function piSessionSearchRoutes(getStore) {
3414
+ const searchApp = new Hono();
3415
+ searchApp.get("/api/pi/sessions/search", (c) => {
3416
+ const store = getStore();
3417
+ const query = c.req.query("query") ?? "";
3418
+ if (!query.trim()) return c.json({ error: "query required" }, 400);
3419
+ const result = searchPiSessions(store.db, query, {
3420
+ project: c.req.query("project"),
3421
+ session_id: c.req.query("session_id"),
3422
+ limit: queryInt(c.req.query("limit"), 10),
3423
+ snippet_chars: queryInt(c.req.query("snippet_chars"), 1200)
3424
+ });
3425
+ return c.json(result);
3426
+ });
3427
+ return searchApp;
3428
+ }
2896
3429
  function memoryToolRoutes(getStore) {
2897
3430
  const app = new Hono();
2898
3431
  app.post("/api/memories/remember", async (c) => {
@@ -3091,7 +3624,7 @@ function memoryToolRoutes(getStore) {
3091
3624
  return c.json({ error: msg }, 400);
3092
3625
  }
3093
3626
  });
3094
- return app;
3627
+ return app.route("/", piSessionSearchRoutes(getStore));
3095
3628
  }
3096
3629
  //#endregion
3097
3630
  //#region src/routes/observer-status.ts
@@ -3333,14 +3866,15 @@ function packRenderOptions(value) {
3333
3866
  ...value.compact_detail_count != null ? { compactDetailCount: value.compact_detail_count } : {}
3334
3867
  };
3335
3868
  }
3336
- function packRequestArgs(request) {
3869
+ function packRequestArgs(request, signal) {
3337
3870
  return [
3338
3871
  request.context,
3339
3872
  request.limit,
3340
3873
  request.tokenBudget,
3341
3874
  request.filters,
3342
3875
  request.renderOptions,
3343
- request.automaticContext
3876
+ request.automaticContext,
3877
+ { signal }
3344
3878
  ];
3345
3879
  }
3346
3880
  function packSchemaError(error) {
@@ -3528,11 +4062,9 @@ function packTransportRoutes(getStore) {
3528
4062
  const store = getStore();
3529
4063
  const target = validateViewerTarget(store, parsed, { requireCurrentIdentity: true });
3530
4064
  if (!target.ok) return c.json(target.body, target.status);
3531
- if (!request.attempt) {
3532
- const pack = await store.buildMemoryPackAsync(...packRequestArgs(request));
3533
- return c.json(pack);
3534
- }
3535
- const artifacts = await store.buildMemoryPackWithTraceAsync(...packRequestArgs(request));
4065
+ if (!request.attempt) return await handleUntracedPackRequest(c, store, request);
4066
+ const artifacts = await store.buildMemoryPackWithTraceAsync(...packRequestArgs(request, c.req.raw.signal));
4067
+ c.req.raw.signal.throwIfAborted();
3536
4068
  let ledgerArtifactFingerprint;
3537
4069
  try {
3538
4070
  ledgerArtifactFingerprint = promptPackArtifactFingerprint(store.db, request.context, request.filters, artifacts);
@@ -3556,6 +4088,11 @@ function packTransportRoutes(getStore) {
3556
4088
  app.post("/api/prompt-pack-ledger", (c) => handleLedgerRequest(c, getStore));
3557
4089
  return app;
3558
4090
  }
4091
+ async function handleUntracedPackRequest(c, store, request) {
4092
+ const pack = await store.buildMemoryPackAsync(...packRequestArgs(request, c.req.raw.signal));
4093
+ c.req.raw.signal.throwIfAborted();
4094
+ return c.json(pack);
4095
+ }
3559
4096
  //#endregion
3560
4097
  //#region src/raw-event-processing.ts
3561
4098
  function nudgeRawEventSessions(sweeper, sessions) {
@@ -3643,7 +4180,7 @@ async function writeDurableFile(path, contents) {
3643
4180
  await handle.close();
3644
4181
  }
3645
4182
  }
3646
- async function syncDirectory(path) {
4183
+ async function syncDirectory$1(path) {
3647
4184
  let handle;
3648
4185
  try {
3649
4186
  handle = await open(path, "r");
@@ -3671,7 +4208,7 @@ async function ensurePrivateDirectory(path) {
3671
4208
  const boundary = dirname(firstCreated);
3672
4209
  let current = path;
3673
4210
  while (true) {
3674
- await syncDirectory(current);
4211
+ await syncDirectory$1(current);
3675
4212
  if (current === boundary) return;
3676
4213
  current = dirname(current);
3677
4214
  }
@@ -3751,7 +4288,7 @@ var FileRawEventInbox = class {
3751
4288
  const existingName = parseInboxFileName(existingEntry.name);
3752
4289
  if (entryContentId(parsedExisting.entry) !== id || existingName?.enqueueOrder !== parsedExisting.enqueueOrder) throw new Error("raw-event inbox entry conflict");
3753
4290
  await chmod(join(this.directory, existingEntry.name), 384);
3754
- await syncDirectory(this.directory);
4291
+ await syncDirectory$1(this.directory);
3755
4292
  this.scheduleDrain();
3756
4293
  return;
3757
4294
  }
@@ -3777,7 +4314,7 @@ var FileRawEventInbox = class {
3777
4314
  } finally {
3778
4315
  await rm(temporary, { force: true }).catch(() => {});
3779
4316
  }
3780
- await syncDirectory(this.directory);
4317
+ await syncDirectory$1(this.directory);
3781
4318
  this.scheduleDrain();
3782
4319
  }
3783
4320
  async allocateEnqueueOrder(entries) {
@@ -13628,6 +14165,7 @@ function readyContext(options, groupId, coordinatorUrl, raw, groups) {
13628
14165
  groupId,
13629
14166
  deviceId: device.deviceId,
13630
14167
  fingerprint: device.fingerprint,
14168
+ publicKeyHash: createHash("sha256").update(device.publicKey).digest("hex"),
13631
14169
  identityId: actor,
13632
14170
  identityLabel: label(profile.identityLabel),
13633
14171
  deviceLabel: label(profile.deviceLabel),
@@ -13707,6 +14245,2052 @@ function createAccountContextReader(options) {
13707
14245
  };
13708
14246
  }
13709
14247
  //#endregion
14248
+ //#region ../core/src/coordinator-ed25519-key-id.ts
14249
+ function decodeWire(encoded) {
14250
+ try {
14251
+ const binary = atob(encoded);
14252
+ return Uint8Array.from(binary, (character) => character.charCodeAt(0));
14253
+ } catch {
14254
+ return null;
14255
+ }
14256
+ }
14257
+ function readRawKey(wire) {
14258
+ if (wire.length < 4) return null;
14259
+ const view = new DataView(wire.buffer, wire.byteOffset, wire.byteLength);
14260
+ const typeEnd = 4 + view.getUint32(0);
14261
+ if (wire.length < typeEnd + 4) return null;
14262
+ const keyLength = view.getUint32(typeEnd);
14263
+ const keyStart = typeEnd + 4;
14264
+ if (keyLength !== 32 || wire.length < keyStart + keyLength) return null;
14265
+ return wire.subarray(keyStart, keyStart + keyLength);
14266
+ }
14267
+ function canonicalBlob(rawKey) {
14268
+ const blob = /* @__PURE__ */ new Uint8Array(51);
14269
+ const view = new DataView(blob.buffer);
14270
+ view.setUint32(0, 11);
14271
+ blob.set(new TextEncoder().encode("ssh-ed25519"), 4);
14272
+ view.setUint32(15, 32);
14273
+ blob.set(rawKey, 19);
14274
+ return blob;
14275
+ }
14276
+ /**
14277
+ * Internal string contract, not an authentication acceptance check. Like the
14278
+ * Worker verifier, skip the inner type bytes and ignore trailing wire bytes.
14279
+ * atob rejects some encodings accepted by Node's Buffer base64 decoder.
14280
+ */
14281
+ function parseSshEd25519PublicKey(publicKey) {
14282
+ return parseSshEd25519PublicKeyWithDecoder(publicKey, decodeWire);
14283
+ }
14284
+ /** Internal trusted decoder seam; callers must not use it to decide authentication acceptance. */
14285
+ function parseSshEd25519PublicKeyWithDecoder(publicKey, decode) {
14286
+ if (typeof publicKey !== "string") return { kind: "other" };
14287
+ const [keyType, keyData] = publicKey.trim().split(/\s+/);
14288
+ if (keyType !== "ssh-ed25519") return { kind: "other" };
14289
+ if (!keyData) return { kind: "malformed_ed25519" };
14290
+ let wire;
14291
+ try {
14292
+ wire = decode(keyData);
14293
+ } catch {
14294
+ return { kind: "malformed_ed25519" };
14295
+ }
14296
+ if (!wire) return { kind: "malformed_ed25519" };
14297
+ const rawKey = readRawKey(wire);
14298
+ if (!rawKey) return { kind: "malformed_ed25519" };
14299
+ return {
14300
+ kind: "ed25519",
14301
+ blob: canonicalBlob(rawKey)
14302
+ };
14303
+ }
14304
+ //#endregion
14305
+ //#region ../core/src/coordinator-auth-controller-history.ts
14306
+ var MAX_BYTES = 75e4;
14307
+ var CONTROLLER_HISTORY_CTE = `history_input AS MATERIALIZED (
14308
+ SELECT json_extract(value, '$.legacyHistory') AS value FROM snapshot
14309
+ ), history_key_sources AS NOT MATERIALIZED (
14310
+ SELECT public_key, fingerprint FROM enrolled_devices
14311
+ UNION
14312
+ SELECT a.public_key, a.fingerprint FROM coordinator_auth_controller_attestations a
14313
+ CROSS JOIN history_input h
14314
+ WHERE a.coordinator_id = json_extract(h.value, '$.coordinatorId')
14315
+ ), history_rows AS NOT MATERIALIZED (
14316
+ SELECT c.*, CASE WHEN json_valid(c.manifest_json) THEN c.manifest_json ELSE '{}' END AS parsed
14317
+ FROM coordinator_legacy_team_completions c
14318
+ ), live_history AS MATERIALIZED (
14319
+ SELECT c.group_id, c.candidate_ref, c.manifest_version, c.completed_at, c.created_at,
14320
+ CASE WHEN length(CAST(c.manifest_json AS BLOB)) <= ${MAX_BYTES} THEN c.manifest_json ELSE NULL END AS manifest_json
14321
+ FROM history_rows c CROSS JOIN history_input h
14322
+ WHERE h.value IS NOT NULL
14323
+ AND (json_extract(c.parsed, '$.coordinator_id') = json_extract(h.value, '$.coordinatorId')
14324
+ OR json_extract(c.parsed, '$.coordinator_id') IS NULL)
14325
+ AND (EXISTS (
14326
+ SELECT 1 FROM json_each(c.parsed, '$.device_decisions') d
14327
+ WHERE json_extract(CASE WHEN d.type = 'object' THEN d.value ELSE '{}' END, '$.device_id') = json_extract(h.value, '$.deviceId')
14328
+ OR json_extract(CASE WHEN d.type = 'object' THEN d.value ELSE '{}' END, '$.key_fingerprint')
14329
+ IN (SELECT value FROM json_each(h.value, '$.fingerprints'))
14330
+ OR ((d.type <> 'object'
14331
+ OR json_type(CASE WHEN d.type = 'object' THEN d.value ELSE '{}' END, '$.device_id') IS NOT 'text'
14332
+ OR json_type(CASE WHEN d.type = 'object' THEN d.value ELSE '{}' END, '$.key_fingerprint') IS NOT 'text')
14333
+ AND (instr(CASE WHEN d.type = 'text' THEN json_quote(d.value) ELSE d.value END,
14334
+ json_quote(json_extract(h.value, '$.deviceId'))) > 0
14335
+ OR EXISTS (SELECT 1 FROM json_each(h.value, '$.fingerprints') f
14336
+ WHERE instr(d.value, f.value) > 0)))
14337
+ ) OR ((json_valid(c.manifest_json) = 0 OR json_type(c.parsed, '$.device_decisions') IS NOT 'array') AND (
14338
+ instr(c.manifest_json, json_quote(json_extract(h.value, '$.deviceId'))) > 0
14339
+ OR EXISTS (SELECT 1 FROM json_each(h.value, '$.fingerprints') f
14340
+ WHERE instr(c.manifest_json, f.value) > 0)
14341
+ ))) LIMIT 501
14342
+ ), snapshot_history AS MATERIALIZED (
14343
+ SELECT json_extract(j.value, '$.group_id') AS group_id,
14344
+ json_extract(j.value, '$.candidate_ref') AS candidate_ref,
14345
+ json_extract(j.value, '$.manifest_version') AS manifest_version,
14346
+ json_extract(j.value, '$.completed_at') AS completed_at,
14347
+ json_extract(j.value, '$.created_at') AS created_at,
14348
+ json_extract(j.value, '$.manifest_json') AS manifest_json
14349
+ FROM history_input h, json_each(h.value, '$.records') j
14350
+ ), snapshot_history_keys AS MATERIALIZED (
14351
+ SELECT json_extract(j.value, '$.public_key') AS public_key,
14352
+ json_extract(j.value, '$.fingerprint') AS fingerprint
14353
+ FROM history_input h, json_each(h.value, '$.keys') j
14354
+ ), snapshot_discovery_keys AS MATERIALIZED (
14355
+ SELECT j.value AS public_key FROM history_input h, json_each(h.value, '$.discoveryKeys') j
14356
+ ), discovery_lines AS NOT MATERIALIZED (
14357
+ SELECT public_key,
14358
+ ltrim(replace(replace(replace(replace(replace(public_key,
14359
+ char(9), ' '), char(10), ' '), char(11), ' '), char(12), ' '), char(13), ' '), ' ') AS line
14360
+ FROM history_key_sources
14361
+ ), discovery_tails AS NOT MATERIALIZED (
14362
+ SELECT public_key, CASE WHEN substr(line, 1, 12) = 'ssh-ed25519 '
14363
+ THEN ltrim(substr(line, 13), ' ') ELSE NULL END AS tail FROM discovery_lines
14364
+ ), discovery_tokens AS NOT MATERIALIZED (
14365
+ SELECT public_key, CASE WHEN tail IS NOT NULL
14366
+ THEN substr(tail, 1, instr(tail || ' ', ' ') - 1) ELSE NULL END AS token
14367
+ FROM discovery_tails
14368
+ ), live_discovery_keys AS MATERIALIZED (
14369
+ SELECT DISTINCT e.public_key FROM discovery_tokens e CROSS JOIN history_input h
14370
+ WHERE e.public_key = json_extract(h.value, '$.publicKey')
14371
+ OR instr(e.public_key, char(0)) > 0
14372
+ OR e.token IS NULL
14373
+ OR EXISTS (SELECT 1 FROM json_each(h.value, '$.discoveryFragments') f
14374
+ WHERE instr(replace(replace(e.token, '-', '+'), '_', '/'), f.value) > 0)
14375
+ OR e.token GLOB '*[^A-Za-z0-9+/=_-]*'
14376
+ LIMIT 8193
14377
+ ), live_history_keys AS MATERIALIZED (
14378
+ SELECT DISTINCT e.public_key, e.fingerprint FROM history_key_sources e
14379
+ WHERE e.public_key IN (SELECT public_key FROM snapshot_history_keys)
14380
+ LIMIT 4097
14381
+ )`;
14382
+ `${CONTROLLER_HISTORY_CTE}`;
14383
+ `${CONTROLLER_HISTORY_CTE}`;
14384
+ `${CONTROLLER_HISTORY_CTE}${MAX_BYTES}`;
14385
+ var CONTROLLER_HISTORY_GUARD = `AND (
14386
+ (SELECT value FROM history_input) IS NULL OR (
14387
+ json_extract((SELECT value FROM history_input), '$.deviceId') = e.device_id
14388
+ AND json_extract((SELECT value FROM history_input), '$.publicKey') = e.public_key
14389
+ AND json_extract((SELECT value FROM history_input), '$.fingerprint') = e.fingerprint
14390
+ AND (SELECT count(*) FROM live_history) = (SELECT count(*) FROM snapshot_history)
14391
+ AND NOT EXISTS (SELECT * FROM live_history EXCEPT SELECT * FROM snapshot_history)
14392
+ AND NOT EXISTS (SELECT * FROM live_history_keys EXCEPT SELECT * FROM snapshot_history_keys)
14393
+ AND NOT EXISTS (SELECT * FROM snapshot_history_keys EXCEPT SELECT * FROM live_history_keys)
14394
+ AND NOT EXISTS (SELECT * FROM live_discovery_keys EXCEPT SELECT * FROM snapshot_discovery_keys)
14395
+ AND NOT EXISTS (SELECT * FROM snapshot_discovery_keys EXCEPT SELECT * FROM live_discovery_keys)
14396
+ ))`;
14397
+ //#endregion
14398
+ //#region ../core/src/coordinator-account-connection-storage.ts
14399
+ /**
14400
+ * Storage constraints, not an unlink/relink authorization API.
14401
+ * The explicit account-schema migration installs this DDL. Management writers
14402
+ * compose the winning proof, archive move and successor CAS in one backend.batch;
14403
+ * an Identity identifier alone never authorizes these effects.
14404
+ */
14405
+ var CONNECTION_BIRTH_COLUMNS = [
14406
+ "coordinator_id",
14407
+ "link_id",
14408
+ "issuer",
14409
+ "subject",
14410
+ "identity_id",
14411
+ "attempt_id",
14412
+ "controller_attestation_id",
14413
+ "auth_config_revision",
14414
+ "created_at_ms",
14415
+ "revoked_at_ms",
14416
+ "authority_kind",
14417
+ "device_claim_id"
14418
+ ];
14419
+ var current = "coordinator_auth_account_links";
14420
+ var history = "coordinator_auth_account_connection_history";
14421
+ var orders = "coordinator_auth_account_connection_orders";
14422
+ var birthEqual = CONNECTION_BIRTH_COLUMNS.map((c) => `c.${c} IS NEW.${c}`).join(" AND ");
14423
+ var immutableBirth = CONNECTION_BIRTH_COLUMNS.filter((c) => c !== "revoked_at_ms").map((c) => `NEW.${c} IS NOT OLD.${c}`).join(" OR ");
14424
+ `${CONNECTION_BIRTH_COLUMNS.map((column) => `h.${column} IS c.${column}`).join(" AND ")}`;
14425
+ `${current}${history}`;
14426
+ /** Alias l must be the pinned current target, never a caller-selected Identity. */
14427
+ var CONNECTION_NOT_REVOKED_SQL = `l.revoked_at_ms IS NULL AND NOT EXISTS (
14428
+ SELECT 1 FROM ${history} h WHERE h.coordinator_id = l.coordinator_id
14429
+ AND h.identity_id = l.identity_id AND h.revoked_at_ms IS NOT NULL)`;
14430
+ `${history}${current}${history}`;
14431
+ `${orders}`;
14432
+ `${orders}`;
14433
+ `${history}`, `${history}${history}${history}${history}${current}${birthEqual}`, `${history}`, `${history}${immutableBirth}${history}${current}${history}`, `${history}`, `${current}${history}`, `${history}`, `${orders}`, `${orders}${orders}`, `${orders}`, `${orders}`;
14434
+ `${CONNECTION_BIRTH_COLUMNS.join(",")}${CONNECTION_BIRTH_COLUMNS.join(",")}`;
14435
+ function rootBirths(coordinator, link) {
14436
+ return `SELECT ${CONNECTION_BIRTH_COLUMNS.join(",")} FROM coordinator_auth_account_links WHERE coordinator_id = ${coordinator} AND link_id = ${link}
14437
+ UNION ALL SELECT ${CONNECTION_BIRTH_COLUMNS.join(",")} FROM coordinator_auth_account_connection_history WHERE coordinator_id = ${coordinator} AND link_id = ${link}`;
14438
+ }
14439
+ /** Trusted SQL aliases only. Historical ownership is independent of current enrollment.
14440
+ * The immutable proof's key ID was derived at commit. Signed-device receipts also
14441
+ * pass a freshly derived canonical key ID; account sessions need no current key.
14442
+ * Link revocation is deliberately checked by the caller, including post-revoke audit.
14443
+ */
14444
+ function authDeviceClaimProvenanceSql(options) {
14445
+ if (options.connections) return connectionClaimProvenance(options);
14446
+ return genesisClaimProvenance(options.link, "coordinator_auth_account_links", options.canonicalKeyId);
14447
+ }
14448
+ function genesisClaimProvenance(link, births, canonicalKeyId) {
14449
+ const l = "pl";
14450
+ return `EXISTS (WITH committed_claim AS MATERIALIZED (
14451
+ SELECT ct.coordinator_id, ct.link_id, cd.key_id FROM coordinator_auth_link_attempts ct
14452
+ JOIN ${births} pl ON pl.coordinator_id = ct.coordinator_id AND pl.link_id = ct.link_id
14453
+ JOIN coordinator_auth_device_claims cd ON cd.coordinator_id = ct.coordinator_id AND cd.claim_id = ${l}.device_claim_id
14454
+ JOIN coordinator_auth_link_audit_log ca ON ca.coordinator_id = ct.coordinator_id AND ca.link_id = ct.link_id AND ca.action = 'link_created'
14455
+ WHERE ct.coordinator_id = ${link}.coordinator_id AND ct.link_id = ${link}.link_id
14456
+ AND ct.attempt_id = ${l}.attempt_id
14457
+ AND ct.authority_kind = 'device_claim' AND ct.controller_attestation_id IS NULL
14458
+ AND ct.controller_review_receipt_id IS NULL AND ct.controller_revision IS NULL AND ct.state IN ('finalized','session_redeemed')
14459
+ AND ${l}.authority_kind = 'device_claim' AND ${l}.controller_attestation_id IS NULL
14460
+ AND ct.identity_id = ${l}.identity_id AND ct.issuer = ${l}.issuer AND ct.account_subject = ${l}.subject
14461
+ AND ct.auth_config_revision = ${l}.auth_config_revision AND ct.finalized_at_ms = ${l}.created_at_ms
14462
+ AND ct.browser_transaction_hash IS NOT NULL AND ct.browser_start_hash IS NOT NULL
14463
+ AND ct.runtime_verifier_hash IS NOT NULL AND ct.completion_secret_hash IS NOT NULL
14464
+ AND ct.created_at_ms <= ct.claimed_at_ms AND ct.claimed_at_ms <= ct.oidc_verified_at_ms
14465
+ AND ct.oidc_verified_at_ms <= ct.confirmed_at_ms AND ct.confirmed_at_ms <= ct.finalized_at_ms AND ct.finalized_at_ms < ct.expires_at_ms
14466
+ AND cd.attempt_id = ct.attempt_id AND cd.identity_id = ct.identity_id AND cd.group_id = ct.group_id AND cd.device_id = ct.device_id
14467
+ AND cd.public_key = ct.public_key AND cd.fingerprint = ct.fingerprint
14468
+ AND cd.issuer = ct.issuer AND cd.auth_config_revision = ct.auth_config_revision AND cd.created_at_ms = ct.finalized_at_ms
14469
+ AND ca.authority_kind = 'device_claim' AND ca.controller_attestation_id IS NULL AND ca.device_claim_id IS ${l}.device_claim_id
14470
+ AND ca.attempt_id = ct.attempt_id AND ca.identity_id = ct.identity_id AND ca.group_id = ct.group_id AND ca.device_id = ct.device_id
14471
+ AND ca.fingerprint = ct.fingerprint AND ca.auth_config_revision = ct.auth_config_revision AND ca.created_at_ms = ct.finalized_at_ms)
14472
+ SELECT 1 FROM committed_claim cp WHERE cp.coordinator_id = ${link}.coordinator_id AND cp.link_id = ${link}.link_id
14473
+ ${canonicalKeyId ? `AND cp.key_id = ${canonicalKeyId}` : ""})`;
14474
+ }
14475
+ function connectionClaimProvenance(options) {
14476
+ const l = options.link;
14477
+ return `EXISTS (WITH connection_births AS MATERIALIZED (${rootBirths(`${l}.coordinator_id`, `${l}.device_claim_id`)}), continuation AS MATERIALIZED (
14478
+ SELECT t.coordinator_id,t.link_id,d.key_id FROM coordinator_auth_link_attempts t
14479
+ JOIN coordinator_auth_link_audit_log a ON a.coordinator_id = t.coordinator_id AND a.link_id = t.link_id AND a.action = 'link_created'
14480
+ JOIN coordinator_auth_device_claims d ON d.coordinator_id = t.coordinator_id AND d.claim_id = ${l}.device_claim_id
14481
+ WHERE t.coordinator_id = ${l}.coordinator_id AND t.link_id = ${l}.link_id AND t.attempt_id = ${l}.attempt_id
14482
+ AND (${l}.authority_kind = 'device_claim' AND ${l}.controller_attestation_id IS NULL AND t.authority_kind = 'device_claim' AND t.controller_attestation_id IS NULL AND t.controller_review_receipt_id IS NULL AND t.controller_revision IS NULL)
14483
+ AND (t.state IN ('finalized','session_redeemed') AND t.identity_id = ${l}.identity_id AND t.issuer = ${l}.issuer AND t.account_subject = ${l}.subject AND t.auth_config_revision = ${l}.auth_config_revision AND t.finalized_at_ms = ${l}.created_at_ms)
14484
+ AND (t.browser_start_hash IS NOT NULL AND t.browser_transaction_hash IS NOT NULL AND t.runtime_verifier_hash IS NOT NULL AND t.completion_secret_hash IS NOT NULL AND t.created_at_ms <= t.claimed_at_ms AND t.claimed_at_ms <= t.oidc_verified_at_ms AND t.oidc_verified_at_ms <= t.confirmed_at_ms AND t.confirmed_at_ms <= t.finalized_at_ms AND t.finalized_at_ms < t.expires_at_ms)
14485
+ AND (d.identity_id = t.identity_id AND d.issuer = t.issuer AND d.group_id = t.group_id AND d.device_id = t.device_id AND d.public_key = t.public_key AND d.fingerprint = t.fingerprint)
14486
+ AND (a.attempt_id = t.attempt_id AND a.identity_id = t.identity_id AND a.group_id = t.group_id AND a.device_id = t.device_id AND a.fingerprint = t.fingerprint AND a.auth_config_revision = t.auth_config_revision AND a.created_at_ms = t.finalized_at_ms AND a.authority_kind = 'device_claim' AND a.controller_attestation_id IS NULL AND a.device_claim_id = d.claim_id)
14487
+ AND ((t.prior_link_id IS NULL AND t.link_id = d.claim_id) OR EXISTS (SELECT 1 FROM coordinator_auth_account_connection_history h WHERE h.coordinator_id = t.coordinator_id AND h.link_id = t.prior_link_id AND h.identity_id = t.identity_id AND h.successor_link_id = t.link_id))
14488
+ AND EXISTS (SELECT 1 FROM connection_births gl WHERE gl.coordinator_id = d.coordinator_id AND gl.link_id = d.claim_id AND ${genesisClaimProvenance("gl", "connection_births")}))
14489
+ SELECT 1 FROM continuation cp ${options.canonicalKeyId ? "WHERE cp.key_id = ?" : ""})`;
14490
+ }
14491
+ /** Account management only; privileged enrollment/grant proofs remain attested-only. */
14492
+ function controllerBirthProvenance(link) {
14493
+ return `EXISTS (WITH controller_receipt AS MATERIALIZED (SELECT t.coordinator_id,t.link_id FROM coordinator_auth_link_attempts t
14494
+ JOIN coordinator_auth_controller_attestations origin ON origin.coordinator_id=t.coordinator_id AND origin.attestation_id=t.controller_attestation_id
14495
+ JOIN coordinator_auth_link_audit_log a ON a.coordinator_id=t.coordinator_id AND a.link_id=t.link_id AND a.action='link_created'
14496
+ WHERE (t.coordinator_id=${link}.coordinator_id AND t.link_id=${link}.link_id AND t.attempt_id=${link}.attempt_id AND t.authority_kind='controller_attestation' AND t.controller_attestation_id=${link}.controller_attestation_id)
14497
+ AND (t.identity_id=${link}.identity_id AND t.issuer=${link}.issuer AND t.account_subject=${link}.subject AND t.auth_config_revision=${link}.auth_config_revision AND t.finalized_at_ms=${link}.created_at_ms AND t.state IN ('finalized','session_redeemed'))
14498
+ AND (t.browser_transaction_hash IS NOT NULL AND t.runtime_verifier_hash IS NOT NULL AND t.completion_secret_hash IS NOT NULL AND t.created_at_ms<=t.claimed_at_ms AND t.claimed_at_ms<=t.oidc_verified_at_ms AND t.oidc_verified_at_ms<=t.confirmed_at_ms AND t.confirmed_at_ms<=t.finalized_at_ms AND t.finalized_at_ms<t.expires_at_ms)
14499
+ AND (origin.identity_id=t.identity_id AND origin.group_id=t.group_id AND origin.device_id=t.device_id AND origin.public_key=t.public_key AND origin.fingerprint=t.fingerprint AND origin.review_receipt_id=t.controller_review_receipt_id AND origin.revision=t.controller_revision)
14500
+ AND (t.prior_link_id IS NULL OR EXISTS (SELECT 1 FROM coordinator_auth_account_connection_history h WHERE h.coordinator_id=t.coordinator_id AND h.identity_id=t.identity_id AND h.link_id=t.prior_link_id AND h.successor_link_id=t.link_id))
14501
+ AND (a.attempt_id=t.attempt_id AND a.identity_id=t.identity_id AND a.group_id=t.group_id AND a.device_id=t.device_id AND a.fingerprint=t.fingerprint AND a.controller_attestation_id=t.controller_attestation_id AND a.authority_kind=t.authority_kind AND a.device_claim_id IS NULL AND a.auth_config_revision=t.auth_config_revision AND a.created_at_ms=t.finalized_at_ms)) SELECT 1 FROM controller_receipt)`;
14502
+ }
14503
+ function authAccountLinkProvenanceSql(link, options = {}) {
14504
+ return `((${link}.authority_kind = 'controller_attestation' AND ${link}.controller_attestation_id IS NOT NULL AND ${link}.device_claim_id IS NULL${options.connections ? ` AND ${controllerBirthProvenance(link)}` : ""})
14505
+ OR (${authDeviceClaimProvenanceSql({
14506
+ link,
14507
+ connections: options.connections
14508
+ })}))`;
14509
+ }
14510
+ `${CONNECTION_NOT_REVOKED_SQL}${authAccountLinkProvenanceSql("l", { connections: true })}`;
14511
+ //#endregion
14512
+ //#region ../core/src/coordinator-auth-controller.ts
14513
+ function isAuthControllerId(value) {
14514
+ return typeof value === "string" && value.length > 0 && value.length <= 256 && value.trim() === value && !/[\p{Cc}\p{Cf}\p{Cs}]/u.test(value);
14515
+ }
14516
+ var AUTH_CONTROLLER_SNAPSHOT_CTE = `
14517
+ WITH snapshot(value) AS (SELECT ?), snapshot_invites AS MATERIALIZED (
14518
+ SELECT json_extract(j.value, '$.inviteId') AS invite_id,
14519
+ json_extract(j.value, '$.kind') AS invite_kind,
14520
+ json_extract(j.value, '$.actorId') AS recipient_actor_id,
14521
+ json_extract(j.value, '$.assignedIdentityId') AS assigned_identity_id,
14522
+ json_extract(j.value, '$.targetIdentityId') AS target_identity_id,
14523
+ json_extract(j.value, '$.digest') AS reviewed_preview_digest
14524
+ FROM json_each((SELECT value FROM snapshot), '$.invites') j
14525
+ ), live_invites AS MATERIALIZED (
14526
+ SELECT i.invite_id, i.invite_kind, i.recipient_actor_id, i.assigned_identity_id,
14527
+ i.target_identity_id, i.reviewed_preview_digest FROM coordinator_invites i
14528
+ WHERE i.group_id = ? AND i.bound_device_id = ? AND i.bound_public_key = ?
14529
+ AND i.bound_fingerprint = ? AND i.revoked_at IS NULL
14530
+ AND i.consumed_at IS NOT NULL AND i.consumed_at != ''
14531
+ AND i.invite_kind IN ('team_member', 'add_device')
14532
+ ), ${CONTROLLER_HISTORY_CTE}`;
14533
+ var AUTH_CONTROLLER_SNAPSHOT_GUARD = `
14534
+ AND ((SELECT value FROM snapshot) IS NULL OR (
14535
+ e.identity_id IS json_extract((SELECT value FROM snapshot), '$.enrollmentIdentityId')
14536
+ AND (SELECT count(*) FROM live_invites) =
14537
+ (SELECT count(*) FROM snapshot_invites)
14538
+ AND NOT EXISTS (
14539
+ SELECT * FROM live_invites
14540
+ EXCEPT
14541
+ SELECT * FROM snapshot_invites
14542
+ )
14543
+ )) ${CONTROLLER_HISTORY_GUARD}`;
14544
+ var AUTH_CONTROLLER_AUTHORITY_GUARD = `
14545
+ AND e.group_id = ? AND e.device_id = ? AND e.public_key = ?
14546
+ AND e.fingerprint = ? AND e.identity_id IS ?
14547
+ AND NOT EXISTS (SELECT 1 FROM coordinator_device_revocations WHERE
14548
+ (subject_kind = 'device_id' AND subject_value = ?) OR
14549
+ (subject_kind = 'ed25519_key' AND subject_value = ?))`;
14550
+ `${AUTH_CONTROLLER_SNAPSHOT_CTE}${AUTH_CONTROLLER_SNAPSHOT_GUARD}${AUTH_CONTROLLER_AUTHORITY_GUARD}`;
14551
+ `${AUTH_CONTROLLER_SNAPSHOT_CTE}${AUTH_CONTROLLER_SNAPSHOT_GUARD}${AUTH_CONTROLLER_AUTHORITY_GUARD}`;
14552
+ var AUTH_CONTROLLER_CURRENT_SQL = `
14553
+ SELECT a.* FROM coordinator_auth_controller_attestations a
14554
+ JOIN enrolled_devices e ON e.group_id = a.group_id AND e.device_id = a.device_id
14555
+ JOIN groups g ON g.group_id = a.group_id
14556
+ WHERE a.coordinator_id = ? AND a.attestation_id = ? AND a.revoked_at IS NULL
14557
+ AND e.enabled = 1 AND g.archived_at IS NULL AND e.public_key = a.public_key
14558
+ AND e.fingerprint = a.fingerprint
14559
+ AND (e.identity_id IS NULL OR e.identity_id = a.identity_id)`;
14560
+ AUTH_CONTROLLER_CURRENT_SQL.replace("SELECT a.*", "SELECT e.*");
14561
+ `${AUTH_CONTROLLER_SNAPSHOT_CTE}`, `${AUTH_CONTROLLER_CURRENT_SQL}${AUTH_CONTROLLER_AUTHORITY_GUARD}`, `${AUTH_CONTROLLER_SNAPSHOT_GUARD}`;
14562
+ function ownerProfileConflict() {
14563
+ throw new Error("Owner enrollment stopped for review. Keep the profile and saved request unchanged; no identity or access repair is automatic.");
14564
+ }
14565
+ [{
14566
+ name: "trg_identity_devices_assignment_version",
14567
+ create: `CREATE TRIGGER trg_identity_devices_assignment_version
14568
+ AFTER UPDATE OF identity_id ON identity_devices
14569
+ WHEN NEW.identity_id <> OLD.identity_id
14570
+ BEGIN
14571
+ UPDATE identity_devices
14572
+ SET assignment_version = OLD.assignment_version + 1
14573
+ WHERE device_id = NEW.device_id;
14574
+ END`
14575
+ }, {
14576
+ name: "trg_identity_devices_purge_decisions",
14577
+ create: `CREATE TRIGGER trg_identity_devices_purge_decisions
14578
+ AFTER DELETE ON identity_devices
14579
+ BEGIN
14580
+ DELETE FROM policy_team_device_decisions WHERE device_id = OLD.device_id;
14581
+ END`
14582
+ }].map(({ name, create }) => `DROP TRIGGER IF EXISTS ${name};\n${create};`).join("\n");
14583
+ [
14584
+ [
14585
+ "insert",
14586
+ "AFTER INSERT",
14587
+ ""
14588
+ ],
14589
+ [
14590
+ "delete",
14591
+ "AFTER DELETE",
14592
+ ""
14593
+ ],
14594
+ [
14595
+ "update",
14596
+ "AFTER UPDATE",
14597
+ "WHEN OLD.id IS NOT NEW.id OR OLD.title IS NOT NEW.title OR OLD.body_text IS NOT NEW.body_text OR OLD.active IS NOT NEW.active"
14598
+ ]
14599
+ ].map(([suffix, event, condition]) => ({
14600
+ name: `vector_corpus_epoch_${suffix}`,
14601
+ sql: `CREATE TRIGGER vector_corpus_epoch_${suffix} ${event} ON memory_items ${condition}
14602
+ BEGIN UPDATE vector_corpus_epoch SET epoch = epoch + 1 WHERE id = 1; END`
14603
+ }));
14604
+ join(homedir(), ".codemem", "mem.sqlite");
14605
+ join(homedir(), ".codemem.sqlite"), join(homedir(), ".opencode-mem.sqlite");
14606
+ //#endregion
14607
+ //#region ../core/src/schema.ts
14608
+ /**
14609
+ * Drizzle ORM schema for the codemem SQLite database.
14610
+ */
14611
+ var sessions = sqliteTable("sessions", {
14612
+ id: integer("id").primaryKey(),
14613
+ started_at: text("started_at").notNull(),
14614
+ ended_at: text("ended_at"),
14615
+ cwd: text("cwd"),
14616
+ project: text("project"),
14617
+ git_remote: text("git_remote"),
14618
+ git_branch: text("git_branch"),
14619
+ user: text("user"),
14620
+ tool_version: text("tool_version"),
14621
+ metadata_json: text("metadata_json"),
14622
+ import_key: text("import_key")
14623
+ }, (table) => [index("idx_sessions_started_id").on(table.started_at, table.id)]);
14624
+ sqliteTable("replication_scopes", {
14625
+ scope_id: text("scope_id").primaryKey(),
14626
+ label: text("label").notNull(),
14627
+ kind: text("kind").notNull().default("user"),
14628
+ authority_type: text("authority_type").notNull().default("local"),
14629
+ coordinator_id: text("coordinator_id"),
14630
+ group_id: text("group_id"),
14631
+ manifest_issuer_device_id: text("manifest_issuer_device_id"),
14632
+ membership_epoch: integer("membership_epoch").notNull().default(0),
14633
+ manifest_hash: text("manifest_hash"),
14634
+ status: text("status").notNull().default("active"),
14635
+ created_at: text("created_at").notNull(),
14636
+ updated_at: text("updated_at").notNull()
14637
+ }, (table) => [index("idx_replication_scopes_status").on(table.status), index("idx_replication_scopes_authority_group").on(table.coordinator_id, table.group_id)]);
14638
+ sqliteTable("project_scope_mappings", {
14639
+ id: integer("id").primaryKey(),
14640
+ workspace_identity: text("workspace_identity"),
14641
+ project_pattern: text("project_pattern").notNull(),
14642
+ scope_id: text("scope_id").notNull(),
14643
+ priority: integer("priority").notNull().default(0),
14644
+ source: text("source").notNull().default("user"),
14645
+ created_at: text("created_at").notNull(),
14646
+ updated_at: text("updated_at").notNull()
14647
+ }, (table) => [
14648
+ index("idx_project_scope_mappings_workspace_priority").on(table.workspace_identity, table.priority),
14649
+ index("idx_project_scope_mappings_pattern_priority").on(table.project_pattern, table.priority),
14650
+ index("idx_project_scope_mappings_scope").on(table.scope_id)
14651
+ ]);
14652
+ sqliteTable("scope_memberships", {
14653
+ scope_id: text("scope_id").notNull(),
14654
+ device_id: text("device_id").notNull(),
14655
+ role: text("role").notNull().default("member"),
14656
+ status: text("status").notNull().default("active"),
14657
+ membership_epoch: integer("membership_epoch").notNull().default(0),
14658
+ coordinator_id: text("coordinator_id"),
14659
+ group_id: text("group_id"),
14660
+ manifest_issuer_device_id: text("manifest_issuer_device_id"),
14661
+ manifest_hash: text("manifest_hash"),
14662
+ signed_manifest_json: text("signed_manifest_json"),
14663
+ updated_at: text("updated_at").notNull()
14664
+ }, (table) => [
14665
+ primaryKey({ columns: [table.scope_id, table.device_id] }),
14666
+ index("idx_scope_memberships_device_status").on(table.device_id, table.status),
14667
+ index("idx_scope_memberships_scope_status").on(table.scope_id, table.status),
14668
+ index("idx_scope_memberships_authority_group").on(table.coordinator_id, table.group_id)
14669
+ ]);
14670
+ sqliteTable("artifacts", {
14671
+ id: integer("id").primaryKey(),
14672
+ session_id: integer("session_id").notNull().references(() => sessions.id, { onDelete: "cascade" }),
14673
+ kind: text("kind").notNull(),
14674
+ path: text("path"),
14675
+ content_text: text("content_text"),
14676
+ content_hash: text("content_hash"),
14677
+ created_at: text("created_at").notNull(),
14678
+ metadata_json: text("metadata_json")
14679
+ }, (table) => [index("idx_artifacts_session_kind").on(table.session_id, table.kind)]);
14680
+ var memoryItems = sqliteTable("memory_items", {
14681
+ id: integer("id").primaryKey(),
14682
+ session_id: integer("session_id").notNull().references(() => sessions.id, { onDelete: "cascade" }),
14683
+ kind: text("kind").notNull(),
14684
+ title: text("title").notNull(),
14685
+ subtitle: text("subtitle"),
14686
+ body_text: text("body_text").notNull(),
14687
+ confidence: real("confidence").default(.5),
14688
+ tags_text: text("tags_text").default(""),
14689
+ active: integer("active").default(1),
14690
+ created_at: text("created_at").notNull(),
14691
+ updated_at: text("updated_at").notNull(),
14692
+ metadata_json: text("metadata_json"),
14693
+ actor_id: text("actor_id"),
14694
+ actor_display_name: text("actor_display_name"),
14695
+ visibility: text("visibility"),
14696
+ workspace_id: text("workspace_id"),
14697
+ workspace_kind: text("workspace_kind"),
14698
+ origin_device_id: text("origin_device_id"),
14699
+ origin_source: text("origin_source"),
14700
+ trust_state: text("trust_state"),
14701
+ facts: text("facts"),
14702
+ narrative: text("narrative"),
14703
+ concepts: text("concepts"),
14704
+ files_read: text("files_read"),
14705
+ files_modified: text("files_modified"),
14706
+ user_prompt_id: integer("user_prompt_id"),
14707
+ prompt_number: integer("prompt_number"),
14708
+ deleted_at: text("deleted_at"),
14709
+ rev: integer("rev").default(0),
14710
+ dedup_key: text("dedup_key"),
14711
+ import_key: text("import_key"),
14712
+ scope_id: text("scope_id"),
14713
+ project: text("project")
14714
+ }, (table) => [
14715
+ index("idx_memory_items_active_created").on(table.active, table.created_at),
14716
+ index("idx_memory_items_created_id").on(table.created_at, table.id),
14717
+ index("idx_memory_items_origin_device_active").on(table.origin_device_id, table.active),
14718
+ index("idx_memory_items_session").on(table.session_id),
14719
+ index("idx_memory_items_project").on(table.project),
14720
+ index("idx_memory_items_scope_visibility_created").on(table.scope_id, table.visibility, table.created_at),
14721
+ index("idx_memory_items_scope_backfill_pending").on(table.id).where(sql`scope_id IS NULL OR scope_id = ''`),
14722
+ index("idx_memory_items_dedup_key_active_created").on(table.dedup_key, table.active, table.created_at),
14723
+ uniqueIndex("idx_memory_items_same_session_dedup_unique").on(table.session_id, table.kind, table.visibility, table.workspace_id, table.dedup_key).where(sql`active = 1 AND dedup_key IS NOT NULL`)
14724
+ ]);
14725
+ sqliteTable("memory_file_refs", {
14726
+ memory_id: integer("memory_id").notNull().references(() => memoryItems.id, { onDelete: "cascade" }),
14727
+ file_path: text("file_path").notNull(),
14728
+ relation: text("relation").notNull()
14729
+ }, (table) => [primaryKey({ columns: [
14730
+ table.memory_id,
14731
+ table.file_path,
14732
+ table.relation
14733
+ ] }), index("idx_memory_file_refs_path").on(table.file_path)]);
14734
+ sqliteTable("memory_concept_refs", {
14735
+ memory_id: integer("memory_id").notNull().references(() => memoryItems.id, { onDelete: "cascade" }),
14736
+ concept: text("concept").notNull()
14737
+ }, (table) => [primaryKey({ columns: [table.memory_id, table.concept] }), index("idx_memory_concept_refs_concept").on(table.concept)]);
14738
+ sqliteTable("usage_events", {
14739
+ id: integer("id").primaryKey(),
14740
+ session_id: integer("session_id").references(() => sessions.id, { onDelete: "set null" }),
14741
+ event: text("event").notNull(),
14742
+ tokens_read: integer("tokens_read").default(0),
14743
+ tokens_written: integer("tokens_written").default(0),
14744
+ tokens_saved: integer("tokens_saved").default(0),
14745
+ created_at: text("created_at").notNull(),
14746
+ metadata_json: text("metadata_json")
14747
+ }, (table) => [index("idx_usage_events_event_created").on(table.event, table.created_at), index("idx_usage_events_session").on(table.session_id)]);
14748
+ var retrievalAttempts = sqliteTable("retrieval_attempts", {
14749
+ attempt_id: text("attempt_id").primaryKey(),
14750
+ contract_version: integer("contract_version").notNull(),
14751
+ surface: text("surface").notNull(),
14752
+ trigger: text("trigger").notNull(),
14753
+ started_at: text("started_at").notNull(),
14754
+ completed_at: text("completed_at"),
14755
+ retrieval_status: text("retrieval_status").notNull(),
14756
+ delivery_status: text("delivery_status").notNull(),
14757
+ candidate_count: integer("candidate_count").notNull(),
14758
+ selected_count: integer("selected_count").notNull(),
14759
+ persisted_candidate_count: integer("persisted_candidate_count").notNull(),
14760
+ recorder_version: text("recorder_version").notNull(),
14761
+ session_id: integer("session_id").references(() => sessions.id, { onDelete: "cascade" }),
14762
+ source: text("source"),
14763
+ stream_id: text("stream_id"),
14764
+ source_session_id: text("source_session_id"),
14765
+ prompt_number: integer("prompt_number"),
14766
+ request_id: text("request_id"),
14767
+ raw_event_start_seq: integer("raw_event_start_seq"),
14768
+ raw_event_end_seq: integer("raw_event_end_seq"),
14769
+ experiment_id: text("experiment_id"),
14770
+ experiment_cell_id: text("experiment_cell_id"),
14771
+ evaluation_checkout_id: text("evaluation_checkout_id"),
14772
+ evaluation_fixture_id: text("evaluation_fixture_id"),
14773
+ evaluation_seed: integer("evaluation_seed"),
14774
+ latency_ms: integer("latency_ms"),
14775
+ project: text("project"),
14776
+ scope_id: text("scope_id"),
14777
+ mode: text("mode"),
14778
+ limit_requested: integer("limit_requested"),
14779
+ token_budget: integer("token_budget"),
14780
+ output_tokens: integer("output_tokens"),
14781
+ working_set_file_count: integer("working_set_file_count"),
14782
+ working_set_files_json: text("working_set_files_json"),
14783
+ query_hash_sha256: text("query_hash_sha256"),
14784
+ query_char_count: integer("query_char_count"),
14785
+ query_token_estimate: integer("query_token_estimate"),
14786
+ filter_summary_json: text("filter_summary_json"),
14787
+ failure_code: text("failure_code"),
14788
+ failure_stage: text("failure_stage"),
14789
+ trace_version: integer("trace_version"),
14790
+ automatic_recall_json: text("automatic_recall_json"),
14791
+ automatic_recall_key: text("automatic_recall_key"),
14792
+ retention_until: text("retention_until"),
14793
+ retention_pinned: integer("retention_pinned").notNull().default(0),
14794
+ retention_finalized_at: text("retention_finalized_at")
14795
+ }, (table) => [
14796
+ index("idx_retrieval_attempts_session_started").on(table.session_id, table.started_at),
14797
+ uniqueIndex("idx_retrieval_attempts_automatic_recall_key").on(table.automatic_recall_key),
14798
+ index("idx_retrieval_attempts_source_stream_started").on(table.source, table.stream_id, table.started_at),
14799
+ index("idx_retrieval_attempts_retention").on(table.retention_pinned, table.retention_until),
14800
+ index("idx_retrieval_attempts_started").on(table.started_at, table.attempt_id),
14801
+ index("idx_retrieval_attempts_surface_started").on(table.surface, table.started_at),
14802
+ uniqueIndex("idx_retrieval_attempts_request_identity").on(table.source, table.surface, table.request_id).where(sql`request_id IS NOT NULL`),
14803
+ index("idx_retrieval_attempts_experiment_cell").on(table.experiment_id, table.experiment_cell_id)
14804
+ ]);
14805
+ var retrievalExposures = sqliteTable("retrieval_exposures", {
14806
+ exposure_id: integer("exposure_id").primaryKey({ autoIncrement: true }),
14807
+ attempt_id: text("attempt_id").notNull().references(() => retrievalAttempts.attempt_id, { onDelete: "cascade" }),
14808
+ memory_id: integer("memory_id").references(() => memoryItems.id, { onDelete: "set null" }),
14809
+ memory_import_key: text("memory_import_key"),
14810
+ origin_device_id: text("origin_device_id"),
14811
+ rank: integer("rank").notNull(),
14812
+ disposition: text("disposition").notNull(),
14813
+ section: text("section"),
14814
+ handoff_status: text("handoff_status").notNull(),
14815
+ memory_rev: integer("memory_rev"),
14816
+ memory_updated_at: text("memory_updated_at"),
14817
+ memory_scope_id: text("memory_scope_id"),
14818
+ memory_kind: text("memory_kind"),
14819
+ memory_active: integer("memory_active"),
14820
+ memory_deleted_at: text("memory_deleted_at"),
14821
+ score_summary_json: text("score_summary_json"),
14822
+ reason_codes_json: text("reason_codes_json")
14823
+ }, (table) => [uniqueIndex("idx_retrieval_exposures_attempt_rank").on(table.attempt_id, table.rank), index("idx_retrieval_exposures_memory").on(table.memory_id)]);
14824
+ var outcomeEvidence = sqliteTable("outcome_evidence", {
14825
+ evidence_id: text("evidence_id").primaryKey(),
14826
+ contract_version: integer("contract_version").notNull(),
14827
+ dimension: text("dimension").notNull(),
14828
+ evidence_type: text("evidence_type").notNull(),
14829
+ source_class: text("source_class").notNull(),
14830
+ observed_at: text("observed_at").notNull(),
14831
+ producer: text("producer").notNull(),
14832
+ producer_version: text("producer_version").notNull(),
14833
+ status: text("status").notNull(),
14834
+ value_type: text("value_type"),
14835
+ value_integer: integer("value_integer"),
14836
+ value_real: real("value_real"),
14837
+ value_unit: text("value_unit"),
14838
+ session_id: integer("session_id").references(() => sessions.id, { onDelete: "cascade" }),
14839
+ source: text("source"),
14840
+ stream_id: text("stream_id"),
14841
+ source_session_id: text("source_session_id"),
14842
+ prompt_number: integer("prompt_number"),
14843
+ raw_event_start_seq: integer("raw_event_start_seq"),
14844
+ raw_event_end_seq: integer("raw_event_end_seq"),
14845
+ experiment_id: text("experiment_id"),
14846
+ experiment_cell_id: text("experiment_cell_id"),
14847
+ window_start_at: text("window_start_at"),
14848
+ window_end_at: text("window_end_at"),
14849
+ references_json: text("references_json"),
14850
+ retention_until: text("retention_until"),
14851
+ retention_pinned: integer("retention_pinned").notNull().default(0),
14852
+ retention_finalized_at: text("retention_finalized_at")
14853
+ }, (table) => [
14854
+ index("idx_outcome_evidence_observed_id").on(table.observed_at, table.evidence_id),
14855
+ index("idx_outcome_evidence_session_observed").on(table.session_id, table.observed_at),
14856
+ index("idx_outcome_evidence_source_stream_observed").on(table.source, table.stream_id, table.observed_at),
14857
+ index("idx_outcome_evidence_type_observed").on(table.evidence_type, table.observed_at),
14858
+ index("idx_outcome_evidence_retention").on(table.retention_pinned, table.retention_until)
14859
+ ]);
14860
+ var attributionAssessments = sqliteTable("attribution_assessments", {
14861
+ assessment_id: text("assessment_id").primaryKey(),
14862
+ contract_version: integer("contract_version").notNull(),
14863
+ subject_type: text("subject_type").notNull(),
14864
+ attempt_id: text("attempt_id").notNull().references(() => retrievalAttempts.attempt_id, { onDelete: "cascade" }),
14865
+ exposure_id: integer("exposure_id").references(() => retrievalExposures.exposure_id, { onDelete: "cascade" }),
14866
+ dimension: text("dimension").notNull(),
14867
+ impact_label: text("impact_label").notNull(),
14868
+ basis: text("basis").notNull(),
14869
+ confidence_level: text("confidence_level").notNull(),
14870
+ method: text("method").notNull(),
14871
+ method_version: text("method_version").notNull(),
14872
+ created_at: text("created_at").notNull(),
14873
+ claim_type: text("claim_type").notNull().default("observational")
14874
+ }, (table) => [
14875
+ index("idx_attribution_assessments_attempt_created").on(table.attempt_id, table.created_at),
14876
+ index("idx_attribution_assessments_label_created").on(table.impact_label, table.created_at),
14877
+ index("idx_attribution_assessments_exposure").on(table.exposure_id)
14878
+ ]);
14879
+ sqliteTable("attribution_assessment_evidence", {
14880
+ assessment_id: text("assessment_id").notNull().references(() => attributionAssessments.assessment_id, { onDelete: "cascade" }),
14881
+ evidence_id: text("evidence_id").notNull().references(() => outcomeEvidence.evidence_id, { onDelete: "cascade" })
14882
+ }, (table) => [primaryKey({ columns: [table.assessment_id, table.evidence_id] }), index("idx_attribution_assessment_evidence_evidence").on(table.evidence_id, table.assessment_id)]);
14883
+ sqliteTable("maintenance_jobs", {
14884
+ kind: text("kind").primaryKey(),
14885
+ title: text("title").notNull(),
14886
+ status: text("status").notNull(),
14887
+ message: text("message"),
14888
+ progress_current: integer("progress_current").notNull().default(0),
14889
+ progress_total: integer("progress_total"),
14890
+ progress_unit: text("progress_unit").notNull().default("items"),
14891
+ metadata_json: text("metadata_json"),
14892
+ started_at: text("started_at"),
14893
+ updated_at: text("updated_at").notNull(),
14894
+ finished_at: text("finished_at"),
14895
+ error: text("error")
14896
+ }, (table) => [index("idx_maintenance_jobs_status_updated").on(table.status, table.updated_at)]);
14897
+ sqliteTable("raw_events", {
14898
+ id: integer("id").primaryKey(),
14899
+ source: text("source").notNull().default("opencode"),
14900
+ stream_id: text("stream_id").notNull().default(""),
14901
+ opencode_session_id: text("opencode_session_id").notNull(),
14902
+ event_id: text("event_id"),
14903
+ event_seq: integer("event_seq").notNull(),
14904
+ event_type: text("event_type").notNull(),
14905
+ ts_wall_ms: integer("ts_wall_ms"),
14906
+ ts_mono_ms: real("ts_mono_ms"),
14907
+ payload_json: text("payload_json").notNull(),
14908
+ capture_context_json: text("capture_context_json"),
14909
+ created_at: text("created_at").notNull()
14910
+ }, (table) => [
14911
+ uniqueIndex("idx_raw_events_source_stream_seq").on(table.source, table.stream_id, table.event_seq),
14912
+ uniqueIndex("idx_raw_events_source_stream_event_id").on(table.source, table.stream_id, table.event_id),
14913
+ index("idx_raw_events_session_seq").on(table.opencode_session_id, table.event_seq),
14914
+ index("idx_raw_events_created").on(table.created_at),
14915
+ index("idx_raw_events_capture_context").on(table.source, table.stream_id, table.event_seq).where(sql`${table.capture_context_json} IS NOT NULL`)
14916
+ ]);
14917
+ sqliteTable("raw_event_sessions", {
14918
+ source: text("source").notNull().default("opencode"),
14919
+ stream_id: text("stream_id").notNull().default(""),
14920
+ opencode_session_id: text("opencode_session_id").notNull(),
14921
+ cwd: text("cwd"),
14922
+ project: text("project"),
14923
+ started_at: text("started_at"),
14924
+ last_seen_ts_wall_ms: integer("last_seen_ts_wall_ms"),
14925
+ last_received_event_seq: integer("last_received_event_seq").notNull().default(-1),
14926
+ last_flushed_event_seq: integer("last_flushed_event_seq").notNull().default(-1),
14927
+ updated_at: text("updated_at").notNull()
14928
+ }, (table) => [primaryKey({ columns: [table.source, table.stream_id] }), index("idx_raw_event_sessions_pending_updated").on(table.updated_at).where(sql`${table.last_received_event_seq} > ${table.last_flushed_event_seq}`)]);
14929
+ sqliteTable("pi_import_state", {
14930
+ file_path: text("file_path").primaryKey(),
14931
+ size_bytes: integer("size_bytes").notNull(),
14932
+ mtime_ms: real("mtime_ms").notNull(),
14933
+ updated_at: text("updated_at").notNull()
14934
+ });
14935
+ sqliteTable("opencode_sessions", {
14936
+ source: text("source").notNull().default("opencode"),
14937
+ stream_id: text("stream_id").notNull().default(""),
14938
+ opencode_session_id: text("opencode_session_id").notNull(),
14939
+ session_id: integer("session_id").references(() => sessions.id, { onDelete: "cascade" }),
14940
+ created_at: text("created_at").notNull()
14941
+ }, (table) => [primaryKey({ columns: [table.source, table.stream_id] }), index("idx_opencode_sessions_session").on(table.session_id)]);
14942
+ sqliteTable("raw_event_flush_batches", {
14943
+ id: integer("id").primaryKey(),
14944
+ source: text("source").notNull().default("opencode"),
14945
+ stream_id: text("stream_id").notNull().default(""),
14946
+ opencode_session_id: text("opencode_session_id").notNull(),
14947
+ start_event_seq: integer("start_event_seq").notNull(),
14948
+ end_event_seq: integer("end_event_seq").notNull(),
14949
+ extractor_version: text("extractor_version").notNull(),
14950
+ status: text("status").notNull(),
14951
+ error_message: text("error_message"),
14952
+ error_type: text("error_type"),
14953
+ observer_provider: text("observer_provider"),
14954
+ observer_model: text("observer_model"),
14955
+ observer_runtime: text("observer_runtime"),
14956
+ observer_auth_source: text("observer_auth_source"),
14957
+ observer_auth_type: text("observer_auth_type"),
14958
+ observer_error_code: text("observer_error_code"),
14959
+ observer_error_message: text("observer_error_message"),
14960
+ attempt_count: integer("attempt_count").notNull().default(0),
14961
+ created_at: text("created_at").notNull(),
14962
+ updated_at: text("updated_at").notNull()
14963
+ }, (table) => [
14964
+ uniqueIndex("idx_flush_batches_source_stream_seq_ver").on(table.source, table.stream_id, table.start_event_seq, table.end_event_seq, table.extractor_version),
14965
+ index("idx_flush_batches_session_created").on(table.opencode_session_id, table.created_at),
14966
+ index("idx_flush_batches_status_updated").on(table.status, table.updated_at),
14967
+ index("idx_flush_batches_observer_status_updated").on(table.status, table.updated_at).where(sql`${table.observer_provider} IS NOT NULL`),
14968
+ index("idx_flush_batches_capture_status_updated").on(table.status, table.updated_at).where(sql`${table.observer_provider} IS NULL`)
14969
+ ]);
14970
+ sqliteTable("user_prompts", {
14971
+ id: integer("id").primaryKey(),
14972
+ session_id: integer("session_id").references(() => sessions.id, { onDelete: "cascade" }),
14973
+ project: text("project"),
14974
+ prompt_text: text("prompt_text").notNull(),
14975
+ prompt_number: integer("prompt_number"),
14976
+ created_at: text("created_at").notNull(),
14977
+ created_at_epoch: integer("created_at_epoch").notNull(),
14978
+ metadata_json: text("metadata_json"),
14979
+ import_key: text("import_key")
14980
+ }, (table) => [
14981
+ index("idx_user_prompts_session").on(table.session_id),
14982
+ index("idx_user_prompts_project").on(table.project),
14983
+ index("idx_user_prompts_epoch").on(table.created_at_epoch)
14984
+ ]);
14985
+ sqliteTable("session_summaries", {
14986
+ id: integer("id").primaryKey(),
14987
+ session_id: integer("session_id").references(() => sessions.id, { onDelete: "cascade" }),
14988
+ project: text("project"),
14989
+ request: text("request"),
14990
+ investigated: text("investigated"),
14991
+ learned: text("learned"),
14992
+ completed: text("completed"),
14993
+ next_steps: text("next_steps"),
14994
+ notes: text("notes"),
14995
+ files_read: text("files_read"),
14996
+ files_edited: text("files_edited"),
14997
+ prompt_number: integer("prompt_number"),
14998
+ created_at: text("created_at").notNull(),
14999
+ created_at_epoch: integer("created_at_epoch").notNull(),
15000
+ metadata_json: text("metadata_json"),
15001
+ import_key: text("import_key")
15002
+ }, (table) => [
15003
+ index("idx_session_summaries_session").on(table.session_id),
15004
+ index("idx_session_summaries_project").on(table.project),
15005
+ index("idx_session_summaries_epoch").on(table.created_at_epoch)
15006
+ ]);
15007
+ sqliteTable("replication_ops", {
15008
+ op_id: text("op_id").primaryKey(),
15009
+ entity_type: text("entity_type").notNull(),
15010
+ entity_id: text("entity_id").notNull(),
15011
+ op_type: text("op_type").notNull(),
15012
+ payload_json: text("payload_json"),
15013
+ clock_rev: integer("clock_rev").notNull(),
15014
+ clock_updated_at: text("clock_updated_at").notNull(),
15015
+ clock_device_id: text("clock_device_id").notNull(),
15016
+ device_id: text("device_id").notNull(),
15017
+ created_at: text("created_at").notNull(),
15018
+ scope_id: text("scope_id")
15019
+ }, (table) => [
15020
+ index("idx_replication_ops_created").on(table.created_at, table.op_id),
15021
+ index("idx_replication_ops_entity").on(table.entity_type, table.entity_id),
15022
+ index("idx_replication_ops_scope_created").on(table.scope_id, table.created_at, table.op_id)
15023
+ ]);
15024
+ sqliteTable("replication_cursors", {
15025
+ peer_device_id: text("peer_device_id").primaryKey(),
15026
+ last_applied_cursor: text("last_applied_cursor"),
15027
+ last_acked_cursor: text("last_acked_cursor"),
15028
+ updated_at: text("updated_at").notNull()
15029
+ });
15030
+ sqliteTable("replication_cursors_v2", {
15031
+ peer_device_id: text("peer_device_id").notNull(),
15032
+ scope_id: text("scope_id").notNull(),
15033
+ last_applied_cursor: text("last_applied_cursor"),
15034
+ last_acked_cursor: text("last_acked_cursor"),
15035
+ updated_at: text("updated_at").notNull()
15036
+ }, (table) => [primaryKey({ columns: [table.peer_device_id, table.scope_id] }), index("idx_replication_cursors_v2_scope").on(table.scope_id)]);
15037
+ sqliteTable("sync_peers", {
15038
+ peer_device_id: text("peer_device_id").primaryKey(),
15039
+ name: text("name"),
15040
+ pinned_fingerprint: text("pinned_fingerprint"),
15041
+ public_key: text("public_key"),
15042
+ addresses_json: text("addresses_json"),
15043
+ manual_addresses_json: text("manual_addresses_json"),
15044
+ last_success_address: text("last_success_address"),
15045
+ claimed_local_actor: integer("claimed_local_actor").notNull().default(0),
15046
+ actor_id: text("actor_id"),
15047
+ projects_include_json: text("projects_include_json"),
15048
+ projects_exclude_json: text("projects_exclude_json"),
15049
+ created_at: text("created_at").notNull(),
15050
+ last_seen_at: text("last_seen_at"),
15051
+ last_sync_at: text("last_sync_at"),
15052
+ last_error: text("last_error"),
15053
+ runtime_version: text("runtime_version"),
15054
+ runtime_version_observed_at: text("runtime_version_observed_at"),
15055
+ highest_observed_direct_signature_version: integer("highest_observed_direct_signature_version"),
15056
+ discovered_via_coordinator_id: text("discovered_via_coordinator_id"),
15057
+ discovered_via_group_id: text("discovered_via_group_id"),
15058
+ trust_provenance: text("trust_provenance"),
15059
+ pending_bootstrap_grant_id: text("pending_bootstrap_grant_id")
15060
+ });
15061
+ sqliteTable("sync_peer_signature_state", {
15062
+ peer_device_id: text("peer_device_id").primaryKey(),
15063
+ highest_observed_direct_signature_version: integer("highest_observed_direct_signature_version").notNull()
15064
+ });
15065
+ sqliteTable("sync_nonces", {
15066
+ nonce: text("nonce").primaryKey(),
15067
+ device_id: text("device_id").notNull(),
15068
+ created_at: text("created_at").notNull()
15069
+ });
15070
+ sqliteTable("sync_device", {
15071
+ device_id: text("device_id").primaryKey(),
15072
+ public_key: text("public_key").notNull(),
15073
+ fingerprint: text("fingerprint").notNull(),
15074
+ created_at: text("created_at").notNull()
15075
+ });
15076
+ sqliteTable("sync_attempts", {
15077
+ id: integer("id").primaryKey({ autoIncrement: true }),
15078
+ peer_device_id: text("peer_device_id").notNull(),
15079
+ started_at: text("started_at").notNull(),
15080
+ finished_at: text("finished_at"),
15081
+ ok: integer("ok").notNull(),
15082
+ ops_in: integer("ops_in").notNull(),
15083
+ ops_out: integer("ops_out").notNull(),
15084
+ error: text("error"),
15085
+ local_sync_capability: text("local_sync_capability"),
15086
+ peer_sync_capability: text("peer_sync_capability"),
15087
+ negotiated_sync_capability: text("negotiated_sync_capability"),
15088
+ failure_category: text("failure_category")
15089
+ }, (table) => [
15090
+ index("idx_sync_attempts_peer_started").on(table.peer_device_id, table.started_at),
15091
+ index("idx_sync_attempts_occurred").on(sql`CASE WHEN ${table.finished_at} IS NULL THEN ${table.started_at} ELSE ${table.finished_at} END`, table.id),
15092
+ index("idx_sync_attempts_error_occurred").on(sql`CASE WHEN ${table.finished_at} IS NULL THEN ${table.started_at} ELSE ${table.finished_at} END`, table.id).where(sql`${table.ok} = 0`),
15093
+ index("idx_sync_attempts_success_occurred").on(sql`CASE WHEN ${table.finished_at} IS NULL THEN ${table.started_at} ELSE ${table.finished_at} END`, table.id).where(sql`${table.ok} <> 0`)
15094
+ ]);
15095
+ sqliteTable("sync_scope_rejections", {
15096
+ id: integer("id").primaryKey({ autoIncrement: true }),
15097
+ peer_device_id: text("peer_device_id"),
15098
+ op_id: text("op_id").notNull(),
15099
+ entity_type: text("entity_type").notNull(),
15100
+ entity_id: text("entity_id").notNull(),
15101
+ scope_id: text("scope_id"),
15102
+ reason: text("reason").notNull(),
15103
+ created_at: text("created_at").notNull()
15104
+ }, (table) => [index("idx_sync_scope_rejections_peer_created").on(table.peer_device_id, table.created_at), index("idx_sync_scope_rejections_scope_created").on(table.scope_id, table.created_at)]);
15105
+ sqliteTable("sync_daemon_state", {
15106
+ id: integer("id").primaryKey(),
15107
+ last_error: text("last_error"),
15108
+ last_traceback: text("last_traceback"),
15109
+ last_error_at: text("last_error_at"),
15110
+ last_ok_at: text("last_ok_at"),
15111
+ phase: text("phase")
15112
+ });
15113
+ sqliteTable("sync_reset_state", {
15114
+ id: integer("id").primaryKey(),
15115
+ generation: integer("generation").notNull(),
15116
+ snapshot_id: text("snapshot_id").notNull(),
15117
+ baseline_cursor: text("baseline_cursor"),
15118
+ retained_floor_cursor: text("retained_floor_cursor"),
15119
+ updated_at: text("updated_at").notNull()
15120
+ });
15121
+ sqliteTable("sync_reset_state_v2", {
15122
+ scope_id: text("scope_id").primaryKey(),
15123
+ generation: integer("generation").notNull(),
15124
+ snapshot_id: text("snapshot_id").notNull(),
15125
+ baseline_cursor: text("baseline_cursor"),
15126
+ retained_floor_cursor: text("retained_floor_cursor"),
15127
+ updated_at: text("updated_at").notNull()
15128
+ });
15129
+ sqliteTable("sync_retention_state", {
15130
+ id: integer("id").primaryKey(),
15131
+ last_run_at: text("last_run_at"),
15132
+ last_duration_ms: integer("last_duration_ms"),
15133
+ last_deleted_ops: integer("last_deleted_ops").notNull().default(0),
15134
+ last_estimated_bytes_before: integer("last_estimated_bytes_before"),
15135
+ last_estimated_bytes_after: integer("last_estimated_bytes_after"),
15136
+ retained_floor_cursor: text("retained_floor_cursor"),
15137
+ last_error: text("last_error"),
15138
+ last_error_at: text("last_error_at")
15139
+ });
15140
+ sqliteTable("sync_retention_state_v2", {
15141
+ scope_id: text("scope_id").primaryKey(),
15142
+ last_run_at: text("last_run_at"),
15143
+ last_duration_ms: integer("last_duration_ms"),
15144
+ last_deleted_ops: integer("last_deleted_ops").notNull().default(0),
15145
+ last_estimated_bytes_before: integer("last_estimated_bytes_before"),
15146
+ last_estimated_bytes_after: integer("last_estimated_bytes_after"),
15147
+ retained_floor_cursor: text("retained_floor_cursor"),
15148
+ last_error: text("last_error"),
15149
+ last_error_at: text("last_error_at")
15150
+ });
15151
+ sqliteTable("raw_event_ingest_samples", {
15152
+ id: integer("id").primaryKey({ autoIncrement: true }),
15153
+ created_at: text("created_at").notNull(),
15154
+ inserted_events: integer("inserted_events").notNull().default(0),
15155
+ skipped_invalid: integer("skipped_invalid").notNull().default(0),
15156
+ skipped_duplicate: integer("skipped_duplicate").notNull().default(0),
15157
+ skipped_conflict: integer("skipped_conflict").notNull().default(0)
15158
+ });
15159
+ sqliteTable("raw_event_ingest_stats", {
15160
+ id: integer("id").primaryKey(),
15161
+ inserted_events: integer("inserted_events").notNull().default(0),
15162
+ skipped_events: integer("skipped_events").notNull().default(0),
15163
+ skipped_invalid: integer("skipped_invalid").notNull().default(0),
15164
+ skipped_duplicate: integer("skipped_duplicate").notNull().default(0),
15165
+ skipped_conflict: integer("skipped_conflict").notNull().default(0),
15166
+ updated_at: text("updated_at").notNull()
15167
+ });
15168
+ sqliteTable("coordinator_group_preferences", {
15169
+ coordinator_id: text("coordinator_id").notNull(),
15170
+ group_id: text("group_id").notNull(),
15171
+ projects_include_json: text("projects_include_json"),
15172
+ projects_exclude_json: text("projects_exclude_json"),
15173
+ auto_seed_scope: integer("auto_seed_scope").notNull().default(1),
15174
+ default_space_scope_id: text("default_space_scope_id"),
15175
+ auto_grant_default_space_on_join: integer("auto_grant_default_space_on_join").notNull().default(0),
15176
+ updated_at: text("updated_at").notNull()
15177
+ }, (table) => ({ pk: primaryKey({ columns: [table.coordinator_id, table.group_id] }) }));
15178
+ sqliteTable("actors", {
15179
+ actor_id: text("actor_id").primaryKey(),
15180
+ display_name: text("display_name").notNull(),
15181
+ is_local: integer("is_local").notNull().default(0),
15182
+ status: text("status").notNull().default("active"),
15183
+ merged_into_actor_id: text("merged_into_actor_id"),
15184
+ created_at: text("created_at").notNull(),
15185
+ updated_at: text("updated_at").notNull()
15186
+ }, (table) => ({
15187
+ isLocalIdx: index("idx_actors_is_local").on(table.is_local),
15188
+ statusIdx: index("idx_actors_status").on(table.status)
15189
+ }));
15190
+ sqliteTable("recipient_policy_review_resolutions", {
15191
+ review_item_id: text("review_item_id").notNull(),
15192
+ source_fingerprint: text("source_fingerprint").notNull(),
15193
+ decision: text("decision").notNull(),
15194
+ decision_input_json: text("decision_input_json").notNull(),
15195
+ preview_json: text("preview_json").notNull(),
15196
+ decided_by_identity_id: text("decided_by_identity_id").notNull(),
15197
+ decided_by_device_id: text("decided_by_device_id").notNull(),
15198
+ resolved_at: text("resolved_at").notNull()
15199
+ }, (table) => [primaryKey({ columns: [table.review_item_id, table.source_fingerprint] })]);
15200
+ sqliteTable("coordinator_enrollment_reconciliation_issues", {
15201
+ coordinator_id: text("coordinator_id").notNull(),
15202
+ group_id: text("group_id").notNull(),
15203
+ kind: text("kind").notNull(),
15204
+ reference_id: text("reference_id").notNull(),
15205
+ code: text("code").notNull(),
15206
+ status: text("status").notNull().default("open"),
15207
+ first_seen_at: text("first_seen_at").notNull(),
15208
+ last_seen_at: text("last_seen_at").notNull(),
15209
+ resolved_at: text("resolved_at"),
15210
+ occurrence_count: integer("occurrence_count").notNull().default(1),
15211
+ updated_at: text("updated_at").notNull()
15212
+ }, (table) => [
15213
+ primaryKey({ columns: [
15214
+ table.coordinator_id,
15215
+ table.group_id,
15216
+ table.kind,
15217
+ table.reference_id,
15218
+ table.code
15219
+ ] }),
15220
+ index("idx_coordinator_enrollment_issues_boundary_status").on(table.coordinator_id, table.group_id, table.status),
15221
+ index("idx_coordinator_enrollment_issues_status_recent").on(table.status, table.last_seen_at, table.resolved_at)
15222
+ ]);
15223
+ var policyTeams = sqliteTable("policy_teams", {
15224
+ team_id: text("team_id").primaryKey(),
15225
+ display_name: text("display_name").notNull(),
15226
+ status: text("status").notNull(),
15227
+ device_eligibility_mode: text("device_eligibility_mode").notNull().default("person_all_devices"),
15228
+ provenance: text("provenance").notNull(),
15229
+ revision: text("revision").notNull(),
15230
+ migration_state: text("migration_state").notNull(),
15231
+ source_fingerprint: text("source_fingerprint"),
15232
+ idempotency_key: text("idempotency_key").notNull().unique(),
15233
+ created_at: text("created_at").notNull(),
15234
+ updated_at: text("updated_at").notNull()
15235
+ });
15236
+ sqliteTable("policy_team_memberships", {
15237
+ team_id: text("team_id").notNull(),
15238
+ identity_id: text("identity_id").notNull(),
15239
+ role: text("role").notNull(),
15240
+ status: text("status").notNull(),
15241
+ provenance: text("provenance").notNull(),
15242
+ revision: text("revision").notNull(),
15243
+ migration_state: text("migration_state").notNull(),
15244
+ source_fingerprint: text("source_fingerprint"),
15245
+ idempotency_key: text("idempotency_key").notNull().unique(),
15246
+ created_at: text("created_at").notNull(),
15247
+ updated_at: text("updated_at").notNull()
15248
+ }, (table) => ({
15249
+ pk: primaryKey({ columns: [table.team_id, table.identity_id] }),
15250
+ identityStatusIdx: index("idx_policy_team_memberships_identity_status").on(table.identity_id, table.status)
15251
+ }));
15252
+ sqliteTable("policy_team_device_decisions", {
15253
+ team_id: text("team_id").notNull().references(() => policyTeams.team_id, { onDelete: "cascade" }),
15254
+ device_id: text("device_id").notNull(),
15255
+ decision: text("decision").notNull(),
15256
+ assignment_version: integer("assignment_version").notNull().default(0),
15257
+ provenance: text("provenance").notNull(),
15258
+ revision: text("revision").notNull(),
15259
+ created_at: text("created_at").notNull(),
15260
+ updated_at: text("updated_at").notNull()
15261
+ }, (table) => [primaryKey({ columns: [table.team_id, table.device_id] }), index("idx_policy_team_device_decisions_device").on(table.device_id)]);
15262
+ sqliteTable("identity_devices", {
15263
+ device_id: text("device_id").primaryKey(),
15264
+ identity_id: text("identity_id").notNull(),
15265
+ display_name: text("display_name").notNull(),
15266
+ status: text("status").notNull(),
15267
+ provenance: text("provenance").notNull(),
15268
+ revision: text("revision").notNull(),
15269
+ migration_state: text("migration_state").notNull(),
15270
+ assignment_version: integer("assignment_version").notNull().default(0),
15271
+ source_fingerprint: text("source_fingerprint"),
15272
+ idempotency_key: text("idempotency_key").notNull().unique(),
15273
+ created_at: text("created_at").notNull(),
15274
+ updated_at: text("updated_at").notNull()
15275
+ }, (table) => ({ identityStatusIdx: index("idx_identity_devices_identity_status").on(table.identity_id, table.status) }));
15276
+ var deviceIdentityBindingCommits = sqliteTable("device_identity_binding_commits", {
15277
+ commit_digest: text("commit_digest").primaryKey(),
15278
+ reviewed_inventory_digest: text("reviewed_inventory_digest").notNull(),
15279
+ request_json: text("request_json").notNull(),
15280
+ outcomes_json: text("outcomes_json").notNull(),
15281
+ write_count: integer("write_count").notNull(),
15282
+ decided_by_identity_id: text("decided_by_identity_id").notNull(),
15283
+ decided_by_device_id: text("decided_by_device_id").notNull(),
15284
+ created_at: text("created_at").notNull()
15285
+ });
15286
+ sqliteTable("device_identity_binding_audit", {
15287
+ event_id: text("event_id").primaryKey(),
15288
+ commit_digest: text("commit_digest").notNull().references(() => deviceIdentityBindingCommits.commit_digest),
15289
+ device_id: text("device_id").notNull(),
15290
+ previous_identity_id: text("previous_identity_id"),
15291
+ target_identity_id: text("target_identity_id").notNull(),
15292
+ action: text("action").notNull(),
15293
+ previous_assignment_version: integer("previous_assignment_version"),
15294
+ resulting_assignment_version: integer("resulting_assignment_version").notNull(),
15295
+ decided_by_identity_id: text("decided_by_identity_id").notNull(),
15296
+ decided_by_device_id: text("decided_by_device_id").notNull(),
15297
+ created_at: text("created_at").notNull()
15298
+ }, (table) => [uniqueIndex("idx_device_identity_binding_audit_commit_device").on(table.commit_digest, table.device_id), index("idx_device_identity_binding_audit_device_created").on(table.device_id, table.created_at, table.event_id)]);
15299
+ sqliteTable("project_recipients", {
15300
+ canonical_project_identity: text("canonical_project_identity").notNull(),
15301
+ recipient_kind: text("recipient_kind").notNull(),
15302
+ recipient_id: text("recipient_id").notNull(),
15303
+ status: text("status").notNull(),
15304
+ provenance: text("provenance").notNull(),
15305
+ policy_revision: text("policy_revision").notNull(),
15306
+ migration_state: text("migration_state").notNull(),
15307
+ source_fingerprint: text("source_fingerprint"),
15308
+ idempotency_key: text("idempotency_key").notNull().unique(),
15309
+ created_at: text("created_at").notNull(),
15310
+ updated_at: text("updated_at").notNull()
15311
+ }, (table) => ({
15312
+ pk: primaryKey({ columns: [
15313
+ table.canonical_project_identity,
15314
+ table.recipient_kind,
15315
+ table.recipient_id
15316
+ ] }),
15317
+ projectStatusIdx: index("idx_project_recipients_project_status").on(table.canonical_project_identity, table.status),
15318
+ recipientStatusIdx: index("idx_project_recipients_recipient_status").on(table.recipient_kind, table.recipient_id, table.status)
15319
+ }));
15320
+ var legacyTeamSetupDrafts = sqliteTable("legacy_team_setup_drafts", {
15321
+ attempt_id: text("attempt_id").primaryKey(),
15322
+ candidate_id: text("candidate_id").notNull(),
15323
+ coordinator_id: text("coordinator_id").notNull(),
15324
+ group_id: text("group_id").notNull(),
15325
+ state: text("state").notNull().default("needs_setup"),
15326
+ display_name: text("display_name").notNull(),
15327
+ roster_fingerprint: text("roster_fingerprint").notNull(),
15328
+ projection_fingerprint: text("projection_fingerprint").notNull(),
15329
+ finish_digest: text("finish_digest"),
15330
+ safe_error_code: text("safe_error_code"),
15331
+ completed_team_id: text("completed_team_id"),
15332
+ created_at: text("created_at").notNull(),
15333
+ updated_at: text("updated_at").notNull(),
15334
+ completed_at: text("completed_at"),
15335
+ superseded_at: text("superseded_at")
15336
+ }, (table) => [
15337
+ index("idx_legacy_team_setup_drafts_candidate_state").on(table.candidate_id, table.state, table.created_at),
15338
+ index("idx_legacy_team_setup_drafts_state_updated").on(table.state, table.updated_at),
15339
+ index("idx_legacy_team_setup_drafts_finish_digest").on(table.finish_digest)
15340
+ ]);
15341
+ sqliteTable("legacy_team_setup_completions", {
15342
+ attempt_id: text("attempt_id").notNull(),
15343
+ finish_digest: text("finish_digest").notNull(),
15344
+ candidate_ref: text("candidate_ref").notNull(),
15345
+ confirmed_access_delta_digest: text("confirmed_access_delta_digest").notNull(),
15346
+ completed_team_id: text("completed_team_id").notNull(),
15347
+ response_json: text("response_json").notNull(),
15348
+ completed_at: text("completed_at").notNull(),
15349
+ created_at: text("created_at").notNull()
15350
+ }, (table) => [uniqueIndex("idx_legacy_team_setup_completions_attempt_finish").on(table.attempt_id, table.finish_digest), index("idx_legacy_team_setup_completions_exact_replay").on(table.candidate_ref, table.attempt_id, table.finish_digest, table.confirmed_access_delta_digest)]);
15351
+ sqliteTable("legacy_team_setup_draft_devices", {
15352
+ attempt_id: text("attempt_id").notNull().references(() => legacyTeamSetupDrafts.attempt_id, { onDelete: "cascade" }),
15353
+ device_id: text("device_id").notNull(),
15354
+ device_ref: text("device_ref").notNull(),
15355
+ key_fingerprint: text("key_fingerprint").notNull(),
15356
+ display_name: text("display_name").notNull(),
15357
+ enabled: integer("enabled", { mode: "boolean" }).notNull(),
15358
+ existing_identity_id: text("existing_identity_id"),
15359
+ existing_assignment_version: integer("existing_assignment_version"),
15360
+ verified_evidence_kind: text("verified_evidence_kind"),
15361
+ decision: text("decision").notNull().default("unresolved"),
15362
+ target_identity_id: text("target_identity_id"),
15363
+ expected_assignment_kind: text("expected_assignment_kind"),
15364
+ expected_assignment_version: integer("expected_assignment_version"),
15365
+ updated_at: text("updated_at").notNull()
15366
+ }, (table) => [
15367
+ primaryKey({ columns: [table.attempt_id, table.device_id] }),
15368
+ uniqueIndex("idx_legacy_team_setup_devices_attempt_ref").on(table.attempt_id, table.device_ref),
15369
+ index("idx_legacy_team_setup_devices_attempt_decision").on(table.attempt_id, table.decision)
15370
+ ]);
15371
+ sqliteTable("legacy_team_setup_draft_projects", {
15372
+ attempt_id: text("attempt_id").notNull().references(() => legacyTeamSetupDrafts.attempt_id, { onDelete: "cascade" }),
15373
+ project_ref: text("project_ref").notNull(),
15374
+ source_project_identity: text("source_project_identity").notNull(),
15375
+ display_name: text("display_name").notNull(),
15376
+ source_fingerprint: text("source_fingerprint").notNull(),
15377
+ resolution_kind: text("resolution_kind").notNull().default("unresolved"),
15378
+ resolved_project_identity: text("resolved_project_identity"),
15379
+ target_scope_id: text("target_scope_id"),
15380
+ updated_at: text("updated_at").notNull()
15381
+ }, (table) => [primaryKey({ columns: [table.attempt_id, table.project_ref] }), index("idx_legacy_team_setup_projects_attempt_resolution").on(table.attempt_id, table.resolution_kind)]);
15382
+ sqliteTable("recipient_managed_project_projections", {
15383
+ canonical_project_identity: text("canonical_project_identity").notNull(),
15384
+ display_name: text("display_name").notNull(),
15385
+ managed_scope_id: text("managed_scope_id").notNull(),
15386
+ coordinator_id: text("coordinator_id").notNull(),
15387
+ group_id: text("group_id").notNull(),
15388
+ recipient_identity_id: text("recipient_identity_id").notNull(),
15389
+ accepting_device_id: text("accepting_device_id").notNull(),
15390
+ source_operation_id: text("source_operation_id").notNull(),
15391
+ reviewed_project_set_digest: text("reviewed_project_set_digest").notNull(),
15392
+ status: text("status").notNull().default("active"),
15393
+ accepted_at: text("accepted_at").notNull(),
15394
+ revoked_at: text("revoked_at"),
15395
+ created_at: text("created_at").notNull(),
15396
+ updated_at: text("updated_at").notNull()
15397
+ }, (table) => [
15398
+ primaryKey({ columns: [table.source_operation_id, table.canonical_project_identity] }),
15399
+ index("idx_recipient_managed_projects_identity_status").on(table.recipient_identity_id, table.status),
15400
+ index("idx_recipient_managed_projects_scope_authority").on(table.managed_scope_id, table.coordinator_id, table.group_id, table.status)
15401
+ ]);
15402
+ sqliteTable("recipient_policy_authority_states", {
15403
+ canonical_project_identity: text("canonical_project_identity").primaryKey(),
15404
+ authority_state: text("authority_state").notNull().default("legacy"),
15405
+ generation: integer("generation").notNull().default(0),
15406
+ desired_devices_digest: text("desired_devices_digest"),
15407
+ current_devices_digest: text("current_devices_digest"),
15408
+ stable_parity_evidence_digest: text("stable_parity_evidence_digest"),
15409
+ stable_parity_passed_at: text("stable_parity_passed_at"),
15410
+ fresh_snapshot_fingerprint: text("fresh_snapshot_fingerprint"),
15411
+ fresh_snapshot_observed_at: text("fresh_snapshot_observed_at"),
15412
+ safe_error_code: text("safe_error_code"),
15413
+ state_changed_at: text("state_changed_at").notNull(),
15414
+ last_error_at: text("last_error_at"),
15415
+ attempt_count: integer("attempt_count").notNull().default(0),
15416
+ last_attempt_at: text("last_attempt_at"),
15417
+ wake_epoch: integer("wake_epoch").notNull().default(0),
15418
+ last_completed_at: text("last_completed_at"),
15419
+ lease_owner: text("lease_owner"),
15420
+ lease_acquired_at: text("lease_acquired_at"),
15421
+ lease_expires_at: text("lease_expires_at"),
15422
+ created_at: text("created_at").notNull(),
15423
+ updated_at: text("updated_at").notNull()
15424
+ });
15425
+ sqliteTable("recipient_policy_reconciliation_steps", {
15426
+ canonical_project_identity: text("canonical_project_identity").notNull(),
15427
+ generation: integer("generation").notNull(),
15428
+ step_key: text("step_key").notNull(),
15429
+ effect_id: text("effect_id").notNull(),
15430
+ payload_digest: text("payload_digest").notNull(),
15431
+ status: text("status").notNull().default("pending"),
15432
+ attempt_count: integer("attempt_count").notNull().default(0),
15433
+ started_at: text("started_at"),
15434
+ completed_at: text("completed_at"),
15435
+ last_attempt_at: text("last_attempt_at"),
15436
+ safe_error_code: text("safe_error_code"),
15437
+ error_at: text("error_at"),
15438
+ lease_owner: text("lease_owner"),
15439
+ lease_acquired_at: text("lease_acquired_at"),
15440
+ lease_expires_at: text("lease_expires_at"),
15441
+ created_at: text("created_at").notNull(),
15442
+ updated_at: text("updated_at").notNull()
15443
+ }, (table) => [
15444
+ primaryKey({ columns: [
15445
+ table.canonical_project_identity,
15446
+ table.generation,
15447
+ table.step_key
15448
+ ] }),
15449
+ uniqueIndex("idx_recipient_policy_reconciliation_steps_effect").on(table.effect_id),
15450
+ index("idx_recipient_policy_reconciliation_steps_status").on(table.canonical_project_identity, table.status),
15451
+ index("idx_recipient_policy_reconciliation_steps_pending_refresh").on(table.canonical_project_identity, table.generation, table.step_key).where(sql`${table.status} IN ('pending', 'running', 'failed') AND ${table.step_key} GLOB 'refresh-after-revocations-v2:*'`)
15452
+ ]);
15453
+ sqliteTable("recipient_policy_deny_overlays", {
15454
+ canonical_project_identity: text("canonical_project_identity").notNull(),
15455
+ scope_id: text("scope_id").notNull(),
15456
+ device_id: text("device_id").notNull(),
15457
+ generation: integer("generation").notNull(),
15458
+ reason_code: text("reason_code").notNull(),
15459
+ created_at: text("created_at").notNull(),
15460
+ updated_at: text("updated_at").notNull()
15461
+ }, (table) => [primaryKey({ columns: [
15462
+ table.canonical_project_identity,
15463
+ table.scope_id,
15464
+ table.device_id
15465
+ ] }), index("idx_recipient_policy_deny_overlays_scope_device").on(table.scope_id, table.device_id)]);
15466
+ //#endregion
15467
+ //#region ../core/src/coordinator-owner-profile-files.ts
15468
+ function ownerDatabaseFile(path) {
15469
+ const node = lstatSync(path, { bigint: true });
15470
+ if (!node.isFile() || node.isSymbolicLink()) return ownerProfileConflict();
15471
+ return `${node.dev}:${node.ino}`;
15472
+ }
15473
+ function ownerObject(value) {
15474
+ if (!value || typeof value !== "object" || Array.isArray(value)) return ownerProfileConflict();
15475
+ return value;
15476
+ }
15477
+ function assertFile(path, options = {}) {
15478
+ const stat = lstatSync(path);
15479
+ if (!stat.isFile() || stat.isSymbolicLink() || options.private && (stat.mode & 511) !== 384 || stat.size > 1048576) ownerProfileConflict();
15480
+ }
15481
+ function ownerFileSnapshot(path) {
15482
+ assertFile(path);
15483
+ const node = lstatSync(path, { bigint: true });
15484
+ return {
15485
+ text: readFileSync(path, "utf8"),
15486
+ dev: String(node.dev),
15487
+ ino: String(node.ino),
15488
+ ctime: String(node.ctimeNs)
15489
+ };
15490
+ }
15491
+ function readOwnerState(path) {
15492
+ assertFile(path, { private: true });
15493
+ return ownerObject(JSON.parse(readFileSync(path, "utf8")));
15494
+ }
15495
+ function syncDirectory(path) {
15496
+ const fd = openSync(path, "r");
15497
+ try {
15498
+ fsyncSync(fd);
15499
+ } finally {
15500
+ closeSync(fd);
15501
+ }
15502
+ }
15503
+ /** Sync an existing POSIX directory without changing its permissions or contents. */
15504
+ function syncOwnerProfileDirectory(path) {
15505
+ syncDirectory(path);
15506
+ }
15507
+ /** Durable, create-only publication; never overwrite a retained final request. */
15508
+ function retainOwnerState(path, value) {
15509
+ const text = JSON.stringify(value);
15510
+ if (text === void 0) ownerProfileConflict();
15511
+ const staged = stageOwnerState(path, text);
15512
+ linkSync(staged.path, path);
15513
+ syncDirectory(dirname(path));
15514
+ assertPublishedConfigLock(path, staged.snapshot);
15515
+ assertPublishedConfigLock(staged.path, staged.snapshot);
15516
+ unlinkSync(staged.path);
15517
+ syncDirectory(dirname(path));
15518
+ }
15519
+ function stageOwnerState(path, text) {
15520
+ const temporary = `${path}.tmp-${randomUUID()}`;
15521
+ const fd = openSync(temporary, "wx", 384);
15522
+ let identity;
15523
+ let closeAttempted = false;
15524
+ try {
15525
+ const node = fstatSync(fd, { bigint: true });
15526
+ identity = {
15527
+ dev: String(node.dev),
15528
+ ino: String(node.ino)
15529
+ };
15530
+ writeFileSync(fd, text);
15531
+ fsyncSync(fd);
15532
+ const snapshot = ownerFileSnapshot(temporary);
15533
+ if (snapshot.dev !== identity.dev || snapshot.ino !== identity.ino || snapshot.text !== text) ownerProfileConflict();
15534
+ syncDirectory(dirname(path));
15535
+ closeAttempted = true;
15536
+ closeSync(fd);
15537
+ return {
15538
+ path: temporary,
15539
+ snapshot
15540
+ };
15541
+ } catch (error) {
15542
+ if (identity) cleanupUnpublishedConfigLock(temporary, identity);
15543
+ if (!closeAttempted) closeSync(fd);
15544
+ throw error;
15545
+ }
15546
+ }
15547
+ function cleanupUnpublishedConfigLock(path, identity) {
15548
+ try {
15549
+ const node = lstatSync(path, { bigint: true });
15550
+ if (!node.isFile() || node.isSymbolicLink() || node.nlink !== 1n || String(node.dev) !== identity.dev || String(node.ino) !== identity.ino) return;
15551
+ unlinkSync(path);
15552
+ } catch {}
15553
+ }
15554
+ function assertPublishedConfigLock(path, staged) {
15555
+ const current = ownerFileSnapshot(path);
15556
+ if (current.dev !== staged.dev || current.ino !== staged.ino || current.text !== staged.text) ownerProfileConflict();
15557
+ return current;
15558
+ }
15559
+ //#endregion
15560
+ //#region ../core/src/account-owner-association-directory.ts
15561
+ function accountOwnerAssociationDirectory() {
15562
+ return join(homedir(), ".codemem", "account-owner-associations");
15563
+ }
15564
+ function checkDirectory(path, options = {}) {
15565
+ try {
15566
+ const stat = lstatSync(path);
15567
+ const unsafeMode = options.private ? (stat.mode & 511) !== 448 : (stat.mode & 18) !== 0;
15568
+ if (!stat.isDirectory() || stat.isSymbolicLink() || unsafeMode || typeof process.getuid === "function" && stat.uid !== process.getuid()) throw new Error("account_owner_association_invalid");
15569
+ return true;
15570
+ } catch (error) {
15571
+ if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") return false;
15572
+ throw error;
15573
+ }
15574
+ }
15575
+ /** Missing directories stay missing during reads. Never follow a state-directory symlink. */
15576
+ function readAccountOwnerAssociationDirectory(path) {
15577
+ return checkDirectory(dirname(path)) && checkDirectory(path, { private: true });
15578
+ }
15579
+ function createDirectory(path) {
15580
+ try {
15581
+ mkdirSync(path, { mode: 448 });
15582
+ } catch (error) {
15583
+ if (!error || typeof error !== "object" || !("code" in error) || error.code !== "EEXIST") throw error;
15584
+ }
15585
+ }
15586
+ /** Sync ancestors on every retry: an earlier mkdir may have become visible without its fsync. */
15587
+ function retainAccountOwnerAssociationDirectory(path) {
15588
+ const parent = dirname(path);
15589
+ createDirectory(parent);
15590
+ if (!checkDirectory(parent)) throw new Error("account_owner_association_invalid");
15591
+ syncOwnerProfileDirectory(dirname(parent));
15592
+ createDirectory(path);
15593
+ if (!checkDirectory(path, { private: true })) throw new Error("account_owner_association_invalid");
15594
+ syncOwnerProfileDirectory(parent);
15595
+ }
15596
+ //#endregion
15597
+ //#region ../core/src/coordinator-auth-browser-style.ts
15598
+ /** Standalone auth pages mirror the Viewer's tokens without loading remote assets.
15599
+ * Keep these palette values aligned with ui/static/{tokens,themes}.css.
15600
+ * Separate origins cannot read the Viewer's saved theme; use the OS preference.
15601
+ */
15602
+ var COORDINATOR_AUTH_STYLE = `
15603
+ :root{color-scheme:dark;--surface-0:#0b1016;--surface-1:#0f1720;--surface-2:#111c27;--text-primary:#e7f0f7;--text-secondary:#b7c5d3;--accent:#7ef0c2;--accent-hover:#9eff87;--border:rgba(126,240,194,.12);--border-strong:rgba(126,240,194,.28);--font-sans:"Geist",system-ui,-apple-system,sans-serif;--font-mono:"JetBrains Mono",ui-monospace,monospace;font-family:var(--font-sans);color:var(--text-primary);background:var(--surface-0)}
15604
+ *{box-sizing:border-box}body{margin:0;padding:clamp(1rem,5vw,4rem) 1rem;line-height:1.6}main{max-width:34rem;margin:0 auto;padding:clamp(1.25rem,4vw,2rem);border:1px solid var(--border-strong);border-radius:20px;background:var(--surface-1)}
15605
+ .brand{display:flex;align-items:center;gap:.6rem;margin:0 0 1.5rem;color:var(--accent);font-size:.875rem;font-weight:700;letter-spacing:.02em}.brand::before{content:"";width:.65rem;height:.65rem;border-radius:3px;background:var(--accent)}
15606
+ h1,h2{font-family:inherit;font-weight:600;line-height:1.25;letter-spacing:-.025em}h1{font-size:1.6rem;margin:0 0 1rem}h2{font-size:1.05rem;margin:0 0 .5rem}p{margin:.5rem 0}section{padding:1.25rem 0;border-bottom:1px solid var(--border)}.eyebrow{font-size:.75rem;letter-spacing:.08em;text-transform:uppercase;color:var(--text-secondary)}
15607
+ .profile{display:flex;align-items:center;gap:1rem}.profile-text{min-width:0;overflow-wrap:anywhere}.avatar{position:relative;display:inline-flex;align-items:center;justify-content:center;flex:0 0 3rem;width:3rem;height:3rem;border-radius:50%;background:var(--surface-2);color:var(--accent);overflow:hidden}.initials{font-weight:700}.avatar img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.note{font-size:.875rem;color:var(--text-secondary)}
15608
+ dl{margin:0}dt{font-size:.8rem;font-weight:600;color:var(--text-secondary);margin-top:1rem}dd{margin:.25rem 0 0}code{font-family:var(--font-mono);font-size:.8rem;overflow-wrap:anywhere;white-space:pre-wrap}
15609
+ .actions{display:flex;flex-wrap:wrap;gap:.75rem;margin:1.5rem 0 0}form{margin:0}button,.link{font:inherit;font-size:.875rem;font-weight:600;display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:.65rem 1rem;border:1px solid var(--border-strong);border-radius:10px;background:var(--accent);color:var(--surface-0);cursor:pointer;text-decoration:none}button.secondary{background:transparent;color:var(--accent)}a{color:var(--accent)}button:hover,.link:hover{background:var(--accent-hover);color:var(--surface-0)}:focus-visible{outline:3px solid var(--accent);outline-offset:4px}
15610
+ @media(prefers-color-scheme:light){:root{color-scheme:light;--surface-0:#f7faf8;--surface-1:#fff;--surface-2:#eef5f1;--text-primary:#0b1016;--text-secondary:#3f4d5c;--accent:#0f8a68;--accent-hover:#0a6f53;--border:rgba(15,138,104,.16);--border-strong:rgba(15,138,104,.3)}button,.link,button:hover,.link:hover{color:#fff}button.secondary{color:var(--accent)}button.secondary:hover{color:#fff}}
15611
+ @media(max-width:30rem){body{padding:1rem}.actions{flex-direction:column}.actions form,.actions button,.actions .link{width:100%}h1{font-size:1.4rem}}
15612
+ `;
15613
+ //#endregion
15614
+ //#region ../core/src/coordinator-account-link-receiver.ts
15615
+ function normalizeCoordinatorAccountLinkOrigin$1(value) {
15616
+ if (typeof value !== "string") return null;
15617
+ try {
15618
+ const url = new URL(value);
15619
+ if (!(url.protocol === "http:" && (url.hostname === "127.0.0.1" || url.hostname === "[::1]")) && url.protocol !== "https:" || url.username || url.password || url.pathname !== "/" || url.search || url.hash || value.includes("\\") || /[\s\p{Cc}]/u.test(value) || value.includes("?") || value.includes("#") || value !== url.origin && value !== `${url.origin}/`) return null;
15620
+ return url.origin;
15621
+ } catch {
15622
+ return null;
15623
+ }
15624
+ }
15625
+ `${createHash("sha256").update(COORDINATOR_AUTH_STYLE).digest("base64")}`;
15626
+ //#endregion
15627
+ //#region ../core/src/account-owner-association.ts
15628
+ var PIN_FIELDS = [
15629
+ "databaseFile",
15630
+ "deviceId",
15631
+ "keyId",
15632
+ "fingerprint",
15633
+ "actorId",
15634
+ "coordinatorUrl",
15635
+ "coordinatorId",
15636
+ "groupId"
15637
+ ];
15638
+ var REVIEW_FIELDS = [
15639
+ "ownerIdentityId",
15640
+ "attestationId",
15641
+ "reviewDigest"
15642
+ ];
15643
+ function invalidAssociation() {
15644
+ throw new Error("account_owner_association_invalid");
15645
+ }
15646
+ function hash(value) {
15647
+ return createHash("sha256").update(value).digest("hex");
15648
+ }
15649
+ /** Local context only, not authority. Does not inspect the running actor or its config. */
15650
+ function captureAccountOwnerProfilePins$1(profile) {
15651
+ const origin = normalizeCoordinatorAccountLinkOrigin$1(profile.coordinatorUrl);
15652
+ const key = parseSshEd25519PublicKey(profile.publicKey);
15653
+ if (!origin || key.kind !== "ed25519" || !isAuthControllerId(profile.actorId) || !isAuthControllerId(profile.deviceId) || !isAuthControllerId(profile.groupId) || !isAuthControllerId(profile.coordinatorId) || typeof profile.fingerprint !== "string" || !/^[a-f0-9]{64}$/.test(profile.fingerprint)) return invalidAssociation();
15654
+ return {
15655
+ databaseFile: ownerDatabaseFile(profile.dbPath),
15656
+ deviceId: profile.deviceId,
15657
+ keyId: hash(key.blob),
15658
+ fingerprint: profile.fingerprint,
15659
+ actorId: profile.actorId,
15660
+ coordinatorUrl: origin,
15661
+ coordinatorId: profile.coordinatorId,
15662
+ groupId: profile.groupId
15663
+ };
15664
+ }
15665
+ var profilePins = captureAccountOwnerProfilePins$1;
15666
+ function ownData(value, fields) {
15667
+ if (!value || typeof value !== "object") return invalidAssociation();
15668
+ const prototype = Object.getPrototypeOf(value);
15669
+ if (prototype !== Object.prototype && prototype !== null) return invalidAssociation();
15670
+ const descriptors = Object.getOwnPropertyDescriptors(value);
15671
+ if (Reflect.ownKeys(descriptors).length !== fields.length) return invalidAssociation();
15672
+ return Object.fromEntries(fields.map((field) => {
15673
+ const descriptor = descriptors[field];
15674
+ if (!Object.hasOwn(descriptors, field) || !descriptor || !("value" in descriptor)) return invalidAssociation();
15675
+ return [field, descriptor.value];
15676
+ }));
15677
+ }
15678
+ function captureStoredPins(value) {
15679
+ if (typeof value.databaseFile !== "string" || !/^(0|[1-9][0-9]*):(0|[1-9][0-9]*)$/.test(value.databaseFile) || !isAuthControllerId(value.deviceId) || !isAuthControllerId(value.actorId) || !isAuthControllerId(value.coordinatorId) || !isAuthControllerId(value.groupId) || typeof value.keyId !== "string" || !/^[a-f0-9]{64}$/.test(value.keyId) || typeof value.fingerprint !== "string" || !/^[a-f0-9]{64}$/.test(value.fingerprint) || typeof value.coordinatorUrl !== "string" || normalizeCoordinatorAccountLinkOrigin$1(value.coordinatorUrl) !== value.coordinatorUrl) return invalidAssociation();
15680
+ return {
15681
+ databaseFile: value.databaseFile,
15682
+ deviceId: value.deviceId,
15683
+ keyId: value.keyId,
15684
+ fingerprint: value.fingerprint,
15685
+ actorId: value.actorId,
15686
+ coordinatorUrl: value.coordinatorUrl,
15687
+ coordinatorId: value.coordinatorId,
15688
+ groupId: value.groupId
15689
+ };
15690
+ }
15691
+ function pinsMatch(value, expected) {
15692
+ return PIN_FIELDS.every((field) => value[field] === expected[field]);
15693
+ }
15694
+ function captureStoredAssociation(input) {
15695
+ const value = ownData(input, [
15696
+ "version",
15697
+ ...PIN_FIELDS,
15698
+ ...REVIEW_FIELDS
15699
+ ]);
15700
+ const pins = captureStoredPins(value);
15701
+ if (value.version !== 1 || !isAuthControllerId(value.ownerIdentityId) || !isAuthControllerId(value.attestationId) || typeof value.reviewDigest !== "string" || !/^[a-f0-9]{64}$/.test(value.reviewDigest)) return invalidAssociation();
15702
+ return {
15703
+ version: 1,
15704
+ ...pins,
15705
+ ownerIdentityId: value.ownerIdentityId,
15706
+ attestationId: value.attestationId,
15707
+ reviewDigest: value.reviewDigest
15708
+ };
15709
+ }
15710
+ function associationPath(profile) {
15711
+ const origin = normalizeCoordinatorAccountLinkOrigin$1(profile.coordinatorUrl);
15712
+ if (!origin || !isAuthControllerId(profile.groupId)) return invalidAssociation();
15713
+ const scope = hash(JSON.stringify([
15714
+ origin,
15715
+ profile.coordinatorId,
15716
+ profile.groupId
15717
+ ])).slice(0, 32);
15718
+ return `${resolve(profile.dbPath)}.account-owner-${scope}.json`;
15719
+ }
15720
+ function captureAssociation(value, profile) {
15721
+ const record = captureStoredAssociation(value);
15722
+ if (!pinsMatch(record, profilePins(profile))) return invalidAssociation();
15723
+ return record;
15724
+ }
15725
+ function captureGeneration(profile, expected) {
15726
+ const expectedPins = captureStoredPins(ownData(expected, PIN_FIELDS));
15727
+ const dbPath = resolve(profile.dbPath);
15728
+ const pins = profilePins({
15729
+ ...profile,
15730
+ dbPath
15731
+ });
15732
+ if (!pinsMatch(pins, expectedPins)) return invalidAssociation();
15733
+ const scope = hash(JSON.stringify([
15734
+ pins.coordinatorUrl,
15735
+ pins.coordinatorId,
15736
+ pins.groupId
15737
+ ])).slice(0, 32);
15738
+ const base = `${dbPath}.account-owner-${scope}`;
15739
+ const generation = hash(JSON.stringify(pins));
15740
+ const basenameBase = join(dirname(dbPath), `${hash(basename(dbPath))}.account-owner-${scope}`);
15741
+ return {
15742
+ dbPath,
15743
+ pins,
15744
+ legacyPath: `${base}.json`,
15745
+ previousPaths: [`${base}-${generation}.json`, `${basenameBase}-${generation}.json`],
15746
+ path: join(accountOwnerAssociationDirectory(), `.account-owner-${generation}.json`)
15747
+ };
15748
+ }
15749
+ function assertGenerationCurrent(profile, context) {
15750
+ try {
15751
+ if (resolve(profile.dbPath) === context.dbPath && pinsMatch(profilePins(profile), context.pins)) return;
15752
+ } catch {}
15753
+ throw new Error("account_owner_association_context_changed_outcome_unknown");
15754
+ }
15755
+ function readStoredAssociation(path, options = {}) {
15756
+ try {
15757
+ lstatSync(path);
15758
+ } catch (error) {
15759
+ if (error && typeof error === "object" && "code" in error) {
15760
+ if (error.code === "ENOENT") return null;
15761
+ if (options.historicalPath && error.code === "ENAMETOOLONG") return null;
15762
+ }
15763
+ return invalidAssociation();
15764
+ }
15765
+ try {
15766
+ const stat = lstatSync(path);
15767
+ if (typeof process.getuid === "function" && stat.uid !== process.getuid()) return invalidAssociation();
15768
+ return captureStoredAssociation(readOwnerState(path));
15769
+ } catch {
15770
+ return invalidAssociation();
15771
+ }
15772
+ }
15773
+ function readGeneration(context) {
15774
+ const legacy = readStoredAssociation(context.legacyPath, { historicalPath: true });
15775
+ let found = null;
15776
+ const paths = [...context.previousPaths];
15777
+ if (readAccountOwnerAssociationDirectory(dirname(context.path))) paths.push(context.path);
15778
+ for (const path of paths) {
15779
+ const record = readStoredAssociation(path, { historicalPath: path !== context.path });
15780
+ if (!record) continue;
15781
+ if (!pinsMatch(record, context.pins)) return invalidAssociation();
15782
+ if (found && JSON.stringify(found.record) !== JSON.stringify(record)) return invalidAssociation();
15783
+ found = {
15784
+ record,
15785
+ path
15786
+ };
15787
+ }
15788
+ if (found) return found;
15789
+ if (legacy && pinsMatch(legacy, context.pins)) return {
15790
+ record: legacy,
15791
+ path: context.legacyPath
15792
+ };
15793
+ return null;
15794
+ }
15795
+ /**
15796
+ * Read without initializing the database, changing the actor, or granting access.
15797
+ * Expected pins opt trusted local callers into exact generations; omitted pins keep legacy behavior.
15798
+ */
15799
+ function readAccountOwnerAssociation$1(profile, options) {
15800
+ if (options?.expectedProfilePins !== void 0) {
15801
+ const context = captureGeneration(profile, options.expectedProfilePins);
15802
+ const record = readGeneration(context);
15803
+ assertGenerationCurrent(profile, context);
15804
+ return record?.record ?? null;
15805
+ }
15806
+ const path = associationPath(profile);
15807
+ try {
15808
+ lstatSync(path);
15809
+ } catch (error) {
15810
+ if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") return null;
15811
+ return invalidAssociation();
15812
+ }
15813
+ try {
15814
+ const stat = lstatSync(path);
15815
+ if (typeof process.getuid === "function" && stat.uid !== process.getuid()) return invalidAssociation();
15816
+ return captureAssociation(readOwnerState(path), profile);
15817
+ } catch {
15818
+ return invalidAssociation();
15819
+ }
15820
+ }
15821
+ /**
15822
+ * Create-only publication after review; an exact retry never replaces prior owner evidence.
15823
+ * Generation checks cover this profile object and the DB file, not runtime actor/config state.
15824
+ * A future recovery service must check that state before and after calling this helper.
15825
+ * Pathname replacement and restoration between checks is not detected atomically.
15826
+ */
15827
+ function retainAccountOwnerAssociation(profile, input, options) {
15828
+ const review = ownData(input, REVIEW_FIELDS);
15829
+ if (options?.expectedProfilePins !== void 0) return retainGeneration(profile, review, captureGeneration(profile, options.expectedProfilePins));
15830
+ const record = captureAssociation({
15831
+ version: 1,
15832
+ ...profilePins(profile),
15833
+ ...review
15834
+ }, profile);
15835
+ const existing = readAccountOwnerAssociation$1(profile);
15836
+ if (existing) {
15837
+ if (JSON.stringify(existing) !== JSON.stringify(record)) return invalidAssociation();
15838
+ syncOwnerProfileDirectory(dirname(associationPath(profile)));
15839
+ return existing;
15840
+ }
15841
+ try {
15842
+ retainOwnerState(associationPath(profile), record);
15843
+ } catch (error) {
15844
+ if (!error || typeof error !== "object" || !("code" in error) || error.code !== "EEXIST") return invalidAssociation();
15845
+ }
15846
+ const retained = readAccountOwnerAssociation$1(profile);
15847
+ if (!retained || JSON.stringify(retained) !== JSON.stringify(record)) return invalidAssociation();
15848
+ syncOwnerProfileDirectory(dirname(associationPath(profile)));
15849
+ return retained;
15850
+ }
15851
+ function retainGeneration(profile, review, context) {
15852
+ const record = captureStoredAssociation({
15853
+ version: 1,
15854
+ ...context.pins,
15855
+ ...review
15856
+ });
15857
+ const existing = readGeneration(context);
15858
+ assertGenerationCurrent(profile, context);
15859
+ if (existing && JSON.stringify(existing.record) !== JSON.stringify(record)) return invalidAssociation();
15860
+ retainAccountOwnerAssociationDirectory(dirname(context.path));
15861
+ assertGenerationCurrent(profile, context);
15862
+ if (existing?.path === context.path) {
15863
+ syncOwnerProfileDirectory(dirname(context.path));
15864
+ assertGenerationCurrent(profile, context);
15865
+ return existing.record;
15866
+ }
15867
+ try {
15868
+ retainOwnerState(context.path, record);
15869
+ } catch (error) {
15870
+ if (!error || typeof error !== "object" || !("code" in error) || error.code !== "EEXIST") return invalidAssociation();
15871
+ }
15872
+ assertGenerationCurrent(profile, context);
15873
+ const retained = readGeneration(context);
15874
+ if (!retained || JSON.stringify(retained.record) !== JSON.stringify(record)) return invalidAssociation();
15875
+ syncOwnerProfileDirectory(dirname(context.path));
15876
+ assertGenerationCurrent(profile, context);
15877
+ return retained.record;
15878
+ }
15879
+ //#endregion
15880
+ //#region src/account/owner-recovery-context.ts
15881
+ function recoverySha(value) {
15882
+ return createHash("sha256").update(value).digest("hex");
15883
+ }
15884
+ function captureDevice(context) {
15885
+ const before = statSync(context.dbPath, { bigint: true });
15886
+ const device = readAccountLinkDevice(context.dbPath);
15887
+ const publicKey = loadPublicKey(context.keysDir);
15888
+ const after = statSync(context.dbPath, { bigint: true });
15889
+ requireRecovery(before.isFile() && before.dev === after.dev && before.ino === after.ino && after.dev.toString() === context.fileIdentity.dev && after.ino.toString() === context.fileIdentity.ino && device.deviceId === context.deviceId && device.fingerprint === context.fingerprint && recoverySha(device.publicKey) === context.publicKeyHash && publicKey === device.publicKey);
15890
+ return device.publicKey;
15891
+ }
15892
+ function captureRecoveryContext(readContext) {
15893
+ let result = readContext();
15894
+ requireRecovery(!("error" in result) && result.groups.length > 0 && result.groups.length <= 25);
15895
+ if (!result.context) result = readContext(result.groups[0]);
15896
+ requireRecovery(!("error" in result) && result.setup === "ready" && result.context);
15897
+ const context = structuredClone(result.context);
15898
+ const groups = [...result.groups].sort();
15899
+ requireRecovery(groups.every(recoveryId) && new Set(groups).size === groups.length && recoveryId(context.identityId));
15900
+ return {
15901
+ context,
15902
+ groups,
15903
+ publicKey: captureDevice(context),
15904
+ semanticId: recoverySha(JSON.stringify([
15905
+ resolve(context.dbPath),
15906
+ context.keysDir === void 0 ? null : resolve(context.keysDir),
15907
+ context.configPath === void 0 ? null : resolve(context.configPath),
15908
+ context.fileIdentity,
15909
+ context.identityId,
15910
+ context.deviceId,
15911
+ context.publicKeyHash,
15912
+ context.fingerprint,
15913
+ context.coordinatorUrl,
15914
+ groups
15915
+ ]))
15916
+ };
15917
+ }
15918
+ function recoveryProfile(capture, coordinatorId) {
15919
+ const context = capture.context;
15920
+ return {
15921
+ contextId: recoverySha(JSON.stringify([capture.semanticId, coordinatorId])),
15922
+ memoryActorId: context.identityId,
15923
+ deviceId: context.deviceId,
15924
+ fingerprint: context.fingerprint,
15925
+ coordinatorOrigin: context.coordinatorUrl,
15926
+ coordinatorId,
15927
+ configuredGroups: [...capture.groups]
15928
+ };
15929
+ }
15930
+ function assertRecoverySelection(selection, expected) {
15931
+ requireRecovery(JSON.stringify(selection.profile) === JSON.stringify(expected) && recoveryId(selection.existingOwnerId) && Array.isArray(selection.groups) && selection.groups.length > 0 && selection.groups.length <= 25 && new Set(selection.groups).size === selection.groups.length && selection.groups.every((group) => expected.configuredGroups.includes(group)));
15932
+ }
15933
+ function recoveryDestinations(capture, coordinatorId) {
15934
+ return new Map(capture.groups.map((groupId) => {
15935
+ const profile = {
15936
+ dbPath: capture.context.dbPath,
15937
+ deviceId: capture.context.deviceId,
15938
+ publicKey: capture.publicKey,
15939
+ fingerprint: capture.context.fingerprint,
15940
+ actorId: capture.context.identityId,
15941
+ coordinatorUrl: capture.context.coordinatorUrl,
15942
+ coordinatorId,
15943
+ groupId
15944
+ };
15945
+ return [groupId, {
15946
+ profile,
15947
+ pins: captureAccountOwnerProfilePins(profile)
15948
+ }];
15949
+ }));
15950
+ }
15951
+ function assertNoCompetingOwner(destinations, ownerIdentityId) {
15952
+ for (const { profile, pins } of destinations.values()) {
15953
+ const existing = readAccountOwnerAssociation(profile, { expectedProfilePins: pins });
15954
+ requireRecovery(!existing || existing.ownerIdentityId === ownerIdentityId);
15955
+ }
15956
+ }
15957
+ //#endregion
15958
+ //#region src/account/owner-recovery-service.ts
15959
+ function groupAction(state) {
15960
+ if (state === "ready") return "new";
15961
+ if (state === "restored") return "reuse";
15962
+ return "blocked";
15963
+ }
15964
+ function uniqueRows(rows) {
15965
+ return [...new Map(rows.map((row) => [JSON.stringify(row), row])).values()];
15966
+ }
15967
+ function staleDenial(error) {
15968
+ return error instanceof Error && "status" in error && error.status === 409 && "code" in error && error.code === "review_stale";
15969
+ }
15970
+ /** No routes or configuration composition: these callbacks are private server capabilities. */
15971
+ var AccountOwnerRecoveryService = class {
15972
+ #options;
15973
+ #handles = /* @__PURE__ */ new Map();
15974
+ #reservations = /* @__PURE__ */ new Set();
15975
+ #controller = new AbortController();
15976
+ #closed = false;
15977
+ constructor(options) {
15978
+ this.#options = options;
15979
+ }
15980
+ #now() {
15981
+ return (this.#options.now ?? Date.now)();
15982
+ }
15983
+ #assertCurrent(capture, reservation) {
15984
+ requireRecovery(!this.#closed, "unavailable");
15985
+ requireRecovery(!reservation || reservation.isCurrent(), "context_changed");
15986
+ requireRecovery(captureRecoveryContext(this.#options.readContext).semanticId === capture.semanticId && !this.#closed && (!reservation || reservation.isCurrent()), "context_changed");
15987
+ }
15988
+ #capture() {
15989
+ requireRecovery(!this.#closed, "unavailable");
15990
+ const capture = captureRecoveryContext(this.#options.readContext);
15991
+ this.#assertCurrent(capture);
15992
+ return capture;
15993
+ }
15994
+ async #discover(capture) {
15995
+ this.#assertCurrent(capture);
15996
+ const c = capture.context;
15997
+ const response = await (this.#options.readRemoteStatus ?? readCoordinatorAccountLinkStatus)({
15998
+ dbPath: c.dbPath,
15999
+ keysDir: c.keysDir,
16000
+ coordinatorUrl: c.coordinatorUrl,
16001
+ groupId: c.groupId,
16002
+ identityId: c.identityId,
16003
+ signal: this.#controller.signal
16004
+ });
16005
+ this.#assertCurrent(capture);
16006
+ requireRecovery(response.kind === "status" && recoveryId(response.status.coordinatorId) && response.status.deviceId === c.deviceId && response.status.fingerprint === c.fingerprint && response.status.groupId === c.groupId, "unavailable");
16007
+ return response.status.coordinatorId;
16008
+ }
16009
+ async getProfile() {
16010
+ const capture = this.#capture();
16011
+ const coordinatorId = await this.#discover(capture);
16012
+ this.#assertCurrent(capture);
16013
+ const reviewAccess = this.#options.readAdminSecret() ? "operator" : "request";
16014
+ this.#assertCurrent(capture);
16015
+ return {
16016
+ version: 1,
16017
+ profile: recoveryProfile(capture, coordinatorId),
16018
+ reviewAccess,
16019
+ candidates: []
16020
+ };
16021
+ }
16022
+ #reviewInput(capture, selection, groupId) {
16023
+ const adminSecret = this.#options.readAdminSecret();
16024
+ requireRecovery(typeof adminSecret === "string" && adminSecret.length > 0);
16025
+ this.#assertCurrent(capture);
16026
+ return {
16027
+ remoteUrl: capture.context.coordinatorUrl,
16028
+ adminSecret,
16029
+ purpose: "existing_account_owner",
16030
+ resolutionScope: RECOVERY_SCOPE,
16031
+ groupId,
16032
+ deviceId: capture.context.deviceId,
16033
+ fingerprint: capture.context.fingerprint,
16034
+ identityId: selection.existingOwnerId
16035
+ };
16036
+ }
16037
+ async #previewReview(entry, groupId) {
16038
+ const input = this.#reviewInput(entry.capture, entry.preview, groupId);
16039
+ this.#assertCurrent(entry.capture);
16040
+ const raw = await (this.#options.reviewOwner ?? coordinatorAuthControllerReviewAction)(input);
16041
+ this.#assertCurrent(entry.capture);
16042
+ const evidence = structuredClone(raw);
16043
+ entry.reviews.set(groupId, validateRecoveryReview(evidence, entry.preview, groupId));
16044
+ entry.evidence.set(groupId, evidence);
16045
+ }
16046
+ #newReview(request, capture) {
16047
+ return {
16048
+ capture,
16049
+ destinations: recoveryDestinations(capture, request.profile.coordinatorId),
16050
+ purpose: request.purpose,
16051
+ createdAt: this.#now(),
16052
+ reviews: /* @__PURE__ */ new Map(),
16053
+ evidence: /* @__PURE__ */ new Map(),
16054
+ preview: {
16055
+ ...structuredClone(request),
16056
+ scope: RECOVERY_SCOPE,
16057
+ approvalDigest: randomBytes(32).toString("hex"),
16058
+ groupPreviews: [],
16059
+ history: {
16060
+ complete: false,
16061
+ rows: [],
16062
+ operatorHelp: "Ask the coordinator operator to review the existing account owner and provide receipt references."
16063
+ },
16064
+ reviewedWeakLabels: []
16065
+ }
16066
+ };
16067
+ }
16068
+ #projectReviews(entry) {
16069
+ const reviews = [...entry.reviews.values()];
16070
+ entry.preview.history = {
16071
+ complete: true,
16072
+ rows: uniqueRows(reviews.flatMap((review) => review.rows))
16073
+ };
16074
+ entry.preview.reviewedWeakLabels = uniqueRows(reviews.flatMap((review) => review.labels));
16075
+ entry.preview.groupPreviews = entry.preview.groups.map((groupId) => {
16076
+ const review = entry.reviews.get(groupId);
16077
+ requireRecovery(review);
16078
+ return {
16079
+ groupId,
16080
+ action: groupAction(review.state),
16081
+ reason: review.state === "needs_review" ? review.reasons.join("; ") : "Fresh coordinator owner review."
16082
+ };
16083
+ });
16084
+ }
16085
+ #retainHandle(entry) {
16086
+ for (const [key, value] of this.#handles) if (this.#now() - value.createdAt >= 3e5) this.#handles.delete(key);
16087
+ while (this.#handles.size >= 16) {
16088
+ const oldest = this.#handles.keys().next().value;
16089
+ requireRecovery(oldest);
16090
+ this.#handles.delete(oldest);
16091
+ }
16092
+ this.#handles.set(entry.preview.approvalDigest, entry);
16093
+ return structuredClone(entry.preview);
16094
+ }
16095
+ async preview(request) {
16096
+ const capture = this.#capture();
16097
+ const coordinatorId = await this.#discover(capture);
16098
+ this.#assertCurrent(capture);
16099
+ assertRecoverySelection(request, recoveryProfile(capture, coordinatorId));
16100
+ requireRecovery(recoveryId(request.requestId) && (request.purpose === "review" || request.purpose === "check_status"));
16101
+ const entry = this.#newReview(request, capture);
16102
+ const admin = this.#options.readAdminSecret();
16103
+ this.#assertCurrent(capture);
16104
+ if (admin) {
16105
+ for (const groupId of entry.preview.groups) await this.#previewReview(entry, groupId);
16106
+ this.#projectReviews(entry);
16107
+ } else await this.#requestAssistance(entry);
16108
+ this.#assertCurrent(capture);
16109
+ return this.#retainHandle(entry);
16110
+ }
16111
+ async #requestAssistance(entry) {
16112
+ for (const groupId of entry.preview.groups) {
16113
+ this.#assertCurrent(entry.capture);
16114
+ await (this.#options.readRemoteOwnerStatus ?? readCoordinatorResolvedAccountOwnerStatus)({
16115
+ ...entry.capture.context,
16116
+ groupId,
16117
+ ownerIdentityId: entry.preview.existingOwnerId,
16118
+ signal: this.#controller.signal
16119
+ });
16120
+ this.#assertCurrent(entry.capture);
16121
+ }
16122
+ entry.preview.groupPreviews = entry.preview.groups.map((groupId) => ({
16123
+ groupId,
16124
+ action: "blocked",
16125
+ reason: "An operator must review the full retained history."
16126
+ }));
16127
+ }
16128
+ #reserve() {
16129
+ requireRecovery(!this.#closed, "unavailable");
16130
+ const reservation = this.#options.registry.tryReserveRecovery?.();
16131
+ requireRecovery(reservation, "busy");
16132
+ requireRecovery(reservation.isCurrent(), "context_changed");
16133
+ this.#reservations.add(reservation);
16134
+ return reservation;
16135
+ }
16136
+ #release(reservation) {
16137
+ reservation.release();
16138
+ this.#reservations.delete(reservation);
16139
+ }
16140
+ async confirm(input) {
16141
+ requireRecovery(!this.#closed, "unavailable");
16142
+ const entry = this.#handles.get(input.approvalDigest);
16143
+ requireRecovery(entry && JSON.stringify(entry.preview) === JSON.stringify(input.preview));
16144
+ if (entry.outcome) return structuredClone(await entry.outcome);
16145
+ requireRecovery(this.#now() - entry.createdAt < 3e5 && entry.purpose === "review" && entry.preview.history.complete && entry.preview.groupPreviews.every((group) => group.action !== "blocked"));
16146
+ const reservation = this.#reserve();
16147
+ entry.outcome = this.#applyReview(entry, reservation).finally(() => this.#release(reservation));
16148
+ return structuredClone(await entry.outcome);
16149
+ }
16150
+ async #applyReview(entry, reservation) {
16151
+ this.#assertCurrent(entry.capture, reservation);
16152
+ assertNoCompetingOwner(entry.destinations, entry.preview.existingOwnerId);
16153
+ this.#assertCurrent(entry.capture, reservation);
16154
+ const groups = [];
16155
+ let verifiedReceipt;
16156
+ for (const groupId of entry.preview.groups) {
16157
+ const applied = await this.#applyGroup(entry, groupId, reservation, { verifiedReceipt });
16158
+ groups.push(applied.outcome);
16159
+ verifiedReceipt ??= applied.verifiedReceipt;
16160
+ }
16161
+ return {
16162
+ preview: structuredClone(entry.preview),
16163
+ groups
16164
+ };
16165
+ }
16166
+ async #confirmNew(entry, groupId, reservation) {
16167
+ const review = entry.reviews.get(groupId);
16168
+ requireRecovery(review?.digest);
16169
+ const input = this.#reviewInput(entry.capture, entry.preview, groupId);
16170
+ this.#assertCurrent(entry.capture, reservation);
16171
+ const raw = await (this.#options.reviewOwner ?? coordinatorAuthControllerReviewAction)({
16172
+ ...input,
16173
+ confirmOwnerResolutionDigest: review.digest,
16174
+ assertBeforeOwnerResolutionConfirm: () => this.#assertCurrent(entry.capture, reservation)
16175
+ });
16176
+ this.#assertCurrent(entry.capture, reservation);
16177
+ const confirmed = validateRecoveryReview(structuredClone(raw), entry.preview, groupId);
16178
+ requireRecovery(confirmed.state === "ready" && confirmed.digest === review.digest && confirmed.receipt);
16179
+ return confirmed.receipt;
16180
+ }
16181
+ async #applyGroup(entry, groupId, reservation, options) {
16182
+ try {
16183
+ this.#assertCurrent(entry.capture, reservation);
16184
+ const review = entry.reviews.get(groupId);
16185
+ requireRecovery(review && review.state !== "needs_review");
16186
+ let receipt = options.verifiedReceipt ?? review.receipt;
16187
+ if (!options.verifiedReceipt && review.state === "ready") receipt = await this.#confirmNew(entry, groupId, reservation);
16188
+ this.#assertCurrent(entry.capture, reservation);
16189
+ requireRecovery(receipt);
16190
+ const outcome = await this.#verifyAndRetain(entry, groupId, receipt, reservation, { afterRemoteConfirmation: Boolean(options.verifiedReceipt) || review.state === "ready" });
16191
+ if (outcome.status !== "confirmed") return { outcome };
16192
+ return {
16193
+ outcome,
16194
+ verifiedReceipt: structuredClone(receipt)
16195
+ };
16196
+ } catch (error) {
16197
+ return { outcome: {
16198
+ groupId,
16199
+ status: staleDenial(error) ? "failed" : "unknown",
16200
+ message: "Check coordinator status or import original receipts before trying again."
16201
+ } };
16202
+ }
16203
+ }
16204
+ async #verifyAndRetain(entry, groupId, receipt, reservation, options = {}) {
16205
+ this.#assertCurrent(entry.capture, reservation);
16206
+ const response = await (this.#options.readRemoteReceiptStatus ?? readCoordinatorResolvedAccountOwnerReceiptStatus)({
16207
+ dbPath: entry.capture.context.dbPath,
16208
+ keysDir: entry.capture.context.keysDir,
16209
+ coordinatorUrl: entry.capture.context.coordinatorUrl,
16210
+ groupId,
16211
+ ownerIdentityId: entry.preview.existingOwnerId,
16212
+ receipt: structuredClone(receipt),
16213
+ signal: this.#controller.signal
16214
+ });
16215
+ this.#assertCurrent(entry.capture, reservation);
16216
+ if (!this.#validOwnerProof(response, entry, groupId)) return {
16217
+ groupId,
16218
+ status: options.afterRemoteConfirmation ? "unknown" : "failed",
16219
+ message: "The original owner receipt could not be verified with a linked account."
16220
+ };
16221
+ this.#publish(entry, groupId, receipt, reservation);
16222
+ return {
16223
+ groupId,
16224
+ status: "confirmed",
16225
+ message: "Verified existing owner context retained; memory authorship is unchanged."
16226
+ };
16227
+ }
16228
+ #validOwnerProof(response, entry, groupId) {
16229
+ if (response.kind !== "owner_status") return false;
16230
+ const status = response.status, p = entry.preview.profile;
16231
+ return status.version === 1 && status.coordinatorId === p.coordinatorId && status.groupId === groupId && status.deviceId === p.deviceId && status.fingerprint === p.fingerprint && status.state === "owner_confirmed" && status.ownerIdentity === entry.preview.existingOwnerId && status.profileState === "linked" && status.profile !== null && typeof status.profile === "object" && !Array.isArray(status.profile);
16232
+ }
16233
+ #publish(entry, groupId, receipt, reservation) {
16234
+ this.#assertCurrent(entry.capture, reservation);
16235
+ assertNoCompetingOwner(entry.destinations, entry.preview.existingOwnerId);
16236
+ const destination = entry.destinations.get(groupId);
16237
+ requireRecovery(destination);
16238
+ const { profile, pins } = destination;
16239
+ const existing = readAccountOwnerAssociation(profile, { expectedProfilePins: pins });
16240
+ this.#assertCurrent(entry.capture, reservation);
16241
+ if (!existing) retainAccountOwnerAssociation(profile, {
16242
+ ownerIdentityId: entry.preview.existingOwnerId,
16243
+ attestationId: receipt.attestationId,
16244
+ reviewDigest: receipt.reviewEvidenceDigest
16245
+ }, { expectedProfilePins: pins });
16246
+ this.#assertCurrent(entry.capture, reservation);
16247
+ }
16248
+ async importReply(input) {
16249
+ const reservation = this.#reserve();
16250
+ try {
16251
+ const capture = this.#capture();
16252
+ const coordinatorId = await this.#discover(capture);
16253
+ this.#assertCurrent(capture, reservation);
16254
+ assertRecoverySelection(input.selection, recoveryProfile(capture, coordinatorId));
16255
+ const receipts = parseRecoveryReply(input.replyText, input.selection);
16256
+ const entry = this.#newReview({
16257
+ ...input.selection,
16258
+ requestId: randomBytes(16).toString("hex"),
16259
+ purpose: "review"
16260
+ }, capture);
16261
+ assertNoCompetingOwner(entry.destinations, entry.preview.existingOwnerId);
16262
+ const groups = [];
16263
+ for (const [groupId, receipt] of receipts) groups.push(await this.#importGroup(entry, groupId, receipt, reservation));
16264
+ return {
16265
+ preview: entry.preview,
16266
+ groups
16267
+ };
16268
+ } finally {
16269
+ this.#release(reservation);
16270
+ }
16271
+ }
16272
+ async #importGroup(entry, groupId, receipt, reservation) {
16273
+ try {
16274
+ return await this.#verifyAndRetain(entry, groupId, receipt, reservation);
16275
+ } catch {
16276
+ return {
16277
+ groupId,
16278
+ status: "unknown",
16279
+ message: "Context or proof outcome changed; check status before importing again."
16280
+ };
16281
+ }
16282
+ }
16283
+ async close() {
16284
+ this.#closed = true;
16285
+ this.#controller.abort();
16286
+ this.#handles.clear();
16287
+ for (const reservation of this.#reservations) this.#release(reservation);
16288
+ }
16289
+ };
16290
+ function createAccountOwnerRecoveryService(options) {
16291
+ return new AccountOwnerRecoveryService(options);
16292
+ }
16293
+ //#endregion
13710
16294
  //#region src/index.ts
13711
16295
  /**
13712
16296
  * @codemem/server — HTTP server (viewer, sync, API).
@@ -13719,16 +16303,28 @@ function createAccountContextReader(options) {
13719
16303
  */
13720
16304
  /** Shared store instance — SQLite WAL mode handles concurrent reads safely. */
13721
16305
  var sharedStore = null;
16306
+ var sharedStoreClosePromise = null;
13722
16307
  /** Get (or create) the shared store instance. Exported so the sweeper can share it. */
13723
16308
  function getStore() {
13724
16309
  if (!sharedStore) sharedStore = new MemoryStore(resolveDbPath());
13725
16310
  return sharedStore;
13726
16311
  }
13727
- /** Close the shared store (called on shutdown). */
16312
+ /** Close a synchronous-only shared store. Async pack owners use closeStoreAsync(). */
13728
16313
  function closeStore() {
13729
16314
  sharedStore?.close();
13730
16315
  sharedStore = null;
13731
16316
  }
16317
+ /** Drain semantic work before closing SQLite and releasing the shared store. */
16318
+ function closeStoreAsync() {
16319
+ if (sharedStoreClosePromise) return sharedStoreClosePromise;
16320
+ if (!sharedStore) return Promise.resolve();
16321
+ const store = sharedStore;
16322
+ sharedStoreClosePromise = store.closeAsync().then(() => {
16323
+ if (sharedStore === store) sharedStore = null;
16324
+ sharedStoreClosePromise = null;
16325
+ });
16326
+ return sharedStoreClosePromise;
16327
+ }
13732
16328
  function registerStaticRoutes(app) {
13733
16329
  const staticRoot = process.env.CODEMEM_VIEWER_STATIC_DIR ?? join(import.meta.dirname ?? ".", "../static");
13734
16330
  app.use("/assets/*", async (c, next) => {
@@ -13761,6 +16357,7 @@ function registerAccountRoutes(app, options) {
13761
16357
  const account = createAccountGuard(options);
13762
16358
  app.use("*", account.middleware);
13763
16359
  app.route("/", account.routes);
16360
+ if (options.ownerRecovery) app.route("/", accountOwnerRecoveryRoutes(options.ownerRecovery));
13764
16361
  if (options.readContext) app.route("/", accountStatusRoutes({
13765
16362
  ...options,
13766
16363
  readContext: options.readContext
@@ -13784,6 +16381,7 @@ function createApp(opts) {
13784
16381
  const viewerTargetGuard = viewerTargetQueryGuard(storeFactory);
13785
16382
  app.use("/api/memories/*", viewerTargetGuard);
13786
16383
  app.use("/api/memory", viewerTargetGuard);
16384
+ app.use("/api/pi/sessions/search", viewerTargetGuard);
13787
16385
  app.route("/", healthRoutes(storeFactory));
13788
16386
  app.route("/", diagnosticsRoutes(storeFactory));
13789
16387
  app.route("/", statsRoutes(storeFactory));
@@ -13845,6 +16443,6 @@ function createSyncApp(opts) {
13845
16443
  return app;
13846
16444
  }
13847
16445
  //#endregion
13848
- export { FileRawEventInbox, VERSION, advancePendingProjectShares, advancePendingProjectSharesOperation, advanceProjectShareOperation, closeStore, createAccountContextReader, createAccountLinkRegistry, createApp, createRecipientPolicyReconcilerEffects, createSyncApp, createViewerRawEventInbox, getStore, listRecipientPolicyReconciliationStatus, recipientPolicyCapabilityFromStatus, reconcileConfiguredCoordinatorEnrollment, reconcileRecipientPolicyProjects, reconcileRecipientPolicyProjectsOperation, resolveRawEventInboxDirectory };
16446
+ export { FileRawEventInbox, VERSION, advancePendingProjectShares, advancePendingProjectSharesOperation, advanceProjectShareOperation, closeStore, closeStoreAsync, createAccountContextReader, createAccountLinkRegistry, createAccountOwnerRecoveryService, createApp, createRecipientPolicyReconcilerEffects, createSyncApp, createViewerRawEventInbox, getStore, listRecipientPolicyReconciliationStatus, recipientPolicyCapabilityFromStatus, reconcileConfiguredCoordinatorEnrollment, reconcileRecipientPolicyProjects, reconcileRecipientPolicyProjectsOperation, resolveRawEventInboxDirectory };
13849
16447
 
13850
16448
  //# sourceMappingURL=index.js.map