@byok-sdk/core 0.26.0 → 0.27.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,3 +16,5 @@ hosted production composition must inject durable atomic storage. The assertion
16
16
  authorizes one exchange only and is not a connector session or refresh token.
17
17
 
18
18
  MIT licensed. Node.js 24.15.0 or newer.
19
+
20
+ Runtime dependencies and size budgets: [entry dependency contract](../../README.md#entry-dependencies).
package/dist/blob.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { CollectExpiredInput, CollectExpiredResult } from './retention';
1
2
  import type { TenantId } from './tenant';
2
3
  /** `sha256:<64 lowercase hex>`. The only content-address form core accepts. */
3
4
  export declare const CONTENT_HASH_PATTERN: RegExp;
@@ -141,6 +142,7 @@ export interface ObjectListQuery {
141
142
  * `deletePendingBefore` is not a canonical ISO-8601 UTC instant).
142
143
  */
143
144
  export interface ObjectStore {
145
+ collectExpired(tenant: TenantId, input: ObjectCollectExpiredInput): Promise<CollectExpiredResult>;
144
146
  /** Creates or returns the `pending` row for `hash`. Idempotent per (tenant, hash). */
145
147
  putManifest(tenant: TenantId, input: ObjectManifestInput): Promise<ObjectManifestEntry>;
146
148
  /** `pending` → `committed` after verifying observed size/type. */
@@ -155,3 +157,6 @@ export interface ObjectStore {
155
157
  /** Tombstone step 3: the object store delete succeeded. */
156
158
  markDeleted(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry>;
157
159
  }
160
+ export interface ObjectCollectExpiredInput extends CollectExpiredInput {
161
+ readonly orphanBefore: string;
162
+ }
@@ -1,3 +1,4 @@
1
+ import type { CollectExpiredInput, CollectExpiredResult } from './retention';
1
2
  /**
2
3
  * Device assertion envelope, canonical signing bytes, and verifier
3
4
  * (plan `device-assertion-broker`, P3 ①-⑤).
@@ -289,6 +290,7 @@ export interface DeviceAssertionReplayConsumeInput {
289
290
  * never be translated into authenticated success.
290
291
  */
291
292
  export interface DeviceAssertionReplayAuthority {
293
+ collectExpired(tenant: TenantId, input: CollectExpiredInput): Promise<CollectExpiredResult>;
292
294
  consume(input: DeviceAssertionReplayConsumeInput): Promise<boolean>;
293
295
  }
294
296
  export interface AuthenticateDeviceAssertionDeps {
package/dist/errors.d.ts CHANGED
@@ -29,6 +29,8 @@
29
29
  * - the five `storage_*` codes (§12.7.7, see `quota.ts`)
30
30
  */
31
31
  export declare const CORE_ERROR_CODES: {
32
+ readonly retention_input_invalid: 'retention_input_invalid';
33
+ readonly retention_collect_failed: 'retention_collect_failed';
32
34
  readonly tenant_id_invalid: 'tenant_id_invalid';
33
35
  readonly content_hash_invalid: 'content_hash_invalid';
34
36
  readonly timestamp_not_canonical: 'timestamp_not_canonical';
@@ -1,3 +1,6 @@
1
+ import { InMemoryStorageLedger } from './storage-ledger';
2
+ import { type CollectExpiredResult } from '../retention';
3
+ import type { ObjectCollectExpiredInput } from '../blob';
1
4
  /**
2
5
  * In-memory {@link ObjectStore} reference (§12.7.4, §12.7.8).
3
6
  *
@@ -12,7 +15,11 @@ import type { Clock } from '../stores';
12
15
  import { type TenantId } from '../tenant';
13
16
  export declare class InMemoryObjectStore implements ObjectStore {
14
17
  #private;
15
- constructor(clock: Clock);
18
+ private readonly maintenance;
19
+ constructor(clock: Clock, maintenance: {
20
+ readonly ledger: InMemoryStorageLedger;
21
+ readonly bytes: InMemoryObjectBytes;
22
+ });
16
23
  putManifest(tenant: TenantId, input: ObjectManifestInput): Promise<ObjectManifestEntry>;
17
24
  commit(tenant: TenantId, input: ObjectCommitInput): Promise<ObjectManifestEntry>;
18
25
  get(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry | undefined>;
@@ -21,4 +28,8 @@ export declare class InMemoryObjectStore implements ObjectStore {
21
28
  removeReference(tenant: TenantId, input: ObjectReferenceInput): Promise<ObjectManifestEntry>;
22
29
  markDeletePending(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry>;
23
30
  markDeleted(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry>;
31
+ collectExpired(tenant: TenantId, input: ObjectCollectExpiredInput): Promise<CollectExpiredResult>;
32
+ }
33
+ export interface InMemoryObjectBytes {
34
+ deleteObject(tenant: TenantId, hash: ContentHash): void;
24
35
  }
@@ -1,8 +1,9 @@
1
+ import { type CollectExpiredInput, type CollectExpiredResult } from '../retention';
2
+ import type { TenantId } from '../tenant';
1
3
  import type { DeviceAssertionReplayConsumeInput, DeviceAssertionReplayAuthority } from '../device-assertion';
2
4
  /** Process-local reference authority. Production runtimes need durable atomic storage. */
3
5
  export declare class InMemoryDeviceAssertionReplayAuthority implements DeviceAssertionReplayAuthority {
4
6
  #private;
5
7
  consume(input: DeviceAssertionReplayConsumeInput): Promise<boolean>;
6
- /** Delete at most `limit` keys whose assertion lifetime ended at or before `before`. */
7
- deleteExpired(before: Date, limit: number): Promise<number>;
8
+ collectExpired(tenant: TenantId, input: CollectExpiredInput): Promise<CollectExpiredResult>;
8
9
  }
@@ -1,3 +1,4 @@
1
+ import type { InMemoryObjectBytes } from './blob';
1
2
  import type { Clock, CoreStores, MutableClock } from '../stores';
2
3
  export { createMutableClock, IN_MEMORY_CLOCK_EPOCH } from './clock';
3
4
  export { InMemoryMailboxStore } from './mailbox';
@@ -9,6 +10,7 @@ export { InMemoryQuotaStore } from './quota';
9
10
  export { InMemorySkillPackStore } from './skill-pack';
10
11
  export { InMemoryDeviceAssertionReplayAuthority } from './device-assertion-replay';
11
12
  export interface InMemoryCoreOptions {
13
+ readonly objectBytes: InMemoryObjectBytes;
12
14
  /** Defaults to a fresh {@link createMutableClock}, so TTL behavior is deterministic. */
13
15
  readonly clock?: Clock;
14
16
  }
@@ -17,9 +19,11 @@ export interface InMemoryCoreComposition {
17
19
  /** The clock the stores read. Mutable only when the caller did not inject its own. */
18
20
  readonly clock: Clock;
19
21
  }
20
- export declare function createInMemoryCoreStores(options?: InMemoryCoreOptions): InMemoryCoreComposition;
22
+ export declare function createInMemoryCoreStores(options: InMemoryCoreOptions): InMemoryCoreComposition;
21
23
  /** Convenience for tests that need to move time: returns the composition and its mutable clock. */
22
- export declare function createInMemoryCoreCompositionWithClock(): {
24
+ export declare function createInMemoryCoreCompositionWithClock(objectBytes: InMemoryObjectBytes): {
23
25
  readonly stores: CoreStores;
24
26
  readonly clock: MutableClock;
25
27
  };
28
+ export { InMemoryStorageLedger } from './storage-ledger';
29
+ export type { InMemoryObjectBytes } from './blob';
@@ -1,13 +1,17 @@
1
- import type { MailboxAdvanceCursorInput, MailboxAppendInput, MailboxCursorState, MailboxMessage, MailboxPage, MailboxReadQuery, MailboxRecordDeliveryInput, MailboxRetentionInput, MailboxRetentionResult, MailboxStore } from '../mailbox';
1
+ import { type CollectExpiredResult } from '../retention';
2
+ import type { MailboxAdvanceCursorInput, MailboxAppendInput, MailboxCursorState, MailboxMessage, MailboxPage, MailboxReadQuery, MailboxRecordDeliveryInput, MailboxCollectExpiredInput, MailboxStore, MailboxUsage } from '../mailbox';
3
+ import type { QuotaStore } from '../quota';
2
4
  import type { Clock } from '../stores';
3
5
  import { type TenantId } from '../tenant';
4
6
  export declare class InMemoryMailboxStore implements MailboxStore {
5
7
  #private;
6
- constructor(clock: Clock);
8
+ /** The mailbox reads its limit from quota; quota never reads the mailbox. */
9
+ constructor(clock: Clock, quota: Pick<QuotaStore, 'readEntitlement'>);
7
10
  append(tenant: TenantId, input: MailboxAppendInput): Promise<MailboxMessage>;
11
+ readUsage(tenant: TenantId): Promise<MailboxUsage>;
8
12
  readAfter(tenant: TenantId, query: MailboxReadQuery): Promise<MailboxPage>;
9
13
  advanceCursor(tenant: TenantId, input: MailboxAdvanceCursorInput): Promise<MailboxCursorState>;
10
14
  recordDelivery(tenant: TenantId, input: MailboxRecordDeliveryInput): Promise<MailboxCursorState>;
11
15
  readCursor(tenant: TenantId, deviceId: string): Promise<MailboxCursorState>;
12
- collectRetired(tenant: TenantId, input: MailboxRetentionInput): Promise<MailboxRetentionResult>;
16
+ collectExpired(tenant: TenantId, input: MailboxCollectExpiredInput): Promise<CollectExpiredResult>;
13
17
  }
@@ -1,3 +1,4 @@
1
+ import { type CollectExpiredInput, type CollectExpiredResult } from '../retention';
1
2
  import { type PresenceHint, type PresenceHintInput, type PresenceStore } from '../presence';
2
3
  import type { Clock } from '../stores';
3
4
  import { type TenantId } from '../tenant';
@@ -7,4 +8,5 @@ export declare class InMemoryPresenceStore implements PresenceStore {
7
8
  publish(tenant: TenantId, input: PresenceHintInput): Promise<PresenceHint>;
8
9
  read(tenant: TenantId, deviceId: string): Promise<PresenceHint | undefined>;
9
10
  list(tenant: TenantId): Promise<readonly PresenceHint[]>;
11
+ collectExpired(tenant: TenantId, input: CollectExpiredInput): Promise<CollectExpiredResult>;
10
12
  }
@@ -1,10 +1,14 @@
1
+ import { InMemoryStorageLedger } from './storage-ledger';
2
+ import { type CollectExpiredResult } from '../retention';
3
+ import type { QuotaCollectExpiredInput } from '../quota';
1
4
  import type { ObjectStore } from '../blob';
2
- import type { MailboxUsageDeltaInput, StorageFinalizeInput, StorageFinalizeResult, StorageReservation, StorageReservationInput, StorageStatus, QuotaStore, TenantStorageEntitlement, TenantStorageEntitlementInput, TenantStorageUsage } from '../quota';
5
+ import type { StorageFinalizeInput, StorageFinalizeResult, StorageReservation, StorageReservationInput, StorageStatus, QuotaStore, TenantStorageEntitlement, TenantStorageEntitlementInput, TenantStorageUsage } from '../quota';
3
6
  import type { Clock } from '../stores';
4
7
  import { type TenantId } from '../tenant';
5
8
  export declare class InMemoryQuotaStore implements QuotaStore {
6
9
  #private;
7
- constructor(clock: Clock, objects: ObjectStore);
10
+ private readonly ledger;
11
+ constructor(clock: Clock, objects: ObjectStore, ledger: InMemoryStorageLedger);
8
12
  readEntitlement(tenant: TenantId): Promise<TenantStorageEntitlement | undefined>;
9
13
  writeEntitlement(tenant: TenantId, input: TenantStorageEntitlementInput): Promise<TenantStorageEntitlement>;
10
14
  readUsage(tenant: TenantId): Promise<TenantStorageUsage>;
@@ -13,6 +17,5 @@ export declare class InMemoryQuotaStore implements QuotaStore {
13
17
  reserve(tenant: TenantId, input: StorageReservationInput): Promise<StorageReservation>;
14
18
  finalizeReservation(tenant: TenantId, input: StorageFinalizeInput): Promise<StorageFinalizeResult>;
15
19
  abortReservation(tenant: TenantId, reservationId: string): Promise<StorageReservation>;
16
- expireReservations(tenant: TenantId): Promise<readonly StorageReservation[]>;
17
- applyMailboxDelta(tenant: TenantId, input: MailboxUsageDeltaInput): Promise<TenantStorageUsage>;
20
+ collectExpired(tenant: TenantId, input: QuotaCollectExpiredInput): Promise<CollectExpiredResult>;
18
21
  }
@@ -0,0 +1,29 @@
1
+ import type { Clock } from '../stores';
2
+ import type { ContentHash } from '../blob';
3
+ import type { StorageReservation, TenantStorageUsage } from '../quota';
4
+ import type { TenantId } from '../tenant';
5
+ export interface ReservationRecord {
6
+ readonly reservation: StorageReservation;
7
+ readonly deduplicated: boolean;
8
+ }
9
+ /** Shared authority for reservations, object accounting and quota reads. */
10
+ export declare class InMemoryStorageLedger {
11
+ #private;
12
+ private readonly clock;
13
+ constructor(clock: Clock);
14
+ readReservation(key: string): ReservationRecord | undefined;
15
+ writeReservation(key: string, record: ReservationRecord): void;
16
+ deleteReservation(key: string): void;
17
+ reservations(): IterableIterator<[string, ReservationRecord]>;
18
+ readUsage(tenant: TenantId): TenantStorageUsage;
19
+ writeUsage(tenant: TenantId, usage: TenantStorageUsage): void;
20
+ isCounted(tenant: TenantId, hash: string): boolean;
21
+ recordCommitted(tenant: TenantId, reservation: StorageReservation): void;
22
+ hasReservedObject(tenant: TenantId, hash: ContentHash): boolean;
23
+ reservedObjectHashes(tenant: TenantId): readonly string[];
24
+ prepareCollectedObjectRelease(tenant: TenantId, hash: ContentHash, byteSize: bigint, now: string): {
25
+ readonly releasedBytes: bigint;
26
+ readonly commit: () => void;
27
+ };
28
+ releaseCollectedObject(tenant: TenantId, hash: ContentHash, byteSize: bigint, now: string): bigint;
29
+ }
package/dist/index.d.ts CHANGED
@@ -20,7 +20,7 @@ export { ByokCoreError, CoreConflictError, CORE_ERROR_CODES, isCoreError, isCore
20
20
  export type { CoreErrorCode } from './errors';
21
21
  export { CANONICAL_TIMESTAMP_PATTERN, assertCanonicalTimestamp, isCanonicalTimestamp, } from './time';
22
22
  export { MAILBOX_MESSAGE_STATES } from './mailbox';
23
- export type { MailboxAdvanceCursorInput, MailboxAppendInput, MailboxBody, MailboxCursorState, MailboxMessage, MailboxMessageState, MailboxPage, MailboxReadQuery, MailboxRecordDeliveryInput, MailboxRetentionInput, MailboxRetentionResult, MailboxStore, } from './mailbox';
23
+ export type { MailboxAdmission, MailboxAdvanceCursorInput, MailboxAppendInput, MailboxBody, MailboxCursorState, MailboxMessage, MailboxMessageState, MailboxPage, MailboxReadQuery, MailboxRecordDeliveryInput, MailboxCollectExpiredInput, MailboxStore, MailboxUsage, } from './mailbox';
24
24
  export { BOARD_STATUSES, BOARD_TRANSITIONS, isLegalBoardTransition } from './board';
25
25
  export type { BoardAssignee, BoardClaimInput, BoardItem, BoardItemInput, BoardListQuery, BoardPage, BoardStatus, BoardStatusUpdateInput, BoardStore, BoardUnclaimInput, } from './board';
26
26
  export { TRUTH_RECORD_KINDS } from './truth';
@@ -30,7 +30,7 @@ export type { PresenceHint, PresenceHintInput, PresenceLevel, PresenceRuntimeFac
30
30
  export { CONTENT_HASH_PATTERN, OBJECT_KEY_PREFIX_PATTERN, OBJECT_STATES, OBJECT_STATE_TRANSITIONS, contentHash, isContentHash, isLegalObjectTransition, objectKeyPrefix, tenantObjectKey, } from './blob';
31
31
  export type { ContentHash, ObjectCommitInput, ObjectKeyPrefix, ObjectListQuery, ObjectManifestEntry, ObjectManifestInput, ObjectReference, ObjectReferenceInput, ObjectState, ObjectStore, } from './blob';
32
32
  export { STORAGE_ERROR_CODES, STORAGE_ERROR_HTTP_STATUS, STORAGE_RESERVATION_STATES, STORAGE_WRITE_KINDS, STORAGE_WRITE_POSTURES, } from './quota';
33
- export type { MailboxUsageDeltaInput, QuotaStore, StorageErrorCode, StorageFinalizeInput, StorageFinalizeResult, StorageReservation, StorageReservationInput, StorageReservationState, StorageStatus, StorageWriteKind, StorageWritePosture, TenantStorageEntitlement, TenantStorageEntitlementInput, TenantStorageUsage, } from './quota';
33
+ export type { QuotaStore, StorageErrorCode, StorageFinalizeInput, StorageFinalizeResult, StorageReservation, StorageReservationInput, StorageReservationState, StorageStatus, StorageWriteKind, StorageWritePosture, TenantStorageEntitlement, TenantStorageEntitlementInput, TenantStorageUsage, } from './quota';
34
34
  export { CAPABILITY_DECLARATION_SCHEMA_ID, CAPABILITY_NAME_PATTERN, CapabilityDeclarationSchema, assertCapability, hasCapability, parseCapabilityDeclaration, } from './capabilities';
35
35
  export type { CapabilityDeclaration } from './capabilities';
36
36
  export { SKILL_FRONTMATTER_FIELDS, SKILL_PACK_DESCRIPTION_MAX_LENGTH, SKILL_PACK_ENTRY_PATH, SKILL_PACK_FILE_MAX_BYTES, SKILL_PACK_FILE_PATH_MAX_LENGTH, SKILL_PACK_FILE_PATH_PATTERN, SKILL_PACK_FORBIDDEN_FIELDS, SKILL_PACK_MANIFEST_SCHEMA_ID, SKILL_PACK_MAX_BYTES, SKILL_PACK_MAX_FILES, SKILL_PACK_NAME_MAX_LENGTH, SKILL_PACK_NAME_PATTERN, SKILL_PACK_REJECTIONS, SKILL_PACK_VERSION_PATTERN, SkillPackFileSchema, SkillPackManifestSchema, checkSkillPackEntry, checkSkillPackFileContent, checkSkillPackManifest, isSkillPackPathSafe, parseSkillFrontmatter, parseSkillPackManifest, skillPackContentHashInput, } from './skill-pack';
@@ -50,3 +50,9 @@ export type { AgentMemoryIntentDigestInput } from './agent-memory-intent';
50
50
  export { NONCE_SIGNING_DOMAIN, nonceSigningBytes } from './pairing';
51
51
  export { IN_MEMORY_CLOCK_EPOCH, InMemoryBoardStore, InMemoryMailboxStore, InMemoryDeviceAssertionReplayAuthority, InMemoryObjectStore, InMemoryPresenceStore, InMemoryQuotaStore, InMemorySkillPackStore, InMemoryTruthStore, createInMemoryCoreStores, createInMemoryCoreCompositionWithClock, createMutableClock, } from './in-memory/index';
52
52
  export type { InMemoryCoreComposition, InMemoryCoreOptions } from './in-memory/index';
53
+ export { assertCollectExpiredInput, CollectExpiredFailure } from './retention';
54
+ export type { CollectExpiredInput, CollectExpiredCounts, CollectExpiredResult } from './retention';
55
+ export type { QuotaCollectExpiredInput } from './quota';
56
+ export type { ObjectCollectExpiredInput } from './blob';
57
+ export { InMemoryStorageLedger } from './in-memory/storage-ledger';
58
+ export type { InMemoryObjectBytes } from './in-memory/blob';