@effect-agent/storage-cloudflare 0.1.0-beta.77 → 0.1.0-beta.79

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.
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
2
  import { Clock, Context, Effect, Schema } from "effect";
3
- import { MemoryConflict, MemoryDocument, MemoryMutationFailure, MemoryOperationConflict, MemoryStorageError, MemoryWithdrawn, MemoryWrite, MemoryWriter } from "@effect-agent/core/MemoryStore";
3
+ import { MemoryConflict, MemoryDocument, MemoryKey, MemoryMutationFailure, MemoryOperationConflict, MemoryReader, MemoryStorageError, MemoryWithdrawn, MemoryWrite, MemoryWriter } from "@effect-agent/core/MemoryStore";
4
4
  import { Principal } from "@effect-agent/thread/SubmissionLedger";
5
5
  import * as MemoryNamespace from "@effect-agent/core/MemoryNamespace";
6
6
  import { MemoryLookup, MemoryRecallError, MemoryRecallLimits } from "@effect-agent/core/MemoryReference";
@@ -68,6 +68,10 @@ const ChangeRequest = Schema.TaggedStruct("Change", {
68
68
  ...RequestFields,
69
69
  write: MemoryWrite.Wire
70
70
  });
71
+ const GetRequest = Schema.TaggedStruct("Get", {
72
+ ...RequestFields,
73
+ key: MemoryKey.Wire
74
+ });
71
75
  const SemanticRequest = Schema.TaggedStruct("RevalidateSemantic", {
72
76
  ...RequestFields,
73
77
  found: MemoryIndexSearch.Wire,
@@ -77,7 +81,8 @@ const SemanticRequest = Schema.TaggedStruct("RevalidateSemantic", {
77
81
  const MemoryOwnerRequest = Schema.Union([
78
82
  RevalidateRequest,
79
83
  ChangeRequest,
80
- SemanticRequest
84
+ SemanticRequest,
85
+ GetRequest
81
86
  ]);
82
87
  const MemoryOwnerFailure = Schema.Union([
83
88
  MemoryRpcError,
@@ -90,22 +95,36 @@ const MemoryOwnerFailure = Schema.Union([
90
95
  MemoryIndexError,
91
96
  SemanticMemoryError
92
97
  ]);
98
+ const LookupResponse = Schema.TaggedStruct("Lookup", {
99
+ access: MemoryAccess.Wire,
100
+ lookup: MemoryLookup
101
+ });
102
+ const ChangedResponse = Schema.TaggedStruct("Changed", {
103
+ access: MemoryAccess.Wire,
104
+ document: MemoryDocument.Wire
105
+ });
106
+ const SemanticResponse = Schema.TaggedStruct("Semantic", {
107
+ access: MemoryAccess.Wire,
108
+ result: SemanticCandidateResult
109
+ });
110
+ const DocumentResponse = Schema.TaggedStruct("Document", {
111
+ access: MemoryAccess.Wire,
112
+ key: MemoryKey.Wire,
113
+ document: Schema.NullOr(MemoryDocument.Wire)
114
+ });
115
+ const FailedResponse = Schema.TaggedStruct("Failed", { failure: MemoryOwnerFailure });
93
116
  const MemoryOwnerResponse = Schema.Union([
94
- Schema.TaggedStruct("Lookup", {
95
- access: MemoryAccess.Wire,
96
- lookup: MemoryLookup
97
- }),
98
- Schema.TaggedStruct("Changed", {
99
- access: MemoryAccess.Wire,
100
- document: MemoryDocument.Wire
101
- }),
102
- Schema.TaggedStruct("Semantic", {
103
- access: MemoryAccess.Wire,
104
- result: SemanticCandidateResult
105
- }),
106
- Schema.TaggedStruct("Failed", { failure: MemoryOwnerFailure })
117
+ LookupResponse,
118
+ ChangedResponse,
119
+ SemanticResponse,
120
+ DocumentResponse,
121
+ FailedResponse
107
122
  ]);
108
- /** Fail-closed application policy. Authorize the namespace, principal, scope, and full command. */
123
+ /**
124
+ * Fail-closed application policy. Authorize the namespace, principal, scope, and full command.
125
+ * Get requires exact-key authority, including application source/provenance checks where needed.
126
+ * Possession of a key or scope is not authorization, including for absent or withdrawn documents.
127
+ */
109
128
  var MemoryOwnerAuthorizer = class extends Context.Service()("@effect-agent/storage-cloudflare/MemoryOwnerAuthorizer") {};
110
129
  /** Canonical namespace derived from this object's idFromName identity, never its request. */
111
130
  var MemoryOwnerIdentity = class extends Context.Service()("@effect-agent/storage-cloudflare/MemoryOwnerIdentity") {};
@@ -120,17 +139,35 @@ const encodeMemoryWire = Effect.fn("encodeMemoryWire")(function* (schema, value,
120
139
  if (encoded.length > maxBytes || memoryWireBytes(encoded) > maxBytes) return yield* MemoryRpcError.make({ reason: "budget" });
121
140
  return encoded;
122
141
  });
123
- /** One local read per distinct candidate source, with no per-document network calls. */
142
+ /** One local read for Get, or per distinct candidate source. No discovery or background work. */
124
143
  const handleMemoryOwnerRequest = Effect.fn("MemoryOwner.handleRequest")(function* (raw, limits = defaultMemoryRpcLimits) {
125
144
  const result = yield* Effect.gen(function* () {
126
145
  limits = yield* Schema.decodeUnknownEffect(MemoryRpcLimits)(limits).pipe(Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })));
127
146
  const request = yield* decodeMemoryWire(MemoryOwnerRequest, raw, limits.maxRequestBytes);
128
147
  const { namespace } = yield* MemoryOwnerIdentity;
129
- if (!MemoryNamespace.equals(namespace, request.access.namespace) || request._tag === "Change" && !MemoryNamespace.equals(namespace, request.write.key.namespace) || request._tag === "RevalidateSemantic" && request.found.candidates.some((candidate) => !MemoryNamespace.equals(namespace, candidate.key.namespace))) return yield* MemoryRpcError.make({ reason: "denied" });
148
+ if (!MemoryNamespace.equals(namespace, request.access.namespace) || request._tag === "Get" && !MemoryNamespace.equals(namespace, request.key.namespace) || request._tag === "Change" && !MemoryNamespace.equals(namespace, request.write.key.namespace) || request._tag === "RevalidateSemantic" && request.found.candidates.some((candidate) => !MemoryNamespace.equals(namespace, candidate.key.namespace))) return yield* MemoryRpcError.make({ reason: "denied" });
130
149
  const remaining = Math.min(limits.timeoutMillis, request.deadlineMillis - (yield* Clock.currentTimeMillis));
131
150
  if (remaining <= 0) return yield* MemoryRpcError.make({ reason: "timeout" });
132
151
  return yield* Effect.gen(function* () {
133
152
  yield* (yield* MemoryOwnerAuthorizer).authorize(request);
153
+ if (request._tag === "Get") {
154
+ const current = yield* (yield* MemoryReader).get(request.key);
155
+ const document = current === null ? null : yield* MemoryDocument.restore(namespace, current);
156
+ if (document !== null) {
157
+ if (document.key.id !== request.key.id || document.source.id !== request.key.id) return yield* MemoryStorageError.make({
158
+ operation: "validate memory read identity",
159
+ reason: "corrupt"
160
+ });
161
+ if (document._tag === "ActiveMemoryDocument" && !document.scopes.includes(request.access.scope)) return yield* MemoryRpcError.make({ reason: "denied" });
162
+ yield* encodeMemoryWire(MemoryDocument.Wire, document, limits.maxSourceBytes);
163
+ }
164
+ return {
165
+ _tag: "Document",
166
+ access: request.access,
167
+ key: request.key,
168
+ document
169
+ };
170
+ }
134
171
  if (request._tag === "Change") {
135
172
  const writer = yield* MemoryWriter;
136
173
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"MemoryProtocol.mjs","names":[],"sources":["../src/MemoryProtocol.ts"],"sourcesContent":["import * as MemoryNamespace from \"@effect-agent/core/MemoryNamespace\";\nimport {\n MemoryLookup,\n MemoryRecallError,\n MemoryRecallLimits,\n} from \"@effect-agent/core/MemoryReference\";\nimport { MemoryAccess, revalidateMemoryLookup } from \"@effect-agent/core/MemoryRevalidation\";\nimport { type MemoryReader } from \"@effect-agent/core/MemoryStore\";\nimport {\n MemoryConflict,\n MemoryDocument,\n MemoryMutationFailure,\n MemoryOperationConflict,\n MemoryStorageError,\n MemoryWithdrawn,\n MemoryWrite,\n MemoryWriter,\n} from \"@effect-agent/core/MemoryStore\";\nimport {\n MemoryIndexSearch,\n MemoryIndexError,\n SemanticMemoryProfile,\n} from \"@effect-agent/core/SemanticMemoryIndex\";\nimport {\n SemanticMemoryError,\n SemanticCandidateLimits,\n SemanticCandidateResult,\n revalidateSemanticMemoryCandidates,\n} from \"@effect-agent/core/SemanticMemoryRevalidation\";\nimport { Principal } from \"@effect-agent/thread/SubmissionLedger\";\nimport { Clock, Context, Effect, Schema } from \"effect\";\n\nexport class MemoryRpcError extends Schema.TaggedError<MemoryRpcError>()(\"MemoryRpcError\", {\n reason: Schema.Literals([\"denied\", \"protocol\", \"budget\", \"timeout\", \"unavailable\"]),\n}) {}\n\nexport class MemoryRpcLimits extends Schema.Class<MemoryRpcLimits>(\n \"@effect-agent/storage-cloudflare/MemoryRpcLimits\",\n)({\n maxRequestBytes: Schema.Int.check(Schema.isBetween({ minimum: 256, maximum: 4_194_304 })),\n maxResponseBytes: Schema.Int.check(Schema.isBetween({ minimum: 256, maximum: 16_777_216 })),\n maxSourceBytes: Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 67_108_864 })),\n maxSources: MemoryRecallLimits.fields.maxSources,\n timeoutMillis: MemoryRecallLimits.fields.timeoutMillis,\n}) {}\n\nexport const defaultMemoryRpcLimits = MemoryRpcLimits.make({\n maxRequestBytes: 1_048_576,\n maxResponseBytes: 4_194_304,\n maxSourceBytes: 16_777_216,\n maxSources: 16,\n timeoutMillis: 10_000,\n});\n\nconst RequestFields = {\n version: Schema.Literal(1),\n access: MemoryAccess.Wire,\n /** Host-authenticated identity, never copied from model input. The owner still authorizes it. */\n principal: Principal,\n deadlineMillis: Schema.Finite.check(Schema.isGreaterThanOrEqualTo(0)),\n};\n\nconst RevalidateRequest = Schema.TaggedStruct(\"Revalidate\", {\n ...RequestFields,\n lookup: MemoryLookup,\n limits: MemoryRecallLimits,\n});\n\nconst ChangeRequest = Schema.TaggedStruct(\"Change\", { ...RequestFields, write: MemoryWrite.Wire });\n\nconst SemanticRequest: Schema.TaggedStruct<\n \"RevalidateSemantic\",\n typeof RequestFields & {\n readonly found: typeof MemoryIndexSearch.Wire;\n readonly profile: typeof SemanticMemoryProfile;\n readonly limits: typeof SemanticCandidateLimits;\n }\n> = Schema.TaggedStruct(\"RevalidateSemantic\", {\n ...RequestFields,\n found: MemoryIndexSearch.Wire,\n profile: SemanticMemoryProfile,\n limits: SemanticCandidateLimits,\n});\n\nexport const MemoryOwnerRequest: Schema.Union<\n [typeof RevalidateRequest, typeof ChangeRequest, typeof SemanticRequest]\n> = Schema.Union([RevalidateRequest, ChangeRequest, SemanticRequest]);\n\nexport type MemoryOwnerRequest = typeof MemoryOwnerRequest.Type;\n\nexport const MemoryOwnerFailure = Schema.Union([\n MemoryRpcError,\n MemoryStorageError,\n MemoryRecallError,\n MemoryConflict,\n MemoryWithdrawn,\n MemoryOperationConflict,\n MemoryMutationFailure,\n MemoryIndexError,\n SemanticMemoryError,\n]);\n\nexport type MemoryOwnerFailure = typeof MemoryOwnerFailure.Type;\n\nexport const MemoryOwnerResponse = Schema.Union([\n Schema.TaggedStruct(\"Lookup\", { access: MemoryAccess.Wire, lookup: MemoryLookup }),\n Schema.TaggedStruct(\"Changed\", { access: MemoryAccess.Wire, document: MemoryDocument.Wire }),\n Schema.TaggedStruct(\"Semantic\", { access: MemoryAccess.Wire, result: SemanticCandidateResult }),\n Schema.TaggedStruct(\"Failed\", { failure: MemoryOwnerFailure }),\n]);\n\nexport type MemoryOwnerResponse = typeof MemoryOwnerResponse.Type;\n\n/** Fail-closed application policy. Authorize the namespace, principal, scope, and full command. */\nexport class MemoryOwnerAuthorizer extends Context.Service<\n MemoryOwnerAuthorizer,\n {\n readonly authorize: (request: MemoryOwnerRequest) => Effect.Effect<void, MemoryRpcError>;\n }\n>()(\"@effect-agent/storage-cloudflare/MemoryOwnerAuthorizer\") {}\n\n/** Canonical namespace derived from this object's idFromName identity, never its request. */\nexport class MemoryOwnerIdentity extends Context.Service<\n MemoryOwnerIdentity,\n {\n readonly namespace: MemoryNamespace.Any;\n }\n>()(\"@effect-agent/storage-cloudflare/MemoryOwnerIdentity\") {}\n\nexport const memoryWireBytes = (text: string): number => new TextEncoder().encode(text).byteLength;\n\nexport const decodeMemoryWire = Effect.fn(\"decodeMemoryWire\")(function* <A, I>(\n schema: Schema.Codec<A, I, never>,\n raw: unknown,\n maxBytes: number,\n) {\n const text = yield* Schema.decodeUnknownEffect(Schema.String)(raw).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n\n if (text.length > maxBytes || memoryWireBytes(text) > maxBytes)\n return yield* MemoryRpcError.make({ reason: \"budget\" });\n\n return yield* Schema.decodeEffect(Schema.fromJsonString(schema))(text).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n});\n\nexport const encodeMemoryWire = Effect.fn(\"encodeMemoryWire\")(function* <A, I>(\n schema: Schema.Codec<A, I, never, never>,\n value: A,\n maxBytes: number,\n) {\n const encoded = yield* Schema.encodeEffect(Schema.fromJsonString(schema))(value).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n\n if (encoded.length > maxBytes || memoryWireBytes(encoded) > maxBytes)\n return yield* MemoryRpcError.make({ reason: \"budget\" });\n\n return encoded;\n});\n\n/** One local read per distinct candidate source, with no per-document network calls. */\nexport const handleMemoryOwnerRequest = Effect.fn(\"MemoryOwner.handleRequest\")(function* (\n raw: unknown,\n limits: MemoryRpcLimits = defaultMemoryRpcLimits,\n): Effect.fn.Return<\n string,\n never,\n MemoryOwnerIdentity | MemoryOwnerAuthorizer | MemoryReader | MemoryWriter\n> {\n const result = yield* Effect.gen(function* (): Effect.fn.Return<\n MemoryOwnerResponse,\n MemoryOwnerFailure,\n MemoryOwnerIdentity | MemoryOwnerAuthorizer | MemoryReader | MemoryWriter\n > {\n limits = yield* Schema.decodeUnknownEffect(MemoryRpcLimits)(limits).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n const request = yield* decodeMemoryWire(MemoryOwnerRequest, raw, limits.maxRequestBytes);\n const { namespace } = yield* MemoryOwnerIdentity;\n\n if (\n !MemoryNamespace.equals(namespace, request.access.namespace) ||\n (request._tag === \"Change\" &&\n !MemoryNamespace.equals(namespace, request.write.key.namespace)) ||\n (request._tag === \"RevalidateSemantic\" &&\n request.found.candidates.some(\n (candidate) => !MemoryNamespace.equals(namespace, candidate.key.namespace),\n ))\n )\n return yield* MemoryRpcError.make({ reason: \"denied\" });\n\n const remaining = Math.min(\n limits.timeoutMillis,\n request.deadlineMillis - (yield* Clock.currentTimeMillis),\n );\n\n if (remaining <= 0) return yield* MemoryRpcError.make({ reason: \"timeout\" });\n\n return yield* Effect.gen(function* (): Effect.fn.Return<\n MemoryOwnerResponse,\n MemoryOwnerFailure,\n MemoryOwnerAuthorizer | MemoryReader | MemoryWriter\n > {\n const authorizer = yield* MemoryOwnerAuthorizer;\n\n yield* authorizer.authorize(request);\n if (request._tag === \"Change\") {\n const writer = yield* MemoryWriter;\n\n return {\n _tag: \"Changed\",\n access: request.access,\n document: yield* writer.change(request.write),\n };\n }\n if (request._tag === \"RevalidateSemantic\") {\n if (\n new Set(request.found.candidates.map((candidate) => candidate.key.id)).size >\n limits.maxSources\n )\n return yield* MemoryRpcError.make({ reason: \"budget\" });\n\n const result = yield* revalidateSemanticMemoryCandidates(\n request.found,\n request.access,\n request.profile,\n {\n ...request.limits,\n maxSourceBytes: Math.min(\n limits.maxSourceBytes,\n request.limits.maxSourceBytes ?? 16_777_216,\n ),\n maxOutputBytes: Math.min(\n limits.maxResponseBytes,\n request.limits.maxOutputBytes ?? 16_777_216,\n ),\n },\n );\n\n return { _tag: \"Semantic\", access: request.access, result };\n }\n\n const count =\n request.lookup._tag === \"Found\"\n ? new Set(request.lookup.passages.map((passage) => passage.source.id)).size\n : 0;\n\n if (count > Math.min(limits.maxSources, request.limits.maxSources))\n return yield* MemoryRpcError.make({ reason: \"budget\" });\n\n const lookup = yield* revalidateMemoryLookup(request.lookup, request.access, {\n maxSourceBytes: limits.maxSourceBytes,\n maxInputBytes: Math.min(limits.maxSourceBytes, request.limits.maxInputBytes ?? 16_777_216),\n });\n\n return { _tag: \"Lookup\", access: request.access, lookup };\n }).pipe(\n Effect.scoped,\n Effect.timeoutOrElse({\n duration: remaining,\n orElse: () => Effect.fail(MemoryRpcError.make({ reason: \"timeout\" })),\n }),\n );\n }).pipe(\n Effect.flatMap((response) =>\n encodeMemoryWire(MemoryOwnerResponse, response, limits.maxResponseBytes),\n ),\n Effect.result,\n );\n\n if (result._tag === \"Success\") return result.success;\n\n return yield* encodeMemoryWire(\n MemoryOwnerResponse,\n {\n _tag: \"Failed\",\n failure: result.failure,\n },\n limits.maxResponseBytes,\n ).pipe(\n Effect.catch(() =>\n Schema.encodeEffect(Schema.fromJsonString(MemoryOwnerResponse))({\n _tag: \"Failed\",\n failure: MemoryRpcError.make({ reason: \"budget\" }),\n }).pipe(Effect.orDie),\n ),\n );\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"MemoryProtocol.mjs","names":[],"sources":["../src/MemoryProtocol.ts"],"sourcesContent":["import * as MemoryNamespace from \"@effect-agent/core/MemoryNamespace\";\nimport {\n MemoryLookup,\n MemoryRecallError,\n MemoryRecallLimits,\n} from \"@effect-agent/core/MemoryReference\";\nimport { MemoryAccess, revalidateMemoryLookup } from \"@effect-agent/core/MemoryRevalidation\";\nimport {\n MemoryKey,\n MemoryReader,\n MemoryConflict,\n MemoryDocument,\n MemoryMutationFailure,\n MemoryOperationConflict,\n MemoryStorageError,\n MemoryWithdrawn,\n MemoryWrite,\n MemoryWriter,\n} from \"@effect-agent/core/MemoryStore\";\nimport {\n MemoryIndexSearch,\n MemoryIndexError,\n SemanticMemoryProfile,\n} from \"@effect-agent/core/SemanticMemoryIndex\";\nimport {\n SemanticMemoryError,\n SemanticCandidateLimits,\n SemanticCandidateResult,\n revalidateSemanticMemoryCandidates,\n} from \"@effect-agent/core/SemanticMemoryRevalidation\";\nimport { Principal } from \"@effect-agent/thread/SubmissionLedger\";\nimport { Clock, Context, Effect, Schema } from \"effect\";\n\nexport class MemoryRpcError extends Schema.TaggedError<MemoryRpcError>()(\"MemoryRpcError\", {\n reason: Schema.Literals([\"denied\", \"protocol\", \"budget\", \"timeout\", \"unavailable\"]),\n}) {}\n\nexport class MemoryRpcLimits extends Schema.Class<MemoryRpcLimits>(\n \"@effect-agent/storage-cloudflare/MemoryRpcLimits\",\n)({\n maxRequestBytes: Schema.Int.check(Schema.isBetween({ minimum: 256, maximum: 4_194_304 })),\n maxResponseBytes: Schema.Int.check(Schema.isBetween({ minimum: 256, maximum: 16_777_216 })),\n maxSourceBytes: Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 67_108_864 })),\n maxSources: MemoryRecallLimits.fields.maxSources,\n timeoutMillis: MemoryRecallLimits.fields.timeoutMillis,\n}) {}\n\nexport const defaultMemoryRpcLimits = MemoryRpcLimits.make({\n maxRequestBytes: 1_048_576,\n maxResponseBytes: 4_194_304,\n maxSourceBytes: 16_777_216,\n maxSources: 16,\n timeoutMillis: 10_000,\n});\n\nconst RequestFields = {\n version: Schema.Literal(1),\n access: MemoryAccess.Wire,\n /** Host-authenticated identity, never copied from model input. The owner still authorizes it. */\n principal: Principal,\n deadlineMillis: Schema.Finite.check(Schema.isGreaterThanOrEqualTo(0)),\n};\n\nconst RevalidateRequest = Schema.TaggedStruct(\"Revalidate\", {\n ...RequestFields,\n lookup: MemoryLookup,\n limits: MemoryRecallLimits,\n});\n\nconst ChangeRequest = Schema.TaggedStruct(\"Change\", { ...RequestFields, write: MemoryWrite.Wire });\n\nconst GetRequest = Schema.TaggedStruct(\"Get\", { ...RequestFields, key: MemoryKey.Wire });\n\nconst SemanticRequest: Schema.TaggedStruct<\n \"RevalidateSemantic\",\n typeof RequestFields & {\n readonly found: typeof MemoryIndexSearch.Wire;\n readonly profile: typeof SemanticMemoryProfile;\n readonly limits: typeof SemanticCandidateLimits;\n }\n> = Schema.TaggedStruct(\"RevalidateSemantic\", {\n ...RequestFields,\n found: MemoryIndexSearch.Wire,\n profile: SemanticMemoryProfile,\n limits: SemanticCandidateLimits,\n});\n\nexport const MemoryOwnerRequest: Schema.Union<\n [typeof RevalidateRequest, typeof ChangeRequest, typeof SemanticRequest, typeof GetRequest]\n> = Schema.Union([RevalidateRequest, ChangeRequest, SemanticRequest, GetRequest]);\n\nexport type MemoryOwnerRequest = typeof MemoryOwnerRequest.Type;\n\nexport const MemoryOwnerFailure = Schema.Union([\n MemoryRpcError,\n MemoryStorageError,\n MemoryRecallError,\n MemoryConflict,\n MemoryWithdrawn,\n MemoryOperationConflict,\n MemoryMutationFailure,\n MemoryIndexError,\n SemanticMemoryError,\n]);\n\nexport type MemoryOwnerFailure = typeof MemoryOwnerFailure.Type;\n\nconst LookupResponse = Schema.TaggedStruct(\"Lookup\", {\n access: MemoryAccess.Wire,\n lookup: MemoryLookup,\n});\n\nconst ChangedResponse = Schema.TaggedStruct(\"Changed\", {\n access: MemoryAccess.Wire,\n document: MemoryDocument.Wire,\n});\n\nconst SemanticResponse = Schema.TaggedStruct(\"Semantic\", {\n access: MemoryAccess.Wire,\n result: SemanticCandidateResult,\n});\n\nconst DocumentResponse = Schema.TaggedStruct(\"Document\", {\n access: MemoryAccess.Wire,\n key: MemoryKey.Wire,\n document: Schema.NullOr(MemoryDocument.Wire),\n});\n\nconst FailedResponse = Schema.TaggedStruct(\"Failed\", { failure: MemoryOwnerFailure });\n\nexport const MemoryOwnerResponse: Schema.Union<\n [\n typeof LookupResponse,\n typeof ChangedResponse,\n typeof SemanticResponse,\n typeof DocumentResponse,\n typeof FailedResponse,\n ]\n> = Schema.Union([\n LookupResponse,\n ChangedResponse,\n SemanticResponse,\n DocumentResponse,\n FailedResponse,\n]);\n\nexport type MemoryOwnerResponse = typeof MemoryOwnerResponse.Type;\n\n/**\n * Fail-closed application policy. Authorize the namespace, principal, scope, and full command.\n * Get requires exact-key authority, including application source/provenance checks where needed.\n * Possession of a key or scope is not authorization, including for absent or withdrawn documents.\n */\nexport class MemoryOwnerAuthorizer extends Context.Service<\n MemoryOwnerAuthorizer,\n {\n readonly authorize: (request: MemoryOwnerRequest) => Effect.Effect<void, MemoryRpcError>;\n }\n>()(\"@effect-agent/storage-cloudflare/MemoryOwnerAuthorizer\") {}\n\n/** Canonical namespace derived from this object's idFromName identity, never its request. */\nexport class MemoryOwnerIdentity extends Context.Service<\n MemoryOwnerIdentity,\n {\n readonly namespace: MemoryNamespace.Any;\n }\n>()(\"@effect-agent/storage-cloudflare/MemoryOwnerIdentity\") {}\n\nexport const memoryWireBytes = (text: string): number => new TextEncoder().encode(text).byteLength;\n\nexport const decodeMemoryWire = Effect.fn(\"decodeMemoryWire\")(function* <A, I>(\n schema: Schema.Codec<A, I, never>,\n raw: unknown,\n maxBytes: number,\n) {\n const text = yield* Schema.decodeUnknownEffect(Schema.String)(raw).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n\n if (text.length > maxBytes || memoryWireBytes(text) > maxBytes)\n return yield* MemoryRpcError.make({ reason: \"budget\" });\n\n return yield* Schema.decodeEffect(Schema.fromJsonString(schema))(text).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n});\n\nexport const encodeMemoryWire = Effect.fn(\"encodeMemoryWire\")(function* <A, I>(\n schema: Schema.Codec<A, I, never, never>,\n value: A,\n maxBytes: number,\n) {\n const encoded = yield* Schema.encodeEffect(Schema.fromJsonString(schema))(value).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n\n if (encoded.length > maxBytes || memoryWireBytes(encoded) > maxBytes)\n return yield* MemoryRpcError.make({ reason: \"budget\" });\n\n return encoded;\n});\n\n/** One local read for Get, or per distinct candidate source. No discovery or background work. */\nexport const handleMemoryOwnerRequest = Effect.fn(\"MemoryOwner.handleRequest\")(function* (\n raw: unknown,\n limits: MemoryRpcLimits = defaultMemoryRpcLimits,\n): Effect.fn.Return<\n string,\n never,\n MemoryOwnerIdentity | MemoryOwnerAuthorizer | MemoryReader | MemoryWriter\n> {\n const result = yield* Effect.gen(function* (): Effect.fn.Return<\n MemoryOwnerResponse,\n MemoryOwnerFailure,\n MemoryOwnerIdentity | MemoryOwnerAuthorizer | MemoryReader | MemoryWriter\n > {\n limits = yield* Schema.decodeUnknownEffect(MemoryRpcLimits)(limits).pipe(\n Effect.mapError(() => MemoryRpcError.make({ reason: \"protocol\" })),\n );\n const request = yield* decodeMemoryWire(MemoryOwnerRequest, raw, limits.maxRequestBytes);\n const { namespace } = yield* MemoryOwnerIdentity;\n\n if (\n !MemoryNamespace.equals(namespace, request.access.namespace) ||\n (request._tag === \"Get\" && !MemoryNamespace.equals(namespace, request.key.namespace)) ||\n (request._tag === \"Change\" &&\n !MemoryNamespace.equals(namespace, request.write.key.namespace)) ||\n (request._tag === \"RevalidateSemantic\" &&\n request.found.candidates.some(\n (candidate) => !MemoryNamespace.equals(namespace, candidate.key.namespace),\n ))\n )\n return yield* MemoryRpcError.make({ reason: \"denied\" });\n\n const remaining = Math.min(\n limits.timeoutMillis,\n request.deadlineMillis - (yield* Clock.currentTimeMillis),\n );\n\n if (remaining <= 0) return yield* MemoryRpcError.make({ reason: \"timeout\" });\n\n return yield* Effect.gen(function* (): Effect.fn.Return<\n MemoryOwnerResponse,\n MemoryOwnerFailure,\n MemoryOwnerAuthorizer | MemoryReader | MemoryWriter\n > {\n const authorizer = yield* MemoryOwnerAuthorizer;\n\n yield* authorizer.authorize(request);\n if (request._tag === \"Get\") {\n const reader = yield* MemoryReader;\n const current = yield* reader.get(request.key);\n\n const document =\n current === null ? null : yield* MemoryDocument.restore(namespace, current);\n\n if (document !== null) {\n if (document.key.id !== request.key.id || document.source.id !== request.key.id)\n return yield* MemoryStorageError.make({\n operation: \"validate memory read identity\",\n reason: \"corrupt\",\n });\n if (\n document._tag === \"ActiveMemoryDocument\" &&\n !document.scopes.includes(request.access.scope)\n )\n return yield* MemoryRpcError.make({ reason: \"denied\" });\n\n yield* encodeMemoryWire(MemoryDocument.Wire, document, limits.maxSourceBytes);\n }\n\n return { _tag: \"Document\", access: request.access, key: request.key, document };\n }\n if (request._tag === \"Change\") {\n const writer = yield* MemoryWriter;\n\n return {\n _tag: \"Changed\",\n access: request.access,\n document: yield* writer.change(request.write),\n };\n }\n if (request._tag === \"RevalidateSemantic\") {\n if (\n new Set(request.found.candidates.map((candidate) => candidate.key.id)).size >\n limits.maxSources\n )\n return yield* MemoryRpcError.make({ reason: \"budget\" });\n\n const result = yield* revalidateSemanticMemoryCandidates(\n request.found,\n request.access,\n request.profile,\n {\n ...request.limits,\n maxSourceBytes: Math.min(\n limits.maxSourceBytes,\n request.limits.maxSourceBytes ?? 16_777_216,\n ),\n maxOutputBytes: Math.min(\n limits.maxResponseBytes,\n request.limits.maxOutputBytes ?? 16_777_216,\n ),\n },\n );\n\n return { _tag: \"Semantic\", access: request.access, result };\n }\n\n const count =\n request.lookup._tag === \"Found\"\n ? new Set(request.lookup.passages.map((passage) => passage.source.id)).size\n : 0;\n\n if (count > Math.min(limits.maxSources, request.limits.maxSources))\n return yield* MemoryRpcError.make({ reason: \"budget\" });\n\n const lookup = yield* revalidateMemoryLookup(request.lookup, request.access, {\n maxSourceBytes: limits.maxSourceBytes,\n maxInputBytes: Math.min(limits.maxSourceBytes, request.limits.maxInputBytes ?? 16_777_216),\n });\n\n return { _tag: \"Lookup\", access: request.access, lookup };\n }).pipe(\n Effect.scoped,\n Effect.timeoutOrElse({\n duration: remaining,\n orElse: () => Effect.fail(MemoryRpcError.make({ reason: \"timeout\" })),\n }),\n );\n }).pipe(\n Effect.flatMap((response) =>\n encodeMemoryWire(MemoryOwnerResponse, response, limits.maxResponseBytes),\n ),\n Effect.result,\n );\n\n if (result._tag === \"Success\") return result.success;\n\n return yield* encodeMemoryWire(\n MemoryOwnerResponse,\n {\n _tag: \"Failed\",\n failure: result.failure,\n },\n limits.maxResponseBytes,\n ).pipe(\n Effect.catch(() =>\n Schema.encodeEffect(Schema.fromJsonString(MemoryOwnerResponse))({\n _tag: \"Failed\",\n failure: MemoryRpcError.make({ reason: \"budget\" }),\n }).pipe(Effect.orDie),\n ),\n );\n});\n"],"mappings":"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"}
@@ -674,6 +674,24 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
674
674
  readonly childResultDigest: string;
675
675
  readonly projectedResultDigest: string;
676
676
  readonly usageSummary: Schema.Json;
677
+ readonly usage?: {
678
+ readonly modelCalls: number;
679
+ readonly inputTokens: number;
680
+ readonly outputTokens: number;
681
+ readonly costMicrousd: number;
682
+ readonly usageStatus?: "complete" | "partial" | "unknown" | undefined;
683
+ readonly pricingStatus?: "complete" | "partial" | "unknown" | undefined;
684
+ readonly unobservedModelCalls?: number | undefined;
685
+ } | undefined;
686
+ readonly delegatedUsage?: {
687
+ readonly modelCalls: number;
688
+ readonly inputTokens: number;
689
+ readonly outputTokens: number;
690
+ readonly costMicrousd: number;
691
+ readonly usageStatus?: "complete" | "partial" | "unknown" | undefined;
692
+ readonly pricingStatus?: "complete" | "partial" | "unknown" | undefined;
693
+ readonly unobservedModelCalls?: number | undefined;
694
+ } | undefined;
677
695
  readonly reservationId: string;
678
696
  readonly finalAccounting: Schema.Json;
679
697
  } | {
@@ -1269,6 +1287,24 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
1269
1287
  readonly childResultDigest: string;
1270
1288
  readonly projectedResultDigest: string;
1271
1289
  readonly usageSummary: Schema.Json;
1290
+ readonly usage?: {
1291
+ readonly modelCalls: number;
1292
+ readonly inputTokens: number;
1293
+ readonly outputTokens: number;
1294
+ readonly costMicrousd: number;
1295
+ readonly usageStatus?: "complete" | "partial" | "unknown" | undefined;
1296
+ readonly pricingStatus?: "complete" | "partial" | "unknown" | undefined;
1297
+ readonly unobservedModelCalls?: number | undefined;
1298
+ } | undefined;
1299
+ readonly delegatedUsage?: {
1300
+ readonly modelCalls: number;
1301
+ readonly inputTokens: number;
1302
+ readonly outputTokens: number;
1303
+ readonly costMicrousd: number;
1304
+ readonly usageStatus?: "complete" | "partial" | "unknown" | undefined;
1305
+ readonly pricingStatus?: "complete" | "partial" | "unknown" | undefined;
1306
+ readonly unobservedModelCalls?: number | undefined;
1307
+ } | undefined;
1272
1308
  readonly reservationId: string;
1273
1309
  readonly finalAccounting: Schema.Json;
1274
1310
  } | {
@@ -2193,6 +2229,24 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
2193
2229
  readonly childResultDigest: string;
2194
2230
  readonly projectedResultDigest: string;
2195
2231
  readonly usageSummary: Schema.Json;
2232
+ readonly usage?: {
2233
+ readonly modelCalls: number;
2234
+ readonly inputTokens: number;
2235
+ readonly outputTokens: number;
2236
+ readonly costMicrousd: number;
2237
+ readonly usageStatus?: "complete" | "partial" | "unknown" | undefined;
2238
+ readonly pricingStatus?: "complete" | "partial" | "unknown" | undefined;
2239
+ readonly unobservedModelCalls?: number | undefined;
2240
+ } | undefined;
2241
+ readonly delegatedUsage?: {
2242
+ readonly modelCalls: number;
2243
+ readonly inputTokens: number;
2244
+ readonly outputTokens: number;
2245
+ readonly costMicrousd: number;
2246
+ readonly usageStatus?: "complete" | "partial" | "unknown" | undefined;
2247
+ readonly pricingStatus?: "complete" | "partial" | "unknown" | undefined;
2248
+ readonly unobservedModelCalls?: number | undefined;
2249
+ } | undefined;
2196
2250
  readonly reservationId: string;
2197
2251
  readonly finalAccounting: Schema.Json;
2198
2252
  } | {
@@ -2810,6 +2864,24 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
2810
2864
  readonly childResultDigest: string;
2811
2865
  readonly projectedResultDigest: string;
2812
2866
  readonly usageSummary: Schema.Json;
2867
+ readonly usage?: {
2868
+ readonly modelCalls: number;
2869
+ readonly inputTokens: number;
2870
+ readonly outputTokens: number;
2871
+ readonly costMicrousd: number;
2872
+ readonly usageStatus?: "complete" | "partial" | "unknown" | undefined;
2873
+ readonly pricingStatus?: "complete" | "partial" | "unknown" | undefined;
2874
+ readonly unobservedModelCalls?: number | undefined;
2875
+ } | undefined;
2876
+ readonly delegatedUsage?: {
2877
+ readonly modelCalls: number;
2878
+ readonly inputTokens: number;
2879
+ readonly outputTokens: number;
2880
+ readonly costMicrousd: number;
2881
+ readonly usageStatus?: "complete" | "partial" | "unknown" | undefined;
2882
+ readonly pricingStatus?: "complete" | "partial" | "unknown" | undefined;
2883
+ readonly unobservedModelCalls?: number | undefined;
2884
+ } | undefined;
2813
2885
  readonly reservationId: string;
2814
2886
  readonly finalAccounting: Schema.Json;
2815
2887
  } | {
@@ -3116,6 +3188,9 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
3116
3188
  readonly operation: string;
3117
3189
  readonly message: string;
3118
3190
  readonly cause?: Schema.Json | undefined;
3191
+ } | {
3192
+ readonly _tag: "PortProtocolError";
3193
+ readonly message: string;
3119
3194
  } | {
3120
3195
  readonly _tag: "SettlementConflict";
3121
3196
  readonly submissionId: string;
@@ -3124,9 +3199,6 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
3124
3199
  readonly _tag: "JoinedToHost";
3125
3200
  readonly submissionId: string;
3126
3201
  readonly hostSubmissionId: string;
3127
- } | {
3128
- readonly _tag: "PortProtocolError";
3129
- readonly message: string;
3130
3202
  };
3131
3203
  }, Schema.SchemaError, never>;
3132
3204
  declare const decodePortResponse: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => import("effect/Effect").Effect<PortFailed | PortSucceeded, Schema.SchemaError, never>;
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@effect-agent/storage-cloudflare","version":"0.1.0-beta.77","dependencies":{"@effect-agent/core":"0.1.0-beta.77","@effect-agent/thread":"0.1.0-beta.77","@effect/platform-browser":"4.0.0-rc.112","@effect/sql-sqlite-do":"4.0.0-rc.112"},"devDependencies":{"@cloudflare/vitest-pool-workers":"0.21.3","@cloudflare/workers-types":"5.20260825.1","@effect-agent/testing":"0.1.0-beta.77","@effect/vitest":"4.0.0-rc.112","effect":"4.0.0-rc.112","typescript":"7.0.2","vite-plus":"0.3.0","vitest":"4.1.11"},"peerDependencies":{"effect":"^4.0.0-rc.112"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./DoMemoryStore":{"types":"./dist/DoMemoryStore.d.mts","default":"./dist/DoMemoryStore.mjs"},"./DoScheduleStore":{"types":"./dist/DoScheduleStore.d.mts","default":"./dist/DoScheduleStore.mjs"},"./DoStorageConfig":{"types":"./dist/DoStorageConfig.d.mts","default":"./dist/DoStorageConfig.mjs"},"./DoStorageError":{"types":"./dist/DoStorageError.d.mts","default":"./dist/DoStorageError.mjs"},"./DoStorageFailpoint":{"types":"./dist/DoStorageFailpoint.d.mts","default":"./dist/DoStorageFailpoint.mjs"},"./DoStorageVersion":{"types":"./dist/DoStorageVersion.d.mts","default":"./dist/DoStorageVersion.mjs"},"./DoSubmissionLedger":{"types":"./dist/DoSubmissionLedger.d.mts","default":"./dist/DoSubmissionLedger.mjs"},"./DoSubscriptionStore":{"types":"./dist/DoSubscriptionStore.d.mts","default":"./dist/DoSubscriptionStore.mjs"},"./DoThreadStore":{"types":"./dist/DoThreadStore.d.mts","default":"./dist/DoThreadStore.mjs"},"./MemoryProtocol":{"types":"./dist/MemoryProtocol.d.mts","default":"./dist/MemoryProtocol.mjs"},"./PortProtocol":{"types":"./dist/PortProtocol.d.mts","default":"./dist/PortProtocol.mjs"},"./PortRouting":{"types":"./dist/PortRouting.d.mts","default":"./dist/PortRouting.mjs"},"./testing/DoStorageFailpointTesting":{"types":"./dist/DoStorageFailpointTesting.d.mts","default":"./dist/DoStorageFailpointTesting.mjs"},"./DoMessageDeliveryStore":{"types":"./dist/DoMessageDeliveryStore.d.mts","default":"./dist/DoMessageDeliveryStore.mjs"}},"description":"Durable Object SQLite storage adapters and the routed port protocol for Effect Agent on Cloudflare.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/danieljvdm/effect-agent.git","directory":"packages/storage-cloudflare"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json"}}
1
+ {"name":"@effect-agent/storage-cloudflare","version":"0.1.0-beta.79","dependencies":{"@effect-agent/core":"0.1.0-beta.79","@effect-agent/thread":"0.1.0-beta.79","@effect/platform-browser":"4.0.0-rc.112","@effect/sql-sqlite-do":"4.0.0-rc.112"},"devDependencies":{"@cloudflare/vitest-pool-workers":"0.21.3","@cloudflare/workers-types":"5.20260825.1","@effect-agent/testing":"0.1.0-beta.79","@effect/vitest":"4.0.0-rc.112","effect":"4.0.0-rc.112","typescript":"7.0.2","vite-plus":"0.3.0","vitest":"4.1.11"},"peerDependencies":{"effect":"^4.0.0-rc.112"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./DoMemoryStore":{"types":"./dist/DoMemoryStore.d.mts","default":"./dist/DoMemoryStore.mjs"},"./DoScheduleStore":{"types":"./dist/DoScheduleStore.d.mts","default":"./dist/DoScheduleStore.mjs"},"./DoStorageConfig":{"types":"./dist/DoStorageConfig.d.mts","default":"./dist/DoStorageConfig.mjs"},"./DoStorageError":{"types":"./dist/DoStorageError.d.mts","default":"./dist/DoStorageError.mjs"},"./DoStorageFailpoint":{"types":"./dist/DoStorageFailpoint.d.mts","default":"./dist/DoStorageFailpoint.mjs"},"./DoStorageVersion":{"types":"./dist/DoStorageVersion.d.mts","default":"./dist/DoStorageVersion.mjs"},"./DoSubmissionLedger":{"types":"./dist/DoSubmissionLedger.d.mts","default":"./dist/DoSubmissionLedger.mjs"},"./DoSubscriptionStore":{"types":"./dist/DoSubscriptionStore.d.mts","default":"./dist/DoSubscriptionStore.mjs"},"./DoThreadStore":{"types":"./dist/DoThreadStore.d.mts","default":"./dist/DoThreadStore.mjs"},"./MemoryProtocol":{"types":"./dist/MemoryProtocol.d.mts","default":"./dist/MemoryProtocol.mjs"},"./PortProtocol":{"types":"./dist/PortProtocol.d.mts","default":"./dist/PortProtocol.mjs"},"./PortRouting":{"types":"./dist/PortRouting.d.mts","default":"./dist/PortRouting.mjs"},"./testing/DoStorageFailpointTesting":{"types":"./dist/DoStorageFailpointTesting.d.mts","default":"./dist/DoStorageFailpointTesting.mjs"},"./DoMessageDeliveryStore":{"types":"./dist/DoMessageDeliveryStore.d.mts","default":"./dist/DoMessageDeliveryStore.mjs"}},"description":"Durable Object SQLite storage adapters and the routed port protocol for Effect Agent on Cloudflare.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/danieljvdm/effect-agent.git","directory":"packages/storage-cloudflare"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json"}}
@@ -5,8 +5,9 @@ import {
5
5
  MemoryRecallLimits,
6
6
  } from "@effect-agent/core/MemoryReference";
7
7
  import { MemoryAccess, revalidateMemoryLookup } from "@effect-agent/core/MemoryRevalidation";
8
- import { type MemoryReader } from "@effect-agent/core/MemoryStore";
9
8
  import {
9
+ MemoryKey,
10
+ MemoryReader,
10
11
  MemoryConflict,
11
12
  MemoryDocument,
12
13
  MemoryMutationFailure,
@@ -68,6 +69,8 @@ const RevalidateRequest = Schema.TaggedStruct("Revalidate", {
68
69
 
69
70
  const ChangeRequest = Schema.TaggedStruct("Change", { ...RequestFields, write: MemoryWrite.Wire });
70
71
 
72
+ const GetRequest = Schema.TaggedStruct("Get", { ...RequestFields, key: MemoryKey.Wire });
73
+
71
74
  const SemanticRequest: Schema.TaggedStruct<
72
75
  "RevalidateSemantic",
73
76
  typeof RequestFields & {
@@ -83,8 +86,8 @@ const SemanticRequest: Schema.TaggedStruct<
83
86
  });
84
87
 
85
88
  export const MemoryOwnerRequest: Schema.Union<
86
- [typeof RevalidateRequest, typeof ChangeRequest, typeof SemanticRequest]
87
- > = Schema.Union([RevalidateRequest, ChangeRequest, SemanticRequest]);
89
+ [typeof RevalidateRequest, typeof ChangeRequest, typeof SemanticRequest, typeof GetRequest]
90
+ > = Schema.Union([RevalidateRequest, ChangeRequest, SemanticRequest, GetRequest]);
88
91
 
89
92
  export type MemoryOwnerRequest = typeof MemoryOwnerRequest.Type;
90
93
 
@@ -102,16 +105,52 @@ export const MemoryOwnerFailure = Schema.Union([
102
105
 
103
106
  export type MemoryOwnerFailure = typeof MemoryOwnerFailure.Type;
104
107
 
105
- export const MemoryOwnerResponse = Schema.Union([
106
- Schema.TaggedStruct("Lookup", { access: MemoryAccess.Wire, lookup: MemoryLookup }),
107
- Schema.TaggedStruct("Changed", { access: MemoryAccess.Wire, document: MemoryDocument.Wire }),
108
- Schema.TaggedStruct("Semantic", { access: MemoryAccess.Wire, result: SemanticCandidateResult }),
109
- Schema.TaggedStruct("Failed", { failure: MemoryOwnerFailure }),
108
+ const LookupResponse = Schema.TaggedStruct("Lookup", {
109
+ access: MemoryAccess.Wire,
110
+ lookup: MemoryLookup,
111
+ });
112
+
113
+ const ChangedResponse = Schema.TaggedStruct("Changed", {
114
+ access: MemoryAccess.Wire,
115
+ document: MemoryDocument.Wire,
116
+ });
117
+
118
+ const SemanticResponse = Schema.TaggedStruct("Semantic", {
119
+ access: MemoryAccess.Wire,
120
+ result: SemanticCandidateResult,
121
+ });
122
+
123
+ const DocumentResponse = Schema.TaggedStruct("Document", {
124
+ access: MemoryAccess.Wire,
125
+ key: MemoryKey.Wire,
126
+ document: Schema.NullOr(MemoryDocument.Wire),
127
+ });
128
+
129
+ const FailedResponse = Schema.TaggedStruct("Failed", { failure: MemoryOwnerFailure });
130
+
131
+ export const MemoryOwnerResponse: Schema.Union<
132
+ [
133
+ typeof LookupResponse,
134
+ typeof ChangedResponse,
135
+ typeof SemanticResponse,
136
+ typeof DocumentResponse,
137
+ typeof FailedResponse,
138
+ ]
139
+ > = Schema.Union([
140
+ LookupResponse,
141
+ ChangedResponse,
142
+ SemanticResponse,
143
+ DocumentResponse,
144
+ FailedResponse,
110
145
  ]);
111
146
 
112
147
  export type MemoryOwnerResponse = typeof MemoryOwnerResponse.Type;
113
148
 
114
- /** Fail-closed application policy. Authorize the namespace, principal, scope, and full command. */
149
+ /**
150
+ * Fail-closed application policy. Authorize the namespace, principal, scope, and full command.
151
+ * Get requires exact-key authority, including application source/provenance checks where needed.
152
+ * Possession of a key or scope is not authorization, including for absent or withdrawn documents.
153
+ */
115
154
  export class MemoryOwnerAuthorizer extends Context.Service<
116
155
  MemoryOwnerAuthorizer,
117
156
  {
@@ -161,7 +200,7 @@ export const encodeMemoryWire = Effect.fn("encodeMemoryWire")(function* <A, I>(
161
200
  return encoded;
162
201
  });
163
202
 
164
- /** One local read per distinct candidate source, with no per-document network calls. */
203
+ /** One local read for Get, or per distinct candidate source. No discovery or background work. */
165
204
  export const handleMemoryOwnerRequest = Effect.fn("MemoryOwner.handleRequest")(function* (
166
205
  raw: unknown,
167
206
  limits: MemoryRpcLimits = defaultMemoryRpcLimits,
@@ -183,6 +222,7 @@ export const handleMemoryOwnerRequest = Effect.fn("MemoryOwner.handleRequest")(f
183
222
 
184
223
  if (
185
224
  !MemoryNamespace.equals(namespace, request.access.namespace) ||
225
+ (request._tag === "Get" && !MemoryNamespace.equals(namespace, request.key.namespace)) ||
186
226
  (request._tag === "Change" &&
187
227
  !MemoryNamespace.equals(namespace, request.write.key.namespace)) ||
188
228
  (request._tag === "RevalidateSemantic" &&
@@ -207,6 +247,30 @@ export const handleMemoryOwnerRequest = Effect.fn("MemoryOwner.handleRequest")(f
207
247
  const authorizer = yield* MemoryOwnerAuthorizer;
208
248
 
209
249
  yield* authorizer.authorize(request);
250
+ if (request._tag === "Get") {
251
+ const reader = yield* MemoryReader;
252
+ const current = yield* reader.get(request.key);
253
+
254
+ const document =
255
+ current === null ? null : yield* MemoryDocument.restore(namespace, current);
256
+
257
+ if (document !== null) {
258
+ if (document.key.id !== request.key.id || document.source.id !== request.key.id)
259
+ return yield* MemoryStorageError.make({
260
+ operation: "validate memory read identity",
261
+ reason: "corrupt",
262
+ });
263
+ if (
264
+ document._tag === "ActiveMemoryDocument" &&
265
+ !document.scopes.includes(request.access.scope)
266
+ )
267
+ return yield* MemoryRpcError.make({ reason: "denied" });
268
+
269
+ yield* encodeMemoryWire(MemoryDocument.Wire, document, limits.maxSourceBytes);
270
+ }
271
+
272
+ return { _tag: "Document", access: request.access, key: request.key, document };
273
+ }
210
274
  if (request._tag === "Change") {
211
275
  const writer = yield* MemoryWriter;
212
276