{"version":3,"sources":["../../src/entity/index.ts","../../src/core/supabase.ts","../../src/core/pgError.ts","../../src/entity/core/errors.ts","../../src/entity/core/client.ts","../../src/entity/core/wire.ts","../../src/entity/core/realtime.ts","../../src/ops.ts","../../src/entity/port/port.ts","../../src/entity/port/rows.ts"],"sourcesContent":["// src/index.ts — @ai-matrx/records/entity\n//\n// Platform records through the one DataPort. No React here: the frame reads these ports through\n// `@ai-matrx/records/data/react` (`DataPortProvider` + `useDataRows` …).\nexport * from \"./core\";\nexport * from \"./port\";\n","// src/core/supabase.ts — @ai-matrx/records (HEADLESS)\n//\n// THE ONE ADAPTER FROM A SUPABASE CLIENT TO THIS PACKAGE'S DATA SEAM.\n//\n// Why it exists, and what it cost to learn (2026-09-19, the independent verdict\n// on /data): `RecordsDataSource.rpc(fn, args, { schema })` says the schema\n// out loud, because every door of this store is `custom.<name>` and every door\n// of the trust layer is `iam.<name>`. supabase-js's own\n// `rpc(fn, args, options)` HAS NO `schema` OPTION — its third argument is\n// `{ head, get, count }`, and an unknown key is dropped in silence. So a\n// supabase client handed straight to `config.dataSource` as a structural cast\n// asked its default PostgREST profile, `public`, for every door, and the store\n// answered correctly and uselessly:\n//\n//   PGRST202 — Could not find the function public.table_kernel_id(...) in the\n//   schema cache\n//\n// Every screen in the record store was dead from a browser because of it, while\n// the desktop app and the browser extension each grew their own way of asking.\n// The class fix is ONE adapter, here, in the headless core, that every host\n// inherits — never three hosts remembering the same thing.\n//\n// The schema is chosen the ONE way supabase-js offers: `client.schema(name)`\n// returns a client bound to that PostgREST profile (it sets the\n// `Accept-Profile` / `Content-Profile` headers), and `.rpc()` on THAT is the\n// call. There is no per-call option that does it.\n//\n// This file holds no key and opens no connection: the host hands in a client\n// that already carries the operating person's session, which is what makes\n// DOOR-5 and AGT-N-4 true — the store sees the person, not us.\n\nimport type { PgError } from \"../results\";\nimport type { RecordsDataSource } from \"../ports\";\n\n/**\n * The structural shape of the supabase client this adapter needs. Deliberately\n * NOT `SupabaseClient<Database>`: a generated `Database` type makes\n * `schema().from().select()` enormous, and a host app that passed its typed\n * client in got `TS2589: Type instantiation is excessively deep and possibly\n * infinite` in its own build (matrx-frontend, 2026-09-18, on all three campaign\n * routes at once). The cast lives here, once, where it is explained.\n */\nexport interface SupabaseLike {\n  schema(name: string): {\n    rpc(\n      fn: string,\n      args?: Record<string, unknown>,\n    ): PromiseLike<{ data: unknown; error: PgError | null }>;\n    from(table: string): unknown;\n  };\n}\n\n/** The refusal a caller sees rather than a silent call to the wrong schema. */\nfunction refuse(code: string, message: string, hint: string): { data: null; error: PgError } {\n  return { data: null, error: { code, message, hint, details: \"\" } as unknown as PgError };\n}\n\n/**\n * Bind a supabase-js client (or anything with the same `schema(name).rpc()`\n * shape) as this package's data seam.\n *\n * Two things never happen here, both of them loudly:\n *\n *  - A call with NO schema is never sent. It is refused by name, because\n *    sending it would reach `public` and get the store's PGRST202 several\n *    layers away from the mistake.\n *  - A client with no `.schema()` is never used. supabase-js has had it since\n *    v2.0; a host that binds something else is told exactly what is missing\n *    instead of throwing `undefined is not a function` inside a render.\n */\nexport function supabaseDataSource(client: object): RecordsDataSource {\n  if (isBound(client)) return client;\n  const supabase = client as unknown as Partial<SupabaseLike>;\n  const hasSchema = typeof supabase.schema === \"function\";\n\n  const bound: RecordsDataSource = {\n    // PAGE-BUNDLE: the real adapter opens a table page with one `custom.table_page_bundle` call.\n    opensInOneCall: true,\n    rpc(fn, args, options) {\n      if (!hasSchema) {\n        return Promise.resolve(\n          refuse(\n            \"data_source_unbound\",\n            `The records client was given something that is not a supabase client: it has no schema() ` +\n              `method, so the door ${fn} cannot be called in the schema it lives in.`,\n            \"Pass a supabase-js v2 client (createClient(...)) to supabaseDataSource().\",\n          ),\n        );\n      }\n      const name = options?.schema;\n      if (!name) {\n        return Promise.resolve(\n          refuse(\n            \"schema_unsaid\",\n            `The door ${fn} was called without saying which schema it lives in. ` +\n              `Every door of this store is custom.${fn} and every trust door is iam.${fn}; ` +\n              `an unqualified call reaches PostgREST's default profile (public) and is refused there.`,\n            \"This is a bug in the caller, not in your data: /core says the schema on every call.\",\n          ),\n        );\n      }\n      return (supabase as SupabaseLike).schema(name).rpc(fn, args) as ReturnType<\n        RecordsDataSource[\"rpc\"]\n      >;\n    },\n    schema(name) {\n      return (supabase as SupabaseLike).schema(name) as ReturnType<RecordsDataSource[\"schema\"]>;\n    },\n  };\n  Object.defineProperty(bound, BOUND, { value: true, enumerable: false });\n  return bound;\n}\n\n/** Marks a data source this adapter made, so binding it twice is a no-op, never a double wrap. */\nconst BOUND = Symbol.for(\"@ai-matrx/records/supabaseDataSource\");\n\nfunction isBound(source: object): source is RecordsDataSource {\n  return (source as Record<symbol, unknown>)[BOUND] === true;\n}\n\n/**\n * WHAT `createRecordsClient` DOES WITH WHATEVER IT IS HANDED (lane PLATFORM-APP-DATA, 2026-10-02).\n *\n * The README has always shown `dataSource: supabase` — a PLAIN supabase-js client — and that\n * exact line answered every call \"Could not find the function public.table_kernel_id\" (PGRST202),\n * because supabase-js's own `rpc()` drops the `{ schema }` option in silence (see the header).\n * Measured on the clone as admin@admin.com, 2026-10-02. The example is now true:\n *\n *  - Already bound by `supabaseDataSource` → used as it is.\n *  - A supabase-js client (it has `schema()`, `from()` and an `auth` client) → bound here, once.\n *  - Nothing callable at all (no `rpc()`) → bound here too, so every call is REFUSED by name with\n *    the remedy (`data_source_unbound`) instead of throwing `rpc is not a function` in a render.\n *  - Anything else that has its own `rpc(fn, args, { schema })` — a host's adapter, a test\n *    double — is the host's own data seam and is used as it is: it promised to honor `schema`.\n */\nexport function asRecordsDataSource(source: unknown): RecordsDataSource {\n  if (source === null || typeof source !== \"object\") return supabaseDataSource({});\n  if (isBound(source)) return source;\n  const candidate = source as Partial<SupabaseLike> & { rpc?: unknown; from?: unknown; auth?: unknown };\n  const looksLikeSupabaseJs =\n    typeof candidate.schema === \"function\" &&\n    typeof candidate.from === \"function\" &&\n    candidate.auth !== null &&\n    typeof candidate.auth === \"object\";\n  if (looksLikeSupabaseJs || typeof candidate.rpc !== \"function\") return supabaseDataSource(source);\n  return source as RecordsDataSource;\n}\n","// src/core/pgError.ts — @ai-matrx/records\n//\n// THE ONE FUNNEL from what the database said to what a caller reads. Every\n// method in this package's client goes through it, and it does exactly three\n// things: it classifies the SQLSTATE, it carries the store's message and hint\n// VERBATIM, and it parses the DETAIL when the store put json there.\n//\n// It never writes a sentence of its own about a refusal the store already\n// explained. The store's messages were written to be read by the person who hit\n// them — \"Someone else changed this record while you were working on it\" is the\n// screen's text, not a code the screen has to translate.\n\nimport type { PgError, RecordsError, RecordsErrorCode, StaleWriteDetail } from \"../results\";\n\n/**\n * SQLSTATE -> code. Every entry here answers one of the codes\n * `STORE_REFUSAL_CODES` reports the store raising; the real-door suite asserts\n * that this map covers all of them, so a new refusal class in the store shows\n * up as a red test rather than an `internal` in somebody's console.\n */\nconst BY_SQLSTATE: Record<string, RecordsErrorCode> = {\n  // Also what custom.has_visibility_at / table_move / whole_value_complete raise since 2026-10-21 (they\n  // raised 40001, which PostgREST retries without limit — the outage that day).\n  PT409: \"stale_write\",\n  \"42501\": \"door\",\n  \"23514\": \"refused_by_rule\",\n  \"22004\": \"invalid_argument\",\n  \"22023\": \"invalid_argument\",\n  // MX005 — a value the store cannot take as asked: since 2026-10-06 (AP-3 U3) a word that names more than one\n  // choice or linked record raises it (it used to borrow PT409 and read as somebody else's write winning).\n  MX005: \"invalid_argument\",\n  // MXD01 — the held-change door tried the proposed values before filing an\n  // approval request and the store refused them. Nothing is waiting for a\n  // person to decide; correct the value before asking again, which is the same\n  // caller-side condition as the other invalid-argument refusals.\n  MXD01: \"invalid_argument\",\n  // 22P02 — a value does not fit the type the store holds for it. The class is\n  // real and was hit live: an organization whose copy of a package table grew\n  // `status` as a uuid-valued Field was sent the text \"open\", and the store\n  // answered `invalid input syntax for type uuid: \"open\"`. It is the CALL that\n  // is wrong for the shape the store holds, which is what `invalid_argument`\n  // already means — the store's own sentence names the value and the type.\n  \"22P02\": \"invalid_argument\",\n  // 42703 — a column that is not there. The store raises it from\n  // `custom.entity_table`, which is asked for a column by NAME, so the class is\n  // exactly \"the call named something the shape does not have\": the same thing\n  // `invalid_argument` already means, and the store's own sentence names the\n  // column. Added 2026-09-20 (lane FORMS) because the package's live-door suite\n  // caught it raised by a door this package did not know about — which is the\n  // suite working, and is why the map is a census rather than a guess.\n  \"42703\": \"invalid_argument\",\n  // 22007 — a date or a time the store could not read as one. It is raised by\n  // `custom.dashboard_window_sql`, which is handed a window a caller wrote\n  // (\"last 30 days\", a literal date), so the class is again \"the call named\n  // something the shape does not accept\" and the store's own sentence names the\n  // text it could not read. Added 2026-09-20 (lane SCREEN-BREAK) after the\n  // live-door census caught it — the same way 42703 arrived, which is the\n  // census working rather than a guess.\n  \"22007\": \"invalid_argument\",\n  // 22003 — a number the store could not hold at the size it was handed. It is\n  // raised by `custom.context_resolve`, which is given a window or a depth a\n  // caller wrote, so the class is the same one 22P02, 42703 and 22007 already\n  // are: the CALL named a value the shape does not accept, and the store's own\n  // sentence names the number and the range. Added 2026-09-20 (lane GRID-TWO)\n  // when the live-door census caught the release gate red on it — which is the\n  // census working, and the fourth time it has been the thing that found a new\n  // refusal class rather than a person guessing one.\n  \"22003\": \"invalid_argument\",\n  // 42883 — `custom._template_call` (the template family, 2026-10-03) was handed a step that\n  // names a door the store does not have, or an argument that door does not take. The TEMPLATE\n  // named something the shape does not have — the same class 42703 is — and the store's own\n  // sentence names the door or the argument. Caught by the live-door census on records 0.68.1's\n  // tag, the eighth time the census found a class before a person did. (A bare 42883 on a door\n  // this package itself asks for is still `door_absent`, mapped before this funnel in\n  // `owedDoor`.)\n  \"42883\": \"invalid_argument\",\n  \"02000\": \"not_found\",\n  // P0002 — `custom.inbox_snooze` / `custom.inbox_clear` (lane S5-PRIME-2, 2026-09-24): \"There is\n  // nothing in your inbox with that id\". An invented id, another person's item and another\n  // organization's all answer it alike, so it reads exactly as 02000 does: not found.\n  \"P0002\": \"not_found\",\n  // 23502 — `custom.synced_source_save` (the synced-source registry, 2026-10-16) refuses a source\n  // saved without a value it cannot do without (its door, its table), in its own sentence naming\n  // the value. The CALL left out something the shape requires: the same class as 22004.\n  \"23502\": \"invalid_argument\",\n  \"23503\": \"missing_reference\",\n  \"23505\": \"already_exists\",\n  \"0A000\": \"not_supported\",\n  \"53400\": \"store_limit\",\n  \"22012\": \"store_limit\",\n  // 54001 — `custom.record_delete` stops a cascade that nests past sixty-four\n  // levels of containment, because that is a loop somebody built rather than a\n  // hierarchy, and saying so beats recursing until the server runs out of\n  // stack. It is a LIMIT of the store, and the store's own sentence names what\n  // to do about it, so it reads as one.\n  \"54001\": \"store_limit\",\n  // 54000 — the grid primitives' organization ceilings (GRID-PRIMITIVES, 2026-09-23):\n  // `custom.action_run` on a selection past its knob, `custom.table_decorate` past the\n  // rule count, `custom.table_from_example` past `custom/example_rows_max`,\n  // `custom.table_webhook_declare` past `custom/table_webhooks_max`, and\n  // `custom.hub_changed_by`. Each names its knob in the hint and writes nothing, so it\n  // reads exactly like 54001: a limit of the store, in the store's own sentence.\n  \"54000\": \"store_limit\",\n  // VIS: `custom.has_visibility_at` refuses to answer from a snapshot older\n  // than a write this reader has already seen, rather than returning something\n  // they just lost access to. It is retryable on a fresher connection, which is\n  // a different instruction from every other refusal here.\n  // 55000 — `custom.table_move` (SC-1', 2026-09-24) refuses a move the table's present state\n  // does not allow: a destination that cannot take it, a table something else holds, contents\n  // that point at themselves in a circle. The store's own sentence names the reason and nothing\n  // moves, so it reads as a refusal on the merits. Caught by the live-door census on records\n  // 0.58.3's tag, the seventh time the census found a class before a person did.\n  \"55000\": \"refused_by_rule\",\n  // 42P17 — a worked-out column that would read itself round a circle (STORE-TAILS-3,\n  // 2026-09-25): `custom._field_reads_what_it_reads` refuses the declaration or edit that would\n  // close the circle, naming every column in it, and `custom.far_value` refuses a circle stored\n  // before that rule when a lookup or rollup is worked out. Refused on its merits, in the store's\n  // own sentence, nothing written — so it reads as 55000 does.\n  \"42P17\": \"refused_by_rule\",\n  // P0001 — `custom.context_scope_write` (2026-10-03) refuses a scope whose parent breaks the\n  // parent rule in the old trigger's own class and words (manager ruling H6). Refused on its\n  // merits, nothing written. Caught by the live-door census on records 0.65.0's tag.\n  P0001: \"refused_by_rule\",\n  \"40001\": \"stale_read\",\n  // 57014 — the store canceled the statement at its own timeout. Like\n  // `stale_read` and unlike every other refusal here, the call was never\n  // refused on its merits: the same call on a smaller page, or once the\n  // organization's kernel is not being rewritten, can succeed. It gets its own\n  // code so a screen can offer \"try again\" honestly instead of showing a\n  // failure sentence the caller cannot act on.\n  \"57014\": \"timed_out\",\n  // PostgREST's own two: the store is not being SERVED, which is a different\n  // thing from the store refusing. `custom` absent from `pgrst.db_schemas`, or\n  // the grants not copied, land here.\n  PGRST202: \"store_not_served\",\n  PGRST205: \"store_not_served\",\n  PGRST301: \"door\",\n  // PT428 — NOT A FAILURE, and the release gate's live census is what found it\n  // missing: the store raises it and this package answered `internal`, which is\n  // the one classification that tells a screen nothing. A stage gate whose\n  // `on_fail` is `require_approval` files the request and leaves the record\n  // where it was; the transaction is rolled back to the pipeline's own block, so\n  // \"nothing was written\" is a fact rather than a promise. Landed by lane\n  // STAGE-RULES; mapped here by STAGE-RULES-2 the day after, when the census\n  // caught it — the sixth time that census has been the thing that found a\n  // refusal class rather than a person guessing one.\n  PT428: \"needs_approval\",\n};\n\n/** The SQLSTATEs this package claims to understand. Exported for the guard. */\nexport const MAPPED_SQLSTATES = Object.keys(BY_SQLSTATE);\n\nfunction parseDetail(details: string | null | undefined): unknown {\n  if (!details) return undefined;\n  const trimmed = details.trim();\n  if (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) return details;\n  try {\n    return JSON.parse(trimmed) as unknown;\n  } catch {\n    return details;\n  }\n}\n\n/**\n * A CODE THAT IS NOT A SQLSTATE AT ALL — so it is not read as one.\n *\n * A SQLSTATE is five characters. supabase-js puts something else in `code` in\n * exactly two situations, and BOTH of them mean the call never reached the\n * store rather than the store refusing it:\n *\n *   `\"\"`        a `FetchError` — no network, a canceled request, CORS.\n *   `\"404\"`…    an HTTP status, when the gateway answered with no JSON body.\n *\n * Lane TAILS-6 (2026-09-22) found both landing in `internal`, which is the one\n * classification that tells a screen nothing: a person on the Checklists tab of\n * a plumbing company's jobs table was shown \"Something went wrong at our end\"\n * with nothing to do about it, over a sentence naming this package. They are\n * `unreachable`, which a screen can honestly offer \"try again\" for.\n */\nfunction isNotASqlstate(code: string | undefined): boolean {\n  if (!code) return true;\n  return /^[0-9]{3}$/.test(code);\n}\n\n/** What a person reads when the store cancelled a call at its statement timeout (57014, code `timed_out`). */\nexport const TIMED_OUT_MESSAGE = \"That took too long. Nothing was lost; try again.\";\n\n/** Map a PostgREST/supabase-js failure into the package's refusal shape. */\n/**\n * THE DOOR'S NAME NEVER REACHES A PERSON (lane AT-REVIEW-3). The store's refusals are written for the\n * engineer and name the door that refused (\"…and custom.doc_template_save needs Full access\", \"…so\n * custom.read_record has nothing to do there\"). A person reads plain words; the store's own sentence goes\n * to the diagnostic. One place, so every door and every screen inherits it.\n */\nexport function plainDoorWords(text: string, where: string): string {\n  const bare = where.replace(/^custom\\./, \"\");\n  const names = [where, bare].filter((n, i, all) => n && /^[A-Za-z0-9_.]+$/.test(n) && all.indexOf(n) === i);\n  const door = `(?:custom\\\\.[a-z0-9_]+${names.map((n) => `|${n.replace(/\\./g, \"\\\\.\")}`).join(\"\")})`;\n  const rules: Array<[RegExp, string]> = [\n    [new RegExp(`, so ${door} has nothing to do there( until an owner restores it)?\\\\.`, \"g\"), \", so there is nothing for you to do there$1.\"],\n    [new RegExp(`, so ${door} has nothing to show you\\\\.`, \"g\"), \", so there is nothing to show you.\"],\n    [new RegExp(`, so ${door} may not write to it\\\\.`, \"g\"), \", so you cannot change it.\"],\n    [new RegExp(`, and ${door} needs `, \"g\"), \", and changing it needs \"],\n    [new RegExp(`, so ${door} is not taking writes\\\\.`, \"g\"), \", so it is not taking changes.\"],\n    // The store now names the ACTION here (\"Changing a record\", or \"Making this change\" for a door outside its\n    // map), not the door — so the sentence is matched by its shape, whatever words lead it.\n    [/^custom: .+? was called without an organization, and the store is keyed \\(organization_id, id\\)\\./, \"Say which organization you are working in.\"],\n    [new RegExp(`\\\\b${door} needs `, \"g\"), \"That needs \"],\n    [new RegExp(`\\\\b${door}\\\\b`, \"g\"), \"that\"],\n  ];\n  let out = text;\n  for (const [re, to] of rules) out = out.replace(re, to);\n  return out;\n}\n\nexport function mapPgError(error: PgError, where: string): RecordsError {\n  // `code: \"\"` is supabase-js's own value for a transport failure, and `\"\"` is\n  // not nullish — so it has to be emptied deliberately or it becomes a SQLSTATE\n  // nobody can look up.\n  const raw = error.code ?? undefined;\n  const sqlstate = raw && raw !== \"\" ? raw : undefined;\n  const mapped: RecordsError = {\n    code: \"internal\",\n    message: error.message,\n    ...(error.hint ? { hint: error.hint } : {}),\n    ...(sqlstate ? { sqlstate } : {}),\n  };\n  // TEMPLATE-INSTALL-3: PGRST001/PGRST002 (\"Could not query the database for the schema cache\") are the API being away, the same\n  // thing a 503 is: never raw text on a screen, and never \"internal\".\n  if (isNotASqlstate(sqlstate) || sqlstate === \"PGRST001\" || sqlstate === \"PGRST002\") {\n    mapped.code = \"unreachable\";\n  } else {\n    mapped.code = BY_SQLSTATE[sqlstate!] ?? \"internal\";\n  }\n  const detail = parseDetail(error.details);\n  if (detail !== undefined) mapped.detail = detail;\n  if (mapped.code === \"internal\") {\n    // 🚨 THE NOTE GOES IN ITS OWN FIELD, NEVER ONTO `hint` (lane TAILS-6).\n    // `hint` is THE REMEDY — the sentence screens hand a person to act on — so\n    // a note this package writes about ITSELF being surprised belonged nowhere\n    // near it. It is still said out loud, so nobody reads the silence as\n    // \"handled\"; it is said to whoever debugs this and to nobody else.\n    mapped.unmapped = true;\n    mapped.diagnostic =\n      `@ai-matrx/records did not recognize SQLSTATE ${sqlstate ?? \"(none)\"} from ${where}; ` +\n      `the store's own message is the thing to act on.`;\n  } else if (mapped.code === \"unreachable\") {\n    mapped.unmapped = true;\n    mapped.diagnostic =\n      `@ai-matrx/records never reached the store from ${where}: ` +\n      `${raw ? `the transport answered ${raw}` : \"no response\"} — ${error.message}`;\n    // 🚨 THE ONE PLACE THIS PACKAGE WRITES A MESSAGE OF ITS OWN, and it is the\n    // one place where there is no store message to carry: the store never\n    // answered. `TypeError: Failed to fetch` is the browser talking to itself,\n    // not a sentence anybody should read, so it goes to the engineer's line\n    // above and the person gets what actually happened.\n    mapped.message = \"We could not reach your data.\";\n    // Whatever the transport said was never a remedy either; the remedy is to ask again (the one-line message plus Try again).\n    mapped.hint = \"Try again.\";\n  } else if (mapped.code === \"door\") {\n    const said = plainDoorWords(error.message, where);\n    if (said !== error.message) {\n      mapped.diagnostic = `${where} refused: ${error.message}`;\n      mapped.message = said;\n    }\n    if (mapped.hint) mapped.hint = plainDoorWords(mapped.hint, where);\n  } else if (mapped.code === \"timed_out\") {\n    // 🚨 THE SECOND PLACE THIS PACKAGE WRITES ITS OWN SENTENCE (lane AT-SLOW, 2026-10-19). 57014 is\n    // Postgres talking about itself — \"canceling statement due to statement timeout\" — not a refusal\n    // the store wrote for a person, and it reached people raw on base move, Kanban \"Make it work\" and\n    // base rename. The cancelled statement rolled back, so nothing was written. The store's words go\n    // to the engineer's line; the person gets what happened and what to do.\n    mapped.diagnostic = `${where} was cancelled at the store's statement timeout: ${error.message}`;\n    mapped.message = TIMED_OUT_MESSAGE;\n    delete mapped.hint;\n  }\n  return mapped;\n}\n\n/**\n * Anything a host caught (a supabase-js error object, a thrown `Error`, a string) as the package's\n * refusal, through `mapPgError` — so a host service's `catch` speaks the same words as its doors.\n */\nexport function mapThrownError(thrown: unknown, where: string): RecordsError {\n  const o = thrown && typeof thrown === \"object\" ? (thrown as { code?: unknown; message?: unknown; details?: unknown; hint?: unknown }) : {};\n  const message = typeof o.message === \"string\" && o.message ? o.message : thrown == null ? \"Unknown error\" : String(thrown);\n  const code = typeof o.code === \"string\" ? o.code : null;\n  // A supabase-js answer (it carries a code) and a transport failure are the store's / the\n  // network's; anything else a host threw is its own sentence and is kept as said.\n  if (code !== null || (thrown instanceof TypeError && /fetch|network/i.test(message))) {\n    return mapPgError(\n      { code, message, details: typeof o.details === \"string\" ? o.details : null, hint: typeof o.hint === \"string\" ? o.hint : null },\n      where,\n    );\n  }\n  return {\n    code: \"internal\",\n    message,\n    unmapped: true,\n    diagnostic: `@ai-matrx/records: ${where} threw outside the store.`,\n  };\n}\n\n/** Pull the conflict out of a `stale_write`, when the store sent one. */\nexport function staleWriteDetail(error: RecordsError): StaleWriteDetail | null {\n  if (error.code !== \"stale_write\") return null;\n  const detail = error.detail as Partial<StaleWriteDetail> | undefined;\n  if (\n    !detail ||\n    typeof detail.expected_version !== \"number\" ||\n    typeof detail.current_version !== \"number\"\n  ) {\n    return null;\n  }\n  return {\n    expected_version: detail.expected_version,\n    current_version: detail.current_version,\n    contested_fields: detail.contested_fields ?? {},\n  };\n}\n\n/**\n * HONEST-REFUSALS 1 — a member of an ARCHIVED organization is refused with the store's own sentence\n * (\"This organization is archived, …\") and DETAIL `organization_archived:<organization id>`. The sentence\n * and the restore hint ride `message` and `hint` verbatim like every refusal; this reads the organization out\n * so a screen can offer \"Restore\" (the owner's `iam.organization_restore` door) instead of a dead end.\n * Null for every other refusal, including the non-member's \"You are not a member of that organization\".\n */\nexport function archivedOrganizationId(error: RecordsError): string | null {\n  if (error.code !== \"door\" || typeof error.detail !== \"string\") return null;\n  const m = /^organization_archived:([0-9a-f-]{36})$/i.exec(error.detail.trim());\n  return m ? m[1]! : null;\n}\n","// src/core/errors.ts — @ai-matrx/records/entity\n//\n// THE ERROR MAP (PHASE-B-APPLETS §4). The entity doors raise their own `MX0xx` class; this turns it\n// into the `RecordsError` every other door of the records package answers, carrying THE STORE'S\n// SENTENCE VERBATIM (message and hint are never rewritten here). Anything that is not an `MX` code\n// (a timeout, a dropped connection, a revoked schema) goes through records' own `mapPgError`.\n\nimport { mapPgError } from \"../../core/pgError\";\nimport type { PgError, RecordsError, RecordsErrorCode } from \"../../results\";\n\n/**\n * Every MX code a read door raises, and the engine code a screen branches on. A code the doors learn\n * later and this map lacks comes back `internal` with `unmapped: true` (never silently \"handled\").\n */\nexport const ENTITY_REFUSALS: Readonly<Record<string, RecordsErrorCode>> = {\n  /** conflict_version: somebody else's write won. */\n  MX001: \"stale_write\",\n  /** organization_required: the call needs an organization and carried none. */\n  MX002: \"organization_required\",\n  /** forbidden. */\n  MX003: \"door\",\n  /** not_found (also: not visible to this person). */\n  MX004: \"not_found\",\n  /** validation_refused (detail.reason required / bad_value / ambiguous_word / constraint; `not_supported` is read apart below). */\n  MX005: \"invalid_argument\",\n  /** system_column: a write named a column the store owns. */\n  MX008: \"invalid_argument\",\n  /** unknown_identifier: a column that is not there or not usable here. */\n  MX012: \"invalid_argument\",\n  /** cursor_invalid: the page cursor belongs to another list; the engine restarts the page. */\n  MX013: \"invalid_argument\",\n  /** view_not_offered. */\n  MX015: \"invalid_argument\",\n  /** invalid_argument: a parameter the door refuses by name. */\n  MX016: \"invalid_argument\",\n};\n\nexport function mapEntityError(error: PgError, where: string): RecordsError {\n  const mapped = mapPgError(error, where);\n  const state = mapped.sqlstate;\n  if (state && /^MX\\d{3}$/.test(state)) {\n    const code = ENTITY_REFUSALS[state];\n    if (code) {\n      // MX005 that says the store does not offer this yet is a different question for a screen than a bad value.\n      const reason = (mapped.detail as { reason?: unknown } | undefined)?.reason;\n      const known: RecordsError = { ...mapped, code: state === \"MX005\" && reason === \"not_supported\" ? \"not_supported\" : code };\n      delete known.unmapped;\n      delete known.diagnostic;\n      return known;\n    }\n  }\n  return mapped;\n}\n\n/** A refusal this package itself raises (an alias nobody declared, a write not offered yet). */\nexport function refusal(code: RecordsErrorCode, message: string, hint?: string): { ok: false; error: RecordsError } {\n  return { ok: false, error: { code, message, ...(hint ? { hint } : {}) } };\n}\n","// src/core/client.ts — @ai-matrx/records/entity\n//\n// THE THIN TYPED CLIENT over the live INVOKER doors in `platform`: reads (`entity_list_scoped`,\n// `entity_get`, `entity_columns`) and, since 0.3, writes (`entity_insert`, `entity_update`,\n// `entity_archive`, `entity_unarchive`). Every call answers a `RecordsResult` and\n// never throws; every refusal is the store's own sentence (see `errors.ts`). The caller's seat is the\n// one on the supabase client handed in — nothing here widens or narrows what the store lets her see.\n\nimport { asRecordsDataSource } from \"../../core/supabase\";\nimport type { RecordsDataSource } from \"../../ports\";\nimport type { RecordsResult } from \"../../results\";\nimport type { Uuid } from \"../../record\";\nimport { mapEntityError } from \"./errors\";\nimport type { EntityColumnsAnswer, EntityGetAnswer, EntityListAnswer, EntityWireQuery, EntityWriteAnswer } from \"./types\";\n\n/**\n * THE ECHO HEADER (U6). The entity doors take no `_op_id` argument: the writer's op id rides the request\n * as this header, PostgREST hands it to `request.headers`, and `platform._entity_org_notice` puts it on\n * the notice as `op_id`, so the browser that wrote drops its own echo (`@ai-matrx/records` `isOwnOp`).\n */\nexport const OP_ID_HEADER = \"x-matrx-op-id\";\n\n/** What a write takes beyond its arguments: the op id minted for it (`mintOpId`). */\nexport interface EntityWriteOptions {\n  opId?: string;\n}\n\n/** The schema every entity door lives in. */\nexport const ENTITY_DOOR_SCHEMA = \"platform\";\n\nexport interface CreateEntityClientOptions {\n  /** A supabase-js v2 client for the signed-in person, or anything with `rpc(fn, args, {schema})`. */\n  dataSource?: unknown;\n  /** Same thing, spelled the way the plan names it. Give one of the two. */\n  supabase?: unknown;\n}\n\nexport interface EntityListRequest extends EntityWireQuery {\n  token: string;\n  /** Keyset cursor from the previous answer's `next_after`. */\n  after?: string | null;\n  /** Ask the door to skip the count. Default: counted. */\n  withTotal?: boolean;\n  archived?: \"active\" | \"archived\" | \"all\";\n}\n\nexport interface EntityClient {\n  list(request: EntityListRequest): Promise<RecordsResult<EntityListAnswer>>;\n  get(request: { token: string; ids: readonly Uuid[] }): Promise<RecordsResult<EntityGetAnswer>>;\n  /** `organizationId` null reads the custom fields of every organization the person belongs to. */\n  columns(request: { token: string; organizationId?: Uuid | null }): Promise<RecordsResult<EntityColumnsAnswer>>;\n  /** One `entity_data` knob as `platform.knob_resolve` answers it for an organization (live updates read three). */\n  knob(request: { key: string; organizationId?: Uuid | null }): Promise<RecordsResult<unknown>>;\n  /** `platform.entity_insert`: rows into the organization the host names (never guessed). */\n  insert(request: { token: string; organizationId: Uuid; rows: readonly Record<string, unknown>[] } & EntityWriteOptions): Promise<RecordsResult<EntityWriteAnswer>>;\n  /** `platform.entity_update`: one row, refused as stale (`MX001`) unless `baseVersion` is still current. */\n  update(request: { token: string; id: Uuid; baseVersion: number; patch: Record<string, unknown> } & EntityWriteOptions): Promise<RecordsResult<EntityWriteAnswer>>;\n  /** `platform.entity_archive` (on these types, the trash). */\n  archive(request: { token: string; ids: readonly Uuid[] } & EntityWriteOptions): Promise<RecordsResult<EntityWriteAnswer>>;\n  /** `platform.entity_unarchive`. */\n  unarchive(request: { token: string; ids: readonly Uuid[] } & EntityWriteOptions): Promise<RecordsResult<EntityWriteAnswer>>;\n  /** The organizations the person belongs to, as row security counts them (`iam.my_orgs()`: archived ones closed). */\n  memberOrganizations(): Promise<RecordsResult<Uuid[]>>;\n}\n\nexport function createEntityClient(options: CreateEntityClientOptions): EntityClient {\n  const source: RecordsDataSource = asRecordsDataSource(options.dataSource ?? options.supabase);\n\n  let warnedHeaderless = false;\n\n  /**\n   * A per-call header rides the request builder supabase-js hands back (`PostgrestBuilder.setHeader`, set\n   * before the builder is awaited). `@ai-matrx/records`' adapter returns that builder unwrapped, so the\n   * header reaches PostgREST on this one call only — never on the client every other caller shares.\n   * A data seam whose answer has no `setHeader` (a host's own adapter, a test double) cannot carry it:\n   * the write still lands, the writer re-reads its own echo once, and the console says why.\n   */\n  function withHeaders(pending: PromiseLike<unknown>, headers: Record<string, string> | undefined): void {\n    if (!headers) return;\n    const builder = pending as { setHeader?: (name: string, value: string) => unknown };\n    if (typeof builder.setHeader === \"function\") {\n      for (const [name, value] of Object.entries(headers)) builder.setHeader(name, value);\n      return;\n    }\n    if (!warnedHeaderless) {\n      warnedHeaderless = true;\n      console.warn(\n        `[@ai-matrx/records/entity] This data source cannot carry a per-call header (${Object.keys(headers).join(\", \")}), so this browser re-reads the notice of its own writes once.`,\n      );\n    }\n  }\n\n  async function call<T>(\n    fn: string,\n    args: Record<string, unknown>,\n    schema: string = ENTITY_DOOR_SCHEMA,\n    headers?: Record<string, string>,\n  ): Promise<RecordsResult<T>> {\n    try {\n      const pending = source.rpc(fn, args, { schema });\n      withHeaders(pending, headers);\n      const answer = await pending;\n      if (answer.error) return { ok: false, error: mapEntityError(answer.error, `${schema}.${fn}`) };\n      return { ok: true, data: answer.data as T };\n    } catch (thrown) {\n      // supabase-js answers failures; a throw here is a transport that never reached the store.\n      return {\n        ok: false,\n        error: mapEntityError({ code: \"\", message: thrown instanceof Error ? thrown.message : String(thrown) }, `${schema}.${fn}`),\n      };\n    }\n  }\n\n  return {\n    list(request) {\n      const args: Record<string, unknown> = {\n        p_entity_type: request.token,\n        p_scope: request.scope ?? null,\n        p_filter: request.filter ?? {},\n        p_search: request.search ?? null,\n        p_sort: request.sort ?? null,\n        p_archived: request.archived ?? \"active\",\n        p_page_size: request.pageSize ?? null,\n        p_after: request.after ?? null,\n        p_with_total: request.withTotal ?? true,\n      };\n      return call<EntityListAnswer>(\"entity_list_scoped\", args);\n    },\n    get(request) {\n      return call<EntityGetAnswer>(\"entity_get\", { p_entity_type: request.token, p_ids: [...request.ids] });\n    },\n    columns(request) {\n      return call<EntityColumnsAnswer>(\"entity_columns\", { p_organization_id: request.organizationId ?? null, p_token: request.token });\n    },\n    insert(request) {\n      return call<EntityWriteAnswer>(\n        \"entity_insert\",\n        { p_entity_type: request.token, p_organization_id: request.organizationId, p_rows: request.rows.map((r) => ({ ...r })) },\n        ENTITY_DOOR_SCHEMA,\n        opHeader(request.opId),\n      );\n    },\n    update(request) {\n      return call<EntityWriteAnswer>(\n        \"entity_update\",\n        { p_entity_type: request.token, p_id: request.id, p_base_version: request.baseVersion, p_patch: request.patch },\n        ENTITY_DOOR_SCHEMA,\n        opHeader(request.opId),\n      );\n    },\n    archive(request) {\n      return call<EntityWriteAnswer>(\"entity_archive\", { p_entity_type: request.token, p_ids: [...request.ids] }, ENTITY_DOOR_SCHEMA, opHeader(request.opId));\n    },\n    unarchive(request) {\n      return call<EntityWriteAnswer>(\"entity_unarchive\", { p_entity_type: request.token, p_ids: [...request.ids] }, ENTITY_DOOR_SCHEMA, opHeader(request.opId));\n    },\n    knob(request) {\n      return call<unknown>(\"knob_resolve\", { p_feature: \"entity_data\", p_key: request.key, p_organization_id: request.organizationId ?? null });\n    },\n    async memberOrganizations() {\n      const answer = await call<unknown>(\"my_orgs\", {}, \"iam\");\n      if (!answer.ok) return answer;\n      const rows = Array.isArray(answer.data) ? answer.data : [];\n      // A SETOF uuid comes back as bare strings; a row shape (`{my_orgs}`) is read the same way.\n      const ids = rows\n        .map((row) => (typeof row === \"string\" ? row : row && typeof row === \"object\" ? Object.values(row as Record<string, unknown>)[0] : null))\n        .filter((id): id is string => typeof id === \"string\");\n      return { ok: true, data: ids };\n    },\n  };\n}\n\nfunction opHeader(opId: string | undefined): Record<string, string> | undefined {\n  return opId ? { [OP_ID_HEADER]: opId } : undefined;\n}\n","// src/core/wire.ts — @ai-matrx/records/entity\n//\n// `toWire`: the Applets `Query` (§4) → the door's arguments (scope, filter, sort). Pure.\n//\n// What the doors do not offer yet is NOT filtered, reordered or emulated here: the clause is sent as\n// asked and the door refuses it BY NAME (`\"contains\" filters are not offered yet.`), so the day the\n// door learns it the port already speaks it, and until then the person reads the store's sentence.\n// A browser-side filter would silently drop everything the browser was not shown.\n\nimport type { Query, WhereClause } from \"../../data\";\nimport type { EntityWirePredicate, EntityWireQuery, EntityWireSort } from \"./types\";\n\n/** The runtime's underscore names for the three identity columns the doors call `id`, `version`, `organization_id`. */\nconst IDENTITY: Readonly<Record<string, string>> = {\n  _id: \"id\",\n  _version: \"version\",\n  _organization_id: \"organization_id\",\n};\n\nexport const CUSTOM_PREFIX = \"_custom.\";\n\n/**\n * Applets column key → the door's identifier. A custom field is `_custom.<key>` (the key as\n * `columns()` answered it — the same plain key for every viewer; `<key>@<organization_id>` is accepted, never produced).\n */\nexport function wireColumn(column: string, customKeys: ReadonlySet<string>): string {\n  const identity = IDENTITY[column];\n  if (identity) return identity;\n  if (column.startsWith(CUSTOM_PREFIX)) return column;\n  return customKeys.has(column) ? `${CUSTOM_PREFIX}${column}` : column;\n}\n\nfunction predicate(clause: WhereClause, customKeys: ReadonlySet<string>): EntityWirePredicate {\n  const column = wireColumn(clause.column, customKeys);\n  const v = clause.value;\n  switch (clause.op) {\n    case \"eq\":\n      // The store reads \"equals nothing\" as empty (the table port's rule, so both kinds of source agree).\n      return v === null || v === undefined ? { column, op: \"empty\" } : { column, op: \"eq\", value: v };\n    case \"neq\":\n      return v === null || v === undefined ? { column, op: \"empty\", negated: true } : { column, op: \"neq\", value: v };\n    case \"lt\":\n    case \"lte\":\n    case \"gt\":\n    case \"gte\":\n      return { column, op: clause.op, value: v };\n    case \"in\":\n      return { column, op: \"in\", values: Array.isArray(v) ? v : [] };\n    case \"empty\":\n      return v === false ? { column, op: \"empty\", negated: true } : { column, op: \"empty\" };\n    case \"contains\":\n      return { column, op: \"contains\", value: v };\n    default:\n      // An op this version does not know is still SENT, so the door names it, instead of vanishing here.\n      return { column, op: String((clause as WhereClause).op), value: v };\n  }\n}\n\nexport function toWire(query: Query | undefined, customKeys: ReadonlySet<string> = new Set()): EntityWireQuery {\n  const q = query ?? {};\n  const out: EntityWireQuery = {};\n  const scope: NonNullable<EntityWireQuery[\"scope\"]> = {};\n  if (q.lane) scope.kind = q.lane; // absent = the type's own landing lane, decided by the door\n  if (q.org && q.org !== \"all\") scope.organization_id = q.org; // a filter, never a lock\n  if (scope.kind || scope.organization_id) out.scope = scope;\n  if (q.where && q.where.length > 0) out.filter = { all: q.where.map((c) => predicate(c, customKeys)) };\n  const search = q.search?.trim();\n  if (search) out.search = search;\n  if (q.sort && q.sort.length > 0) {\n    out.sort = q.sort.map<EntityWireSort>((s) => ({\n      column: wireColumn(s.column, customKeys),\n      dir: s.direction === \"desc\" ? \"desc\" : \"asc\",\n      nulls: \"last\",\n    }));\n  }\n  if (typeof q.pageSize === \"number\" && Number.isFinite(q.pageSize)) out.pageSize = Math.max(1, Math.floor(q.pageSize));\n  return out;\n}\n","// src/core/realtime.ts — @ai-matrx/records/entity\n//\n// LIVE NOTICES FOR PLATFORM LISTS (PHASE-B-APPLETS R4 / U6).\n//\n// The database announces every statement on the five Table-API tables (party, crm_deal, project, task,\n// hr_employee) with ONE broadcast per organization it touched, on the PRIVATE topic\n// `mx:entity-org:<organization>:<token>`, event `entity_bump`, payload\n// `{id, entity_type, organization_id, op, op_id, ids | null, at}` — ids, never values. It is written by\n// `platform.entity_org_notice_stmt` and admitted by `platform.entity_org_topic_admits` through the one RLS\n// policy on `realtime.messages`: a signed-in member of that organization (her own memberships, never the\n// admin route) whose role may read the table. The subscriber re-reads the ids through the read door, so\n// row security decides what she sees at read time.\n//\n// This file joins those topics through `@ai-matrx/data/realtime` — the ONE realtime layer, never a hand-written\n// `.channel(` — so the socket, `setAuth` before a private join, backoff, dedupe and wake backfill are the\n// manager's.\n//\n//   · ONE CHANNEL PER (organization, token), HOWEVER MANY READERS — opened by the first, closed by the last.\n//   · BURSTS COALESCED per reader: the first notice starts a `batchMs` timer, later ones join it, and\n//     `maxWaitMs` caps how long a steady stream can hold a re-read back (knobs entity_data.realtime_batch_ms\n//     / realtime_max_wait_ms).\n//   · `ids: null` PASSES THROUGH — above knob entity_data.realtime_max_ids the database stops naming ids.\n//   · ECHO DROPPED — a write that carried header `x-matrx-op-id` comes back with that `op_id`; a notice whose\n//     op id this client minted (`@ai-matrx/records` `isOwnOp`) is our own write and is dropped.\n//   · NO REPLAY ON A WAKE OR RECONNECT — the answer is `ids: null` (read again).\n\nimport {\n  defineChannelNamespace,\n  subscribeToRealtimeManager,\n  type ChannelSpec,\n  type RealtimeManager,\n} from \"@ai-matrx/data/realtime\";\nimport { isOwnOp } from \"../../ops\";\n\nimport type { EntityClient } from \"./client\";\n\n/** The topic is a CONTRACT WITH THE DATABASE (a trigger writes it, an RLS policy parses it): built once, here. */\nexport const entityOrgChannel = defineChannelNamespace({\n  namespace: \"entity-org\",\n  foreignTopic: \"mx:entity-org\",\n  parts: [\"organizationId\", \"token\"],\n  description:\n    \"One organization's changes to one platform type (contacts, deals, projects, tasks, employees). Carries NOTICES written by platform.entity_org_notice_stmt — which ids moved, never a value. Admitted by the one RLS policy on realtime.messages to members of that organization.\",\n});\n\n/** The broadcast event the database sends on an organization topic. */\nexport const ENTITY_NOTICE_EVENT = \"entity_bump\";\n\n/** Starting values of the knobs the runtime coalesces with (entity_data.realtime_batch_ms / _max_wait_ms). */\nexport const DEFAULT_BATCH_MS = 150;\nexport const DEFAULT_MAX_WAIT_MS = 1000;\n/** Starting value of knob entity_data.realtime_max_org_topics. */\nexport const DEFAULT_MAX_ORG_TOPICS = 20;\n\nexport interface EntityNotice {\n  id?: string;\n  entity_type?: string;\n  organization_id?: string;\n  op?: \"created\" | \"updated\" | \"deleted\";\n  /** The client operation that caused it (header `x-matrx-op-id`), or null for any other writer. */\n  op_id?: string | null;\n  /** `null` MEANS \"more changed than the database lists: re-read\". */\n  ids?: string[] | null;\n  at?: string;\n}\n\n/** A redelivered notice is the same notice: the database mints one id per send. */\nexport function entityNoticeKey(notice: EntityNotice): string | undefined {\n  return notice.id ?? (notice.at ? `${notice.organization_id ?? \"\"}:${notice.entity_type ?? \"\"}:${notice.at}` : undefined);\n}\n\nexport function entityOrgTopic(organizationId: string, token: string): string {\n  return entityOrgChannel.topic({ organizationId, token });\n}\n\n/** The channel spec for one (organization, token): private, echo-guarded, deduped, backfilled. */\nexport function entityOrgChannelSpec(\n  organizationId: string,\n  token: string,\n  onNotice: (notice: EntityNotice) => void,\n  onBackfill: () => void,\n): ChannelSpec {\n  return {\n    topic: entityOrgTopic(organizationId, token),\n    // Database Broadcast is authorized by RLS on realtime.messages; the manager awaits setAuth() first.\n    private: true,\n    // The sender is Postgres: no Matrx envelope. Our own write is known by the op id it carried.\n    wire: { mode: \"raw\", isOwnMessage: (payload) => isOwnOp((payload as EntityNotice | null)?.op_id) },\n    eventKey: (_source, payload) => entityNoticeKey((payload ?? {}) as EntityNotice),\n    broadcast: [\n      {\n        event: ENTITY_NOTICE_EVENT,\n        onMessage: (message) => {\n          const notice = (message.data ?? {}) as EntityNotice;\n          if (isOwnOp(notice.op_id)) return; // belt and braces: the manager's test ran first\n          onNotice(notice);\n        },\n      },\n    ],\n    // Realtime has no replay: a channel back from a gap re-reads.\n    onBackfill: () => onBackfill(),\n  };\n}\n\n/**\n * Which organization topics to join, in order, until `max`: the active organization, the alias's `org`\n * filter, then the organizations of held rows by number of held rows (descending; organization id\n * ascending on ties), then the person's remaining memberships by id. Only memberships are kept when they\n * are known — any other topic is refused by the database anyway. Deterministic for the same input.\n */\nexport function orderOrganizationTopics(input: {\n  active?: string | null;\n  filter?: string | null;\n  held?: ReadonlyMap<string, number>;\n  members?: readonly string[] | null;\n  max: number;\n}): string[] {\n  const members = input.members ? new Set(input.members) : null;\n  const out: string[] = [];\n  const push = (org: string | null | undefined) => {\n    if (!org || out.includes(org)) return;\n    if (members && !members.has(org)) return;\n    out.push(org);\n  };\n  push(input.active);\n  push(input.filter);\n  const held = [...(input.held ?? new Map<string, number>()).entries()].sort((a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));\n  for (const [org] of held) push(org);\n  for (const org of [...(input.members ?? [])].sort()) push(org);\n  return out.slice(0, Math.max(0, input.max));\n}\n\nexport interface EntityNoticeSink {\n  /** `ids` to re-read, or `null` to re-read everything this reader shows. */\n  rows(ids: string[] | null): void;\n}\n\nexport interface EntityRealtime {\n  /** Hear `token` across `organizationIds`; the sink gets one coalesced call per burst. Returns the stop. */\n  subscribe(target: { token: string; organizationIds: readonly string[] }, sink: EntityNoticeSink): () => void;\n}\n\nexport interface CreateEntityRealtimeOptions {\n  /** The host's realtime manager. Left out, the AMBIENT manager the app mounted — never a socket of our own. */\n  manager?: RealtimeManager;\n  /** Knob entity_data.realtime_batch_ms (starting value 150). */\n  batchMs?: number;\n  /** Knob entity_data.realtime_max_wait_ms (starting value 1000). */\n  maxWaitMs?: number;\n}\n\ninterface OrgListener {\n  notice(notice: EntityNotice): void;\n  backfill(): void;\n}\n\ninterface OrgChannel {\n  listeners: Set<OrgListener>;\n  stop: (() => void) | null;\n}\n\n/** The live-notice layer for platform lists, bound to a realtime manager. One per host is enough. */\nexport function createEntityRealtime(options: CreateEntityRealtimeOptions = {}): EntityRealtime {\n  const batchMs = options.batchMs ?? DEFAULT_BATCH_MS;\n  const maxWaitMs = options.maxWaitMs ?? DEFAULT_MAX_WAIT_MS;\n  const channels = new Map<string, OrgChannel>();\n\n  const open = (organizationId: string, token: string): OrgChannel => {\n    const channel: OrgChannel = { listeners: new Set(), stop: null };\n    const spec = entityOrgChannelSpec(\n      organizationId,\n      token,\n      (notice) => {\n        for (const listener of channel.listeners) listener.notice(notice);\n      },\n      () => {\n        for (const listener of channel.listeners) listener.backfill();\n      },\n    );\n    if (options.manager) {\n      const handle = options.manager.open(spec);\n      channel.stop = () => handle.close();\n    } else {\n      channel.stop = subscribeToRealtimeManager(() => spec);\n    }\n    return channel;\n  };\n\n  return {\n    subscribe({ token, organizationIds }, sink) {\n      let timer: ReturnType<typeof setTimeout> | null = null;\n      let firstAt = 0;\n      let pending = new Set<string>();\n      let wholeList = false;\n\n      const flush = () => {\n        if (timer !== null) clearTimeout(timer);\n        timer = null;\n        const ids = [...pending];\n        const all = wholeList;\n        pending = new Set();\n        wholeList = false;\n        // THE IDS ARE USED AS IDS. `null` costs a whole re-read; three ids re-read three rows.\n        if (all) sink.rows(null);\n        else if (ids.length > 0) sink.rows(ids);\n      };\n      const nudge = () => {\n        const now = Date.now();\n        if (timer === null) firstAt = now;\n        else clearTimeout(timer);\n        // Wait `batchMs` after the latest notice, never past `maxWaitMs` after the first one.\n        const wait = Math.max(0, Math.min(batchMs, firstAt + maxWaitMs - now));\n        timer = setTimeout(flush, wait);\n      };\n\n      const listener: OrgListener = {\n        notice(notice) {\n          if (notice.entity_type && notice.entity_type !== token) return;\n          if (notice.ids == null) wholeList = true;\n          else for (const id of notice.ids) pending.add(id);\n          nudge();\n        },\n        backfill() {\n          wholeList = true;\n          flush();\n        },\n      };\n\n      const keys = [...new Set(organizationIds)].map((org) => {\n        const key = entityOrgTopic(org, token);\n        const channel = channels.get(key) ?? open(org, token);\n        channels.set(key, channel);\n        channel.listeners.add(listener);\n        return key;\n      });\n\n      return () => {\n        if (timer !== null) clearTimeout(timer);\n        for (const key of keys) {\n          const channel = channels.get(key);\n          if (!channel) continue;\n          channel.listeners.delete(listener);\n          if (channel.listeners.size > 0) continue;\n          // The last reader of this (organization, token) left: its one subscription goes with it.\n          channel.stop?.();\n          channels.delete(key);\n        }\n      };\n    },\n  };\n}\n\n/** The three live-update knobs as the store answers them for an organization (starting values when unset). */\nexport async function readEntityRealtimeKnobs(\n  client: Pick<EntityClient, \"knob\">,\n  organizationId?: string | null,\n): Promise<{ batchMs: number; maxWaitMs: number; maxOrgTopics: number }> {\n  const read = async (key: string, fallback: number) => {\n    const answer = await client.knob({ key, organizationId: organizationId ?? null });\n    const value = answer.ok ? Number(answer.data) : Number.NaN;\n    if (!Number.isFinite(value)) {\n      // SAID OUT LOUD: the starting value stands in for a knob the store did not answer.\n      console.warn(`[@ai-matrx/records/entity] knob entity_data.${key} did not resolve; using its starting value ${fallback}.`);\n      return fallback;\n    }\n    return value;\n  };\n  const [batchMs, maxWaitMs, maxOrgTopics] = await Promise.all([\n    read(\"realtime_batch_ms\", DEFAULT_BATCH_MS),\n    read(\"realtime_max_wait_ms\", DEFAULT_MAX_WAIT_MS),\n    read(\"realtime_max_org_topics\", DEFAULT_MAX_ORG_TOPICS),\n  ]);\n  return { batchMs, maxWaitMs, maxOrgTopics };\n}\n","/**\n * THE CLIENT OPERATION LEDGER — how a browser recognizes the echo of its own write.\n *\n * Every private-channel notice the record store broadcasts reaches EVERY browser watching that\n * Table, including the one that caused it. Until now the writer had no way to tell its own\n * change from a colleague's: the notice carried ids and nothing about who moved them, so\n * `recordsRealtimePort.ts` declared `acceptEchoFromSelf: true` and the writer re-read a page it\n * had already updated. It was named honestly rather than faked, and this is the other half.\n *\n * THE SHAPE. Every write through `RecordsClient` mints a uuid, sends it to the store as the\n * platform envelope key `_op_id`, and remembers it here. The store lifts that key out before\n * storage — it is never written onto the record — carries it on the change-feed row, and puts\n * it in the notice as `op_id`. A notice whose `op_id` is in this ledger is this browser's own\n * echo and is dropped.\n *\n * WHY A TIME WINDOW RATHER THAN A DELETE-ON-MATCH. One write can produce MORE THAN ONE notice:\n * a record write that also moves a column produces a `record` notice and a `field` notice, and\n * a statement touching two Tables produces one per Table. Forgetting an op the first time it\n * came back would make the second notice look like somebody else's and cost the re-read this\n * exists to avoid. So an op is remembered for a window and expires on its own.\n *\n * 🚨 THE WINDOW IS A CORRECTNESS BOUNDARY, NOT A TUNING KNOB, AND IT FAILS IN THE SAFE\n * DIRECTION BY CONSTRUCTION. Too SHORT and a late echo is treated as a stranger's change: one\n * extra read of a page that is already correct — invisible. Too LONG and a stranger's change\n * that happened to reuse our uuid would be dropped — which cannot happen, because it is a v4\n * uuid nobody else has ever seen. The only real cost of a long window is memory, so it is\n * bounded by COUNT as well as by time.\n *\n * WHAT THIS IS NOT. It is not a replacement for the store's optimistic concurrency, and it\n * never decides what is true — a dropped echo means \"I already know about this\", and every\n * path that could be wrong about that (a reconnect, a tab wake, a notice with no `op_id` at\n * all) re-reads through the door as it always did.\n */\nimport { globalSlot } from \"@ai-matrx/kit/global-slot\";\n\nimport type { Uuid } from \"./core/index\";\n\n/** How long an operation stays recognizable as ours. See the header: it fails safe both ways. */\nconst REMEMBER_MS = 30_000;\n\n/** A ceiling so a long-lived tab that writes constantly cannot grow this without bound. */\nconst REMEMBER_MAX = 500;\n\n/**\n * One client's memory of its own operations. `mint()` names a write and remembers it; `isOwn(opId)`\n * answers whether a notice is that write's echo.\n *\n * OWN-WRITE DETECTION IS PER CLIENT INSTANCE. Two setups in ONE process (a server holding two\n * identities, a worker beside a UI) must hear each other: a realm-wide ledger made A's write \"ours\" to\n * B as well, and B dropped it as an echo (2026-10-08, the README proof). `createRecords` gives every\n * setup its own ledger and hands it to its client, its entity port and its live-changes port.\n */\nexport interface OpLedger {\n  mint(): Uuid;\n  isOwn(opId: string | null | undefined): boolean;\n  /** Test seam: forget everything. */\n  clear(): void;\n  /** Test seam: how many operations are currently remembered. */\n  readonly size: number;\n}\n\nfunction ledgerOver(ours: Map<string, number>): OpLedger {\n  function trim(now: number): void {\n    // A Map iterates in insertion order and ids are minted in time order, so the first entry\n    // that is still inside the window means every entry after it is too.\n    for (const [id, at] of ours) {\n      if (now - at <= REMEMBER_MS) break;\n      ours.delete(id);\n    }\n    // Then the ceiling, oldest first, for a tab that writes faster than the window expires.\n    while (ours.size > REMEMBER_MAX) {\n      const oldest = ours.keys().next();\n      if (oldest.done === true) break;\n      ours.delete(oldest.value);\n    }\n  }\n  return {\n    mint() {\n      const id = crypto.randomUUID();\n      const now = Date.now();\n      ours.set(id, now);\n      trim(now);\n      return id as Uuid;\n    },\n    isOwn(opId) {\n      if (!opId) return false;\n      const at = ours.get(opId);\n      if (at === undefined) return false;\n      if (Date.now() - at > REMEMBER_MS) {\n        ours.delete(opId);\n        return false;\n      }\n      return true;\n    },\n    clear() {\n      ours.clear();\n    },\n    get size() {\n      return ours.size;\n    },\n  };\n}\n\n/** A ledger of one client's own: hand the SAME one to the client that writes and the port that listens. */\nexport function createOpLedger(): OpLedger {\n  return ledgerOver(new Map<string, number>());\n}\n\n/**\n * THE REALM'S DEFAULT LEDGER, IN A GLOBAL SLOT — for hosts that mount one client per realm (a browser\n * tab) and never name a ledger. Every section of the built package (root, core, react, realtime, data,\n * typed-table) carries its own copy of this module, and the ESM and CJS builds are two more graphs; a\n * module-level Map split it so `records/core` minted in one and `records/realtime` checked another — own\n * writes came back as strangers' changes (2026-10-08). Guarded on the packed tarball by\n * scripts/check-shared-state.mjs.\n */\nexport const defaultOpLedger: OpLedger = ledgerOver(globalSlot(\"ai-matrx.records.op-ledger\", () => new Map<string, number>()));\n\n/**\n * Mint the id for one client operation and remember it as ours (the realm's default ledger).\n *\n * ONE CALL IS ONE OPERATION. A fifty-row paste through `recordWriteMany` is ONE op id, because\n * the store announces one statement once — and it REFUSES a batch carrying two different ones\n * by name, for exactly that reason.\n */\nexport function mintOpId(): Uuid {\n  return defaultOpLedger.mint();\n}\n\n/**\n * Is this notice the echo of a write this realm's default ledger made?\n *\n * `undefined`/`null` is NOT ours and never has been: a notice with no `op_id` came from a\n * server-side write, an agent tool, another client, or a store older than this mechanism —\n * all of which are changes this browser has not seen and must read.\n */\nexport function isOwnOp(opId: string | null | undefined): boolean {\n  return defaultOpLedger.isOwn(opId);\n}\n\n/** Test seam: forget everything. Never called by product code. */\nexport function forgetAllOps(): void {\n  defaultOpLedger.clear();\n}\n\n/** Test seam: how many operations are currently remembered. */\nexport function rememberedOpCount(): number {\n  return defaultOpLedger.size;\n}\n","// src/port/port.ts — @ai-matrx/records/entity\n//\n// THE HOST'S DATAPORT FOR ENTITY ALIASES (Applets CONTRACTS §4; PHASE-B-APPLETS U5, read-only).\n//\n// One port per mounted Applet, scoped to the aliases its record declares: `{kind:\"entity\", token}`.\n// Every call goes through the store's entity doors under the signed-in person's seat — the store\n// decides what she may see; nothing here widens or narrows it.\n//\n//   · sources  — canCreate / canUpdate are `entity_columns`' own answer for the person.\n//   · columns  — live: platform columns plus the organizations' custom fields (`origin`), the identity\n//                columns left to `_id` / `_version` / `_organization_id`.\n//   · list     — KEYSET: the cursor is the door's `next_after`; the lane defaults to the type's own\n//                landing lane (decided by the door, never here); `org` is a filter, never a lock.\n//   · get      — by id, through the same door every list row opens through. Every id asked in the same\n//                tick (the engine re-reading the rows a notice named) is ONE `entity_get(ids)`.\n//   · create   — `entity_insert` into the organization the HOST names (`activeOrganizationId()`), never\n//                guessed; with none, refused `organization_required` before anything is sent.\n//   · update   — `entity_update` with the `baseVersion` the person saw; a link (`EntityRef[]`) goes back\n//                as its id, `_custom` as `{key: value}`. Stale → `stale_write` with the store's sentence.\n//   · archive / restore — `entity_archive` / `entity_unarchive` (on these types, the trash).\n//                Every write mints an op id (`mintOpId`) and sends it as header `x-matrx-op-id`, so the\n//                notice of the writer's own change comes back marked and is dropped.\n//   · subscribe — LIVE (U6): `rows:<alias>` hears the organization topics `mx:entity-org:<org>:<token>`\n//                through the host's `realtime` (core/realtime.ts). An alias with an organization hears\n//                that one; otherwise the active organization, then the organizations of the rows this\n//                port has handed out (most rows first), then the person's other memberships — capped by\n//                knob entity_data.realtime_max_org_topics. `{ids}` names rows to re-read; `{ids: null}`\n//                re-reads all. With no `realtime` bound it says so out loud and stays a no-op.\n\nimport { isUuidShape } from \"@ai-matrx/kit/uuid\";\nimport type {\n  Column,\n  DataPortEventName,\n  DataSource,\n  HostDataPort,\n  Page,\n  Query,\n  Row,\n  RowsEvent,\n  Uuid,\n  Values,\n} from \"../../data\";\nimport { defaultOpLedger, type OpLedger } from \"../../ops\";\nimport type { RecordsResult } from \"../../results\";\nimport { createEntityClient, type EntityClient } from \"../core/client\";\nimport { refusal } from \"../core/errors\";\nimport { DEFAULT_MAX_ORG_TOPICS, orderOrganizationTopics, type EntityRealtime } from \"../core/realtime\";\nimport type { EntityColumnsAnswer, EntityGetAnswer, EntityWriteAnswer, EntityWireRow } from \"../core/types\";\nimport { toWire } from \"../core/wire\";\nimport { toColumns, toRow } from \"./rows\";\n\n/** An alias as the Applet record declares it for an entity: one token (a `platform.entity_types` word). */\nexport interface EntityAlias {\n  kind: \"entity\";\n  token: string;\n  /** Whose custom fields `columns()` reads. Left out: every organization the person belongs to. */\n  organizationId?: Uuid;\n  /** Shown in `sources()`; the type's own name when left out. */\n  label?: string;\n}\n\nexport interface CreateEntityDataPortOptions {\n  /** A client from `createEntityClient` … */\n  client?: EntityClient;\n  /** … or the supabase-js client (or `rpc` source) to build one from. Give one of the two. */\n  dataSource?: unknown;\n  aliases: Readonly<Record<string, EntityAlias>>;\n  /**\n   * TOKEN-FIRST (the `/react` layer): an alias nobody declared is read as a type token —\n   * `list(\"party\")` is `{kind:\"entity\", token:\"party\"}`. `sources()` still lists only the declared\n   * aliases. Off by default: an Applet's port answers only what its record declares.\n   */\n  tokensAreAliases?: boolean;\n  /**\n   * The active organization (CONTRACTS §4: `viewer().activeOrganizationId`), read at the moment it is\n   * needed: where `create` saves, and the first live topic joined. The host's own answer, never guessed;\n   * null/undefined means none is chosen and `create` is refused `organization_required`.\n   */\n  activeOrganizationId?: () => Uuid | null | undefined;\n  /** A fixed active organization, for a host whose port lives no longer than its choice. `activeOrganizationId` wins. */\n  organization?: Uuid | null;\n  /** The host's live-notice layer (`createEntityRealtime`). Left out, lists are as fresh as their last read. */\n  realtime?: EntityRealtime;\n  /** This port's own-write memory (`createOpLedger()`); absent ⇒ the realm's default ledger. */\n  opLedger?: OpLedger;\n}\n\n/** A value as rows carry it → as the write doors take it: a link (`EntityRef[]` or one ref) becomes its id. */\nexport function toWireValue(value: unknown): unknown {\n  if (isRef(value)) return value.id;\n  if (Array.isArray(value) && value.length > 0 && value.every(isRef)) {\n    // One link is one id; none is null; several are sent as ids and the door refuses a one-record column by name.\n    return value.length === 1 ? (value[0] as { id: string }).id : value.map((ref) => (ref as { id: string }).id);\n  }\n  return value;\n}\n\nfunction isRef(value: unknown): value is { token: string; id: string } {\n  return value !== null && typeof value === \"object\" && !Array.isArray(value)\n    && typeof (value as { token?: unknown }).token === \"string\" && typeof (value as { id?: unknown }).id === \"string\";\n}\n\n/** `Values` → the doors' `{column: value, _custom: {key: value}}`: links back to ids at both levels. */\nexport function toWireValues(values: Values): Record<string, unknown> {\n  const out: Record<string, unknown> = {};\n  for (const [key, value] of Object.entries(values)) {\n    if (value === undefined) continue;\n    if (key === \"_custom\" && value && typeof value === \"object\" && !Array.isArray(value)) {\n      out._custom = Object.fromEntries(Object.entries(value as Record<string, unknown>).filter(([, v]) => v !== undefined).map(([k, v]) => [k, toWireValue(v)]));\n      continue;\n    }\n    // A link column emptied in a grid arrives as [] and means \"no link\".\n    out[key] = Array.isArray(value) && value.length === 0 && key !== \"_custom\" ? null : toWireValue(value);\n  }\n  return out;\n}\n\n/** A type as the person may use it: its name and whether she may add or change rows (`entity_columns`' own answer). */\nexport interface EntityTypeFacts {\n  token: string;\n  label: string;\n  canCreate: boolean;\n  canUpdate: boolean;\n}\n\n/** The host's entity port: the DataPort, plus `describe` for a token-first screen that has no `sources()` entry. */\nexport interface EntityDataPort extends HostDataPort {\n  /** The type behind an alias, from the same one `entity_columns` read `columns()` uses. */\n  describe(alias: string): Promise<RecordsResult<EntityTypeFacts>>;\n}\n\nexport function createEntityDataPort(options: CreateEntityDataPortOptions): EntityDataPort {\n  const client: EntityClient = options.client ?? createEntityClient({ dataSource: options.dataSource });\n  const ledger = options.opLedger ?? defaultOpLedger;\n  const activeOrganization = (): Uuid | null => (options.activeOrganizationId ? options.activeOrganizationId() : options.organization) ?? null;\n  /** Ids asked by `get` in this tick, per alias: answered by one `entity_get`. */\n  const gets = new Map<string, Map<Uuid, ((answer: RecordsResult<Row | null>) => void)[]>>();\n  const aliases = options.aliases;\n  const shapes = new Map<string, Promise<RecordsResult<EntityColumnsAnswer>>>();\n  let warnedNotLive = false;\n  /** Which organization each row this port handed out belongs to, per alias: the \"held rows\" topic order. */\n  const held = new Map<string, Map<Uuid, Uuid>>();\n  const replans = new Map<string, Set<() => void>>();\n  let memberships: Promise<Uuid[] | null> | null = null;\n  let maxOrgTopics: Promise<number> | null = null;\n\n  function hold(alias: string, rows: readonly { id?: unknown; organization_id?: unknown }[]) {\n    const byId = held.get(alias) ?? new Map<Uuid, Uuid>();\n    held.set(alias, byId);\n    const before = new Set(byId.values());\n    for (const r of rows) {\n      if (typeof r.id === \"string\" && typeof r.organization_id === \"string\") byId.set(r.id, r.organization_id);\n    }\n    // A row from an organization this alias did not hold yet may move it into the joined topics.\n    if ([...byId.values()].some((org) => !before.has(org))) for (const replan of replans.get(alias) ?? []) replan();\n  }\n\n  function heldCounts(alias: string): Map<Uuid, number> {\n    const counts = new Map<Uuid, number>();\n    for (const org of held.get(alias)?.values() ?? []) counts.set(org, (counts.get(org) ?? 0) + 1);\n    return counts;\n  }\n\n  function membershipsOnce(): Promise<Uuid[] | null> {\n    memberships ??= client.memberOrganizations().then((answer) => {\n      if (answer.ok) return answer.data;\n      memberships = null; // a refusal is never kept for the next asker\n      console.warn(`[@ai-matrx/records/entity] Could not read your organizations for live updates: ${answer.error.message}`);\n      return null;\n    });\n    return memberships;\n  }\n\n  function maxOrgTopicsOnce(): Promise<number> {\n    maxOrgTopics ??= client.knob({ key: \"realtime_max_org_topics\", organizationId: activeOrganization() }).then((answer) => {\n      const value = answer.ok ? Number(answer.data) : Number.NaN;\n      if (Number.isFinite(value) && value >= 0) return value;\n      console.warn(`[@ai-matrx/records/entity] knob entity_data.realtime_max_org_topics did not resolve; joining at most ${DEFAULT_MAX_ORG_TOPICS} organizations.`);\n      return DEFAULT_MAX_ORG_TOPICS;\n    });\n    return maxOrgTopics;\n  }\n\n  const tokenBindings = new Map<string, EntityAlias>();\n  function bindingOf(alias: string): EntityAlias | null {\n    if (Object.prototype.hasOwnProperty.call(aliases, alias)) return aliases[alias]!;\n    if (!options.tokensAreAliases || !/^[a-z][a-z0-9_]*$/.test(alias)) return null;\n    let bound = tokenBindings.get(alias);\n    if (!bound) {\n      bound = { kind: \"entity\", token: alias };\n      tokenBindings.set(alias, bound);\n    }\n    return bound;\n  }\n\n  function noSuchAlias(alias: string) {\n    return refusal(\"not_found\", `This Applet has no data source called \"${alias}\".`, \"Use one of the aliases sources() lists.\");\n  }\n\n  /** One read of a type's columns per port; a refusal is never kept for the next asker. */\n  function shapeOf(alias: string, binding: EntityAlias): Promise<RecordsResult<EntityColumnsAnswer>> {\n    let held = shapes.get(alias);\n    if (!held) {\n      held = client.columns({ token: binding.token, organizationId: binding.organizationId ?? null }).then((answer) => {\n        if (!answer.ok) shapes.delete(alias);\n        return answer;\n      });\n      shapes.set(alias, held);\n    }\n    return held;\n  }\n\n  /** Ask for one row; every id asked for the alias before the tick ends goes in the same `entity_get`. */\n  function getCoalesced(alias: string, token: string, id: Uuid): Promise<RecordsResult<Row | null>> {\n    return new Promise((resolve) => {\n      let batch = gets.get(alias);\n      if (!batch) {\n        batch = new Map();\n        gets.set(alias, batch);\n        const asked = batch;\n        queueMicrotask(() => {\n          gets.delete(alias);\n          void flushGets(alias, token, asked);\n        });\n      }\n      const waiting = batch.get(id) ?? [];\n      waiting.push(resolve);\n      batch.set(id, waiting);\n    });\n  }\n\n  async function flushGets(alias: string, token: string, asked: Map<Uuid, ((answer: RecordsResult<Row | null>) => void)[]>) {\n    const answer: RecordsResult<EntityGetAnswer> = await client.get({ token, ids: [...asked.keys()] });\n    if (answer.ok) hold(alias, answer.data.rows);\n    const byId = new Map<string, EntityWireRow>(answer.ok ? answer.data.rows.map((r) => [r.id, r]) : []);\n    for (const [id, waiting] of asked) {\n      // A row in the trash is not a row of this port: the DataPort's lists are active rows only (a Query has no\n      // archived option), so a re-read that finds one trashed answers null and the engine takes it off the list.\n      // `entity_get` itself opens trashed rows by id (`_state.archived`) for screens that read the doors directly.\n      const found = byId.get(id);\n      const wire = found && (found[\"_state\"] as { archived?: unknown } | undefined)?.archived === true ? undefined : found;\n      const result: RecordsResult<Row | null> = answer.ok ? { ok: true, data: wire ? toRow(wire) : null } : answer;\n      for (const resolve of waiting) resolve(result);\n    }\n  }\n\n  /** The one row a write door read back (with its new `version`). */\n  function readBack(alias: string, answer: RecordsResult<EntityWriteAnswer>, what: string): RecordsResult<Row> {\n    if (!answer.ok) return answer;\n    hold(alias, answer.data.rows);\n    const wire = answer.data.rows[0];\n    if (!wire) {\n      return refusal(\n        \"not_found\",\n        `${what} was saved, but you cannot open it now, so it is not shown here.`,\n        \"The row is in the store; who may open it decides whether it appears in this list.\",\n      );\n    }\n    return { ok: true, data: toRow(wire) };\n  }\n\n  function done(answer: RecordsResult<EntityWriteAnswer>): RecordsResult<void> {\n    return answer.ok ? { ok: true, data: undefined } : answer;\n  }\n\n  return {\n    async sources() {\n      const out: DataSource[] = [];\n      for (const [alias, binding] of Object.entries(aliases)) {\n        const shape = await shapeOf(alias, binding);\n        if (!shape.ok) return shape;\n        out.push({\n          alias,\n          label: binding.label ?? shape.data.label ?? alias,\n          kind: \"entity\",\n          canCreate: Boolean(shape.data.can_create),\n          canUpdate: Boolean(shape.data.can_update),\n        });\n      }\n      return { ok: true, data: out };\n    },\n\n    async describe(alias) {\n      const binding = bindingOf(alias);\n      if (!binding) return noSuchAlias(alias);\n      const shape = await shapeOf(alias, binding);\n      if (!shape.ok) return shape;\n      return {\n        ok: true,\n        data: {\n          token: binding.token,\n          label: binding.label ?? shape.data.label ?? binding.token,\n          canCreate: Boolean(shape.data.can_create),\n          canUpdate: Boolean(shape.data.can_update),\n        },\n      };\n    },\n\n    async columns(alias) {\n      const binding = bindingOf(alias);\n      if (!binding) return noSuchAlias(alias);\n      const shape = await shapeOf(alias, binding);\n      return shape.ok ? { ok: true, data: toColumns(shape.data.columns) satisfies Column[] } : shape;\n    },\n\n    async list(alias, q: Query = {}, cursor) {\n      const binding = bindingOf(alias);\n      if (!binding) return noSuchAlias(alias);\n      // A custom field's key is only known from the columns; ask for them only when the query names a column.\n      let customKeys: ReadonlySet<string> = new Set();\n      if ((q.where && q.where.length > 0) || (q.sort && q.sort.length > 0)) {\n        const shape = await shapeOf(alias, binding);\n        if (!shape.ok) return shape;\n        customKeys = new Set(shape.data.columns.filter((c) => c.origin === \"custom\").map((c) => c.key));\n      }\n      const wire = toWire(q, customKeys);\n      // A SOURCE DECLARED IN ONE ORGANIZATION reads that organization only (an Applet's own source scope,\n      // CONTRACTS v2.11): the alias's organization replaces any per-query org filter — it is the source's\n      // definition, not the person's list filter. Without one, the query's filter (or none) stands.\n      if (binding.organizationId) wire.scope = { ...wire.scope, organization_id: binding.organizationId };\n      // The archive (`archived: true`) is the same door's own archived lane, never a client-side sieve.\n      const answer = await client.list({ token: binding.token, ...wire, after: cursor ?? null, ...(q.archived === true ? { archived: \"archived\" as const } : {}) });\n      if (!answer.ok) return answer;\n      const { data } = answer;\n      if (data.sort_ignored.length > 0) {\n        // SAID OUT LOUD: the door keeps one sort key today; the rest were dropped, not silently reordered.\n        console.warn(`[@ai-matrx/records/entity] \"${alias}\" sorts by one column for now; ignored: ${data.sort_ignored.join(\", \")}.`);\n      }\n      hold(alias, data.rows);\n      const page: Page = {\n        rows: data.rows.map(toRow),\n        // A count that stopped at the store's cap is a floor, not a count: unknown beats a wrong number.\n        total: data.total === null || data.total === undefined || data.total_is_capped ? null : data.total,\n        cursor: data.has_more ? data.next_after : null,\n      };\n      return { ok: true, data: page };\n    },\n\n    async get(alias, id: Uuid) {\n      const binding = bindingOf(alias);\n      if (!binding) return noSuchAlias(alias);\n      if (!isUuidShape(id)) return refusal(\"invalid_argument\", `\"${String(id)}\" is not a row id.`);\n      return getCoalesced(alias, binding.token, id);\n    },\n\n    async create(alias, values: Values) {\n      const binding = bindingOf(alias);\n      if (!binding) return noSuchAlias(alias);\n      // A source declared in one organization saves there; otherwise the host's active organization.\n      const organizationId = binding.organizationId ?? activeOrganization();\n      if (!organizationId) {\n        // MX002, said before anything is sent: a new row's organization is the person's choice, never ours.\n        return refusal(\n          \"organization_required\",\n          \"Choose the organization this new record belongs to.\",\n          \"Pick an organization, then add the row again. Nothing was saved.\",\n        );\n      }\n      const answer = await client.insert({ token: binding.token, organizationId, rows: [toWireValues(values)], opId: ledger.mint() });\n      return readBack(alias, answer, \"The new row\");\n    },\n\n    async update(alias, id: Uuid, patch: Values, baseVersion: number) {\n      const binding = bindingOf(alias);\n      if (!binding) return noSuchAlias(alias);\n      if (!isUuidShape(id)) return refusal(\"invalid_argument\", `\"${String(id)}\" is not a row id.`);\n      const answer = await client.update({ token: binding.token, id, baseVersion, patch: toWireValues(patch), opId: ledger.mint() });\n      return readBack(alias, answer, \"The change\");\n    },\n\n    async archive(alias, id: Uuid) {\n      const binding = bindingOf(alias);\n      if (!binding) return noSuchAlias(alias);\n      if (!isUuidShape(id)) return refusal(\"invalid_argument\", `\"${String(id)}\" is not a row id.`);\n      return done(await client.archive({ token: binding.token, ids: [id], opId: ledger.mint() }));\n    },\n\n    async restore(alias, id: Uuid) {\n      const binding = bindingOf(alias);\n      if (!binding) return noSuchAlias(alias);\n      if (!isUuidShape(id)) return refusal(\"invalid_argument\", `\"${String(id)}\" is not a row id.`);\n      return done(await client.unarchive({ token: binding.token, ids: [id], opId: ledger.mint() }));\n    },\n\n    subscribe(event: DataPortEventName, listener: (event: RowsEvent) => void) {\n      const alias = event.startsWith(\"rows:\") ? event.slice(5) : null;\n      const binding = alias ? bindingOf(alias) : null;\n      if (!alias || !binding) {\n        throw new Error(`DataPort.subscribe: \"${event}\" is not an event this Applet's port carries. Use rows:<alias>.`);\n      }\n      const realtime = options.realtime;\n      if (!realtime) {\n        // NOT LIVE, SAID OUT LOUD: a host that bound no realtime layer goes stale, and the console says why.\n        if (!warnedNotLive) {\n          warnedNotLive = true;\n          console.warn(\"[@ai-matrx/records/entity] This host bound no realtime layer, so other people's changes appear on the next read.\");\n        }\n        return () => {};\n      }\n\n      let stopped = false;\n      let joined: string[] = [];\n      let stopLive: (() => void) | null = null;\n      const sink = { rows: (ids: string[] | null) => listener({ ids: ids === null ? null : [...ids] }) };\n\n      const plan = async () => {\n        const organizationIds = binding.organizationId\n          ? [binding.organizationId]\n          : orderOrganizationTopics({\n              active: activeOrganization(),\n              held: heldCounts(alias),\n              members: await membershipsOnce(),\n              max: await maxOrgTopicsOnce(),\n            });\n        if (stopped) return;\n        if (organizationIds.length === joined.length && organizationIds.every((org, i) => org === joined[i])) return;\n        // Join the new set before leaving the old, so a topic in both never closes and reopens.\n        const previous = stopLive;\n        joined = organizationIds;\n        stopLive = realtime.subscribe({ token: binding.token, organizationIds }, sink);\n        previous?.();\n      };\n      const replan = () => void plan();\n      const set = replans.get(alias) ?? new Set<() => void>();\n      replans.set(alias, set);\n      set.add(replan);\n      replan();\n\n      return () => {\n        stopped = true;\n        set.delete(replan);\n        stopLive?.();\n        stopLive = null;\n      };\n    },\n  };\n}\n\n/**\n * THE PORT A SERVER ASKS THROUGH, AND THE PAGE READS THROUGH WHILE IT HYDRATES (lane SEED-ENTITY).\n * One construction for both, so the doors' arguments are the same on either side: a token is its own\n * alias, nothing is bound to an organization, and nothing is live. `dataSource` is the person's own\n * (server), a recording one, or one that answers from a page seed.\n */\nexport function createSeedPort(dataSource: unknown): EntityDataPort {\n  return createEntityDataPort({ client: createEntityClient({ dataSource }), aliases: {}, tokensAreAliases: true, activeOrganizationId: () => null });\n}\n","// src/port/rows.ts — @ai-matrx/records/entity\n//\n// ROW AND COLUMN SHAPING (Applets CONTRACTS §0): the door's wire row → `Row`, its columns → `Column`.\n// Pure; every case is pinned against recorded door answers (`__fixtures__`).\n\nimport type { Column, EntityRef, Row } from \"../../data\";\nimport type { EntityColumnWire, EntityWireRow } from \"../core/types\";\n\n/** The door's identity columns become the runtime's own underscore keys on a Row; they are never plain columns. */\nconst IDENTITY_COLUMNS = new Set([\"id\", \"version\", \"organization_id\"]);\n/** The compiler's own presentation markers; not data. */\nconst PRESENTATION_KEYS = new Set([\"_state\", \"_k\"]);\n\nfunction isRefList(value: unknown): value is { token: string; id: string; label?: unknown }[] {\n  return (\n    Array.isArray(value) &&\n    value.length > 0 &&\n    value.every((item) => item !== null && typeof item === \"object\" && typeof (item as { token?: unknown }).token === \"string\" && typeof (item as { id?: unknown }).id === \"string\")\n  );\n}\n\n/** Every link reads as `EntityRef[]` — `{token, id, label}`, the label null when the store had no words for it. */\nexport function toRefs(value: unknown): EntityRef[] {\n  if (!isRefList(value)) return [];\n  return value.map<EntityRef>((item) => ({ token: item.token, id: item.id, label: typeof item.label === \"string\" ? item.label : null }));\n}\n\nexport function toRow(wire: EntityWireRow): Row {\n  const row: Row = {\n    _id: wire.id,\n    _version: wire.version,\n    _organization_id: wire.organization_id,\n    _custom: wire._custom && typeof wire._custom === \"object\" ? { ...wire._custom } : {},\n  };\n  for (const [key, value] of Object.entries(wire)) {\n    if (IDENTITY_COLUMNS.has(key) || PRESENTATION_KEYS.has(key) || key === \"_custom\") continue;\n    row[key] = isRefList(value) ? toRefs(value) : value === undefined ? null : value;\n  }\n  return row;\n}\n\nexport function toColumn(wire: EntityColumnWire): Column {\n  const column: Column = {\n    key: wire.key,\n    label: wire.label || wire.key,\n    type: wire.type,\n    origin: wire.origin === \"custom\" ? \"custom\" : \"platform\",\n    required: Boolean(wire.required),\n    readOnly: Boolean(wire.readOnly),\n  };\n  if (wire.choices && wire.choices.length > 0) column.choices = [...wire.choices];\n  if (wire.linksTo && wire.linksTo.length > 0) column.linksTo = [...wire.linksTo];\n  return column;\n}\n\n/** The columns a person sees: the door's own list minus the identity columns a Row carries as `_id` / `_version` / `_organization_id`. */\nexport function toColumns(wire: readonly EntityColumnWire[]): Column[] {\n  return wire.filter((c) => !IDENTITY_COLUMNS.has(c.key)).map(toColumn);\n}\n"],"mappings":"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","names":["held"]}