/** * Same-origin endpoint descriptions for a future HUX-02 backend adapter. * The server must derive identity from the authenticated session, compare it * with each request's expectedIdentity, and echo it in list responses. A * revision appends a proposed ledger entry; forget purges content while * retaining audit metadata. These descriptors never perform a request. */ import { memoryControlEnabled } from "./model.ts"; import { isOpaqueMemoryId, normalizeIdentity } from "./security.ts"; import type { HuxIdentity, MemoryAction, MemoryEndpoint, MemoryEndpointContract, } from "./types.ts"; interface FoundationClient { apiVersion: string; identity: HuxIdentity; endpoint(path: string): string; } function endpoint( method: MemoryEndpoint["method"], path: string, responseSchema: string, ): MemoryEndpoint { return Object.freeze({ method, path, responseSchema }); } /** * Describe, but do not call, the backend interface. Returning null while any * dependency flag is absent keeps HUX-02 inert and default-off. */ export function createMemoryEndpointContract( client: FoundationClient, flags?: Iterable, ): MemoryEndpointContract | null { if (!memoryControlEnabled(flags)) return null; if (client.apiVersion !== "hux.v1") throw new TypeError("HUX v1 client required"); const identity = Object.freeze({ ...normalizeIdentity(client.identity) }); function itemPath(memoryId: string): string { if (!isOpaqueMemoryId(memoryId)) throw new TypeError("Opaque memory id required"); return client.endpoint(`/memories/${memoryId}`); } return Object.freeze({ identity, list: endpoint("GET", client.endpoint("/memories"), "hux.memory_page.v1"), suggestOnly: endpoint( "PUT", client.endpoint("/memory-settings/suggest-only"), "hux.memory_settings.v1", ), doNotRemember: endpoint( "POST", client.endpoint("/memory-blocks"), "hux.memory_block.v1", ), action(memoryId: string, action: MemoryAction) { if (!["approve", "reject", "forget"].includes(action)) throw new TypeError("Unsupported memory action"); return endpoint( "POST", `${itemPath(memoryId)}/${action}`, "hux.memory.v1", ); }, revise(memoryId: string) { return endpoint( "POST", `${itemPath(memoryId)}/revisions`, "hux.memory.v1", ); }, }); }