@ai-matrx/records 0.99.32 → 0.99.33

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.
Files changed (62) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/dist/{client-CrwedBYU.d.ts → client-CSfkP7Xf.d.ts} +5 -74
  3. package/dist/{client-D1EwyWfh.d.cts → client-jKf1Z-kp.d.cts} +5 -74
  4. package/dist/core/index.cjs +149 -105
  5. package/dist/core/index.cjs.map +1 -1
  6. package/dist/core/index.d.cts +9 -331
  7. package/dist/core/index.d.ts +9 -331
  8. package/dist/core/index.js +149 -105
  9. package/dist/core/index.js.map +1 -1
  10. package/dist/data/index.cjs +280 -236
  11. package/dist/data/index.cjs.map +1 -1
  12. package/dist/data/index.d.cts +3 -2
  13. package/dist/data/index.d.ts +3 -2
  14. package/dist/data/index.js +280 -236
  15. package/dist/data/index.js.map +1 -1
  16. package/dist/{declareTable-CC5rTTIA.d.ts → declareTable-0emxEewn.d.ts} +1 -1
  17. package/dist/{declareTable-BIIt0Wqt.d.cts → declareTable-800bwUn3.d.cts} +1 -1
  18. package/dist/door-call/index.cjs +1287 -0
  19. package/dist/door-call/index.cjs.map +1 -0
  20. package/dist/door-call/index.d.cts +20 -0
  21. package/dist/door-call/index.d.ts +20 -0
  22. package/dist/door-call/index.js +1264 -0
  23. package/dist/door-call/index.js.map +1 -0
  24. package/dist/{doors-D1yAs0a0.d.cts → doors-BgjRUdxw.d.cts} +13 -1
  25. package/dist/{doors-D2z3kH2i.d.ts → doors-D7_jEKtg.d.ts} +13 -1
  26. package/dist/index.d.cts +5 -4
  27. package/dist/index.d.ts +5 -4
  28. package/dist/{objectOrganization-DazBoDAq.d.cts → objectOrganization-B5YFGVUB.d.cts} +1 -1
  29. package/dist/{objectOrganization-D1ox3gUx.d.ts → objectOrganization-DozoVIxS.d.ts} +1 -1
  30. package/dist/pickListDoors-C-_eAEGL.d.cts +135 -0
  31. package/dist/pickListDoors-DgWVnNRI.d.ts +135 -0
  32. package/dist/questions/index.d.cts +3 -2
  33. package/dist/questions/index.d.ts +3 -2
  34. package/dist/react/index.cjs +363 -319
  35. package/dist/react/index.cjs.map +1 -1
  36. package/dist/react/index.d.cts +37 -22
  37. package/dist/react/index.d.ts +37 -22
  38. package/dist/react/index.js +363 -319
  39. package/dist/react/index.js.map +1 -1
  40. package/dist/scopes/index.cjs +7 -0
  41. package/dist/scopes/index.cjs.map +1 -1
  42. package/dist/scopes/index.d.cts +2 -2
  43. package/dist/scopes/index.d.ts +2 -2
  44. package/dist/scopes/index.js +7 -0
  45. package/dist/scopes/index.js.map +1 -1
  46. package/dist/setup/index.cjs +289 -245
  47. package/dist/setup/index.cjs.map +1 -1
  48. package/dist/setup/index.d.cts +4 -3
  49. package/dist/setup/index.d.ts +4 -3
  50. package/dist/setup/index.js +289 -245
  51. package/dist/setup/index.js.map +1 -1
  52. package/dist/table-logic-BPquabNN.d.ts +328 -0
  53. package/dist/table-logic-CTh6lwaq.d.cts +328 -0
  54. package/dist/typed-table/index.cjs +280 -236
  55. package/dist/typed-table/index.cjs.map +1 -1
  56. package/dist/typed-table/index.d.cts +4 -3
  57. package/dist/typed-table/index.d.ts +4 -3
  58. package/dist/typed-table/index.js +280 -236
  59. package/dist/typed-table/index.js.map +1 -1
  60. package/dist/views/index.d.cts +3 -2
  61. package/dist/views/index.d.ts +3 -2
  62. package/package.json +13 -3
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/supabase.ts","../../src/results.ts","../../src/core/pgError.ts","../../src/core/primedBundle.ts","../../src/core/doorCall.ts","../../src/core/pickListDoors.ts","../../src/scopes/types.ts","../../src/scopes/codec.ts","../../src/scopes/rules.ts","../../src/scopes/doors.ts","../../src/core/storeDoors.ts","../../src/core/table-logic.ts","../../src/objectOrganization.ts","../../src/door-call/index.ts"],"sourcesContent":["// 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 honour `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/results.ts — @ai-matrx/records\n//\n// THE NEVER-THROW RESULT ENVELOPE, and the refusal vocabulary behind it.\n//\n// This package's whole posture toward the store is in one sentence: THE CLIENT\n// MIRRORS THE STORE'S CONTRACT AND NEVER RE-IMPLEMENTS A RULE THE STORE\n// ENFORCES. When the store refuses, the client hands back the store's OWN\n// message, the store's OWN hint and the store's OWN SQLSTATE, under a code a\n// screen can branch on. It never rewrites the sentence, never swallows it, and\n// never invents a friendlier one — the store's refusals were written to be read\n// by a person, and a client that paraphrases them is lying about what happened.\n\nimport type { PerValueAccessWord } from \"./vocabulary\";\nimport type { Uuid } from \"./record\";\n\n/**\n * What KIND of refusal it was. The mapping from SQLSTATE to code lives in\n * `/core`, and it is checked against `STORE_REFUSAL_CODES` — the list of every\n * SQLSTATE the store's own bodies raise, generated from the live catalogue. A\n * code the store can raise and this union cannot name is a hole, and the\n * real-door suite fails on it.\n */\nexport type RecordsErrorCode =\n /** `PT409` — somebody else's write won. The record clock moved under you. */\n | \"stale_write\"\n /**\n * The call needs an organization and none was carried (the platform's `organization_required`; the entity\n * doors' MX002). Never resolved by guessing one: the person is shown their memberships and picks.\n */\n | \"organization_required\"\n /** `42501` — a door. Either the schema is revoked, or the store is switched off, or this principal may not pass. */\n | \"door\"\n /** `23514` — a Rule, a shape guard, or a validation the store enforces refused it. */\n | \"refused_by_rule\"\n /**\n * `22004` / `22023` / `22P02` — the call itself was malformed: a missing id, a\n * patch that is not an object, or a value that does not fit the type the\n * store holds for that Field. The store's own message names the value and the\n * type it could not be read as.\n */\n | \"invalid_argument\"\n /** `02000` — the record is not here (deleted, never existed, or another organization's). */\n | \"not_found\"\n /** `23503` — something it points at is not there. */\n | \"missing_reference\"\n /** `23505` — that thing is already here. */\n | \"already_exists\"\n /** `0A000` — the store does not do this yet, and says which part. */\n | \"not_supported\"\n /** `53400` / `22012` — the store ran out of something, or the arithmetic could not be done. */\n | \"store_limit\"\n /**\n * `40001` — the read-access snapshot this connection carries is older than a\n * write the reader has already observed, so the store refused to answer at\n * all rather than hand back something they just lost. Retry on a fresh\n * connection; it is the one refusal in this list that is worth repeating.\n */\n | \"stale_read\"\n /**\n * `57014` — the store cancelled the statement at its own timeout. Nothing was\n * refused on its merits and nothing was written; the same call can succeed on\n * a smaller page or a quieter moment. With `stale_read`, one of the only two\n * refusals in this list worth repeating.\n */\n | \"timed_out\"\n /**\n * THE DOOR THAT DOES NOT EXIST YET. Not an error condition in the database —\n * this package asked for a door that is not in the live catalogue, so it\n * refused to guess. `door_absent` always names the door and the lane that\n * owns it; it is never a silent no-op and never an empty list.\n */\n | \"door_absent\"\n /**\n * `PGRST202` / `PGRST205` — PostgREST could not find the function or the\n * schema. The database this client is pointed at is not serving the record\n * store: the schema is not exposed, or the grants are not there.\n */\n | \"store_not_served\"\n /**\n * `PT428` — the move was not refused and it did not happen: a stage gate whose\n * `on_fail` is `require_approval` filed a request with the people who can\n * answer it, and left the record exactly where it was. The store's own\n * sentence is the gate's own sentence, and the DETAIL carries the approval.\n *\n * It is the one code in this list that is not a failure. A screen that drew it\n * as one would tell somebody their work was rejected when it is being\n * considered; a screen that drew it as success would move the card while\n * somebody is still deciding. `custom.pipeline_move` answers an object on this\n * path rather than raising, so a caller only meets PT428 when the move went\n * through the ORDINARY write door — which is most of them.\n */\n | \"needs_approval\"\n /**\n * THE CALL NEVER REACHED THE STORE. Not a refusal — a transport failure: the\n * browser lost the network, the gateway answered with an HTTP status and no\n * body, the request was cancelled. supabase-js hands these back with an EMPTY\n * `code` (a `FetchError`) or with the HTTP status in it (`\"404\"`, `\"502\"`),\n * neither of which is a SQLSTATE, and until 2026-09-22 they all landed in\n * `internal` — which is the one classification that tells a screen nothing,\n * and which made the package print a sentence about ITSELF to the person\n * (lane TAILS-6). Nothing was written, and the same call can simply be made\n * again, which is what separates it from `internal`.\n */\n | \"unreachable\"\n /** Anything the mapper could not place. It still carries the store's own words. */\n | \"internal\";\n\n/** A refusal, in the store's own words. */\nexport interface RecordsError {\n code: RecordsErrorCode;\n /** THE STORE'S message, verbatim. Never paraphrased. */\n message: string;\n /** THE STORE'S hint, verbatim — this is where the remedy is written. */\n hint?: string;\n /** The SQLSTATE, so a caller can be exact when a code is not exact enough. */\n sqlstate?: string;\n /** Whatever the store put in DETAIL, parsed when it was json. */\n detail?: unknown;\n /**\n * TRUE when this package did not recognise the class it was handed, so a\n * caller can say so instead of reading the silence as \"handled\".\n *\n * 🚨 IT IS A FLAG AND A SEPARATE SENTENCE, NEVER AN APPENDIX TO `hint`\n * (lane TAILS-6, 2026-09-22). `mapPgError` used to append \"@ai-matrx/records\n * did not recognise SQLSTATE … from checklistTemplates\" ONTO `hint`, and\n * `hint` is the field every screen treats as THE REMEDY — the sentence a\n * person is told to act on. So a dropped connection on the Checklists tab\n * showed a plumbing company \"Something went wrong at our end\" over a line\n * about a TypeScript package and a SQLSTATE. A note this package writes about\n * ITSELF is for whoever debugs it and belongs nowhere a person reads.\n */\n unmapped?: boolean;\n /**\n * THIS PACKAGE'S OWN NOTE, for an engineer. Never the store's words and never\n * a person's: screens render it out of sight (a `title` attribute, a\n * screen-reader line) or not at all.\n */\n diagnostic?: string;\n}\n\nexport type RecordsResult<T> = { ok: true; data: T } | { ok: false; error: RecordsError };\n\n/** Narrowing helper for hosts compiled without `strictNullChecks`. */\nexport function isRecordsErr<T>(\n result: RecordsResult<T>,\n): result is { ok: false; error: RecordsError } {\n return result.ok === false;\n}\n\n/**\n * A result's data, or THROW its refusal as an `Error` carrying the store's sentence — for the places\n * a throw is the contract (a `createAsyncThunk` body, a loader whose caller catches and shows it).\n */\nexport function unwrapRecords<T>(result: RecordsResult<T>): T {\n if (result.ok) return result.data;\n throw new Error(result.error.message);\n}\n\nexport const ok = <T>(data: T): RecordsResult<T> => ({ ok: true, data });\nexport const err = <T>(error: RecordsError): RecordsResult<T> => ({ ok: false, error });\n\n/**\n * A `stale_write` carries everything the screen needs to show the conflict\n * rather than a toast: which version you wrote against, which one won, and the\n * value of every field you touched as it stands now. The store builds this and\n * this type is its shape — nothing is reconstructed on the client.\n */\nexport interface StaleWriteDetail {\n expected_version: number;\n current_version: number;\n contested_fields: Record<string, unknown>;\n}\n\n/** The parsed form of a `stale_write`, for `useRecordMutation`'s conflict state. */\nexport interface WriteConflict extends StaleWriteDetail {\n record_id: Uuid;\n /** The store's own sentence — what the screen shows. */\n message: string;\n /** The store's own remedy. */\n hint: string;\n}\n\n/**\n * The structural shape of a PostgREST failure as supabase-js resolves it: a\n * PLAIN OBJECT parsed from the response body, NOT an `Error`. Reading\n * `.message` off `instanceof Error` discards the real database message on every\n * genuine failure.\n */\nexport interface PgError {\n code?: string | null;\n message: string;\n details?: string | null;\n hint?: string | null;\n}\n\n/** What the validation mirror answers: the same sentence the trigger would raise. */\nexport interface PredictedRefusal {\n /** The field key the store would name, when it names one. */\n field_key?: string;\n /** The message the store's own body would raise, word for word. */\n message: string;\n hint?: string;\n /** The store's structured detail, when its refusal carries one (e.g. `{ example }`). */\n detail?: Record<string, unknown>;\n sqlstate: string;\n /**\n * Which of the store's bodies would raise it, so a reader can go and check\n * that this mirror still tells the truth.\n */\n predicted_by: string;\n}\n\n/** VAL-5 / VAL-6, named so a caller can say which word was the problem. */\nexport interface ForbiddenEnvelopeWord {\n field_key: string;\n word: PerValueAccessWord;\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 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 \"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 cancelled 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 cancelled 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/** Map a PostgREST/supabase-js failure into the package's refusal shape. */\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 if (isNotASqlstate(sqlstate)) {\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 recognise 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.\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/primedBundle.ts — A TABLE PAGE'S BUNDLE, ASKED BEFORE THE PAGE'S SCRIPT HAS BOOTED (lane PAGE-BUNDLE-2).\n//\n// THE USE CASE: Dr. Patel's front desk opens \"Visits\" from a link. The server that renders the page\n// already holds her session, so it asks `custom.table_page_bundle` AS HER while the browser is still\n// downloading the page's script, and hands the answer (a promise, streamed) to the page. The records\n// client that mounts a moment later finds it here and asks nothing: its first wave of doors is already\n// answered. Without this the bundle was asked only after the whole app had booted (~1 s on production).\n//\n// HOW IT STAYS THE SAME: the primed answer is exactly what `custom.table_page_bundle` answered for the\n// same organization, Table and view, so `callDoor`'s part-by-part matching (name and every argument)\n// is unchanged. It is used ONCE and only while fresh (PRIMED_TTL_MS); an answer that is an error, or\n// not a bundle, is ignored and the bundle is asked as it always was. A primed answer never turns a\n// refusal into \"empty\": a refusing part is still asked by its own door.\n\n/** What a data source's `rpc` answers for `custom.table_page_bundle` (PostgREST's `{ data, error }`). */\nexport interface PrimedBundleAnswer {\n data: unknown;\n error: unknown;\n}\n\nconst PRIMED_TTL_MS = 15_000;\n\n/**\n * ONE REGISTRY FOR EVERY COPY OF THIS FILE. The package's entries (`/core`, `/react`, `/data`,\n * `/typed-table`) are bundled separately and each carries its own copy of the client, so a module-level\n * Map here would be FOUR maps: the host primes `/core`'s and the `RecordsProvider` (`/react`) never\n * sees it (measured on /data/<table>, 2026-10-07: the bundle was asked again). The registry lives\n * on `globalThis` under one well-known symbol, so every copy reads the same one.\n */\nconst REGISTRY = Symbol.for(\"@ai-matrx/records/primed-table-page-bundles\");\ntype Registry = Map<string, { answer: Promise<PrimedBundleAnswer>; at: number }>;\nfunction registry(): Registry {\n const g = globalThis as unknown as Record<symbol, Registry | undefined>;\n return (g[REGISTRY] ??= new Map());\n}\n\nconst primedKey = (organizationId: string, tableId: string, viewId: string | null | undefined): string =>\n `${organizationId}|${tableId}|${viewId ?? \"\"}`;\n\n/**\n * Hand the records client a table page's bundle that was asked elsewhere (the server render, as the\n * same person). The next records client that opens this Table in this organization uses it instead of\n * asking — once, within PRIMED_TTL_MS.\n */\nexport function primeTablePageBundle(input: {\n organizationId: string;\n tableId: string;\n viewId?: string | null;\n answer: Promise<PrimedBundleAnswer> | PrimedBundleAnswer;\n}): void {\n const answer = Promise.resolve(input.answer).catch((thrown: unknown) => ({ data: null, error: thrown }));\n registry().set(primedKey(input.organizationId, input.tableId, input.viewId), { answer, at: Date.now() });\n}\n\n/** The primed answer for this page, once — or null (none, or stale). */\nexport function takePrimedTablePageBundle(\n organizationId: string | null | undefined,\n tableId: string,\n viewId: string | null | undefined,\n): Promise<PrimedBundleAnswer> | null {\n if (!organizationId) return null;\n const key = primedKey(organizationId, tableId, viewId);\n const primed = registry();\n const held = primed.get(key);\n if (!held) return null;\n primed.delete(key);\n return Date.now() - held.at < PRIMED_TTL_MS ? held.answer : null;\n}\n\n/**\n * A WRITE HAPPENED ON THIS TABLE: its primed page bundle (asked by the server before the write, never\n * used because the page opened from the seed) would answer the next read with the table as it WAS.\n * Forget the Table's (`tableId`), or every one when the write did not name a Table (`null`).\n */\nexport function forgetPrimedTablePageBundlesOf(tableId: string | null): void {\n const primed = registry();\n for (const key of [...primed.keys()]) if (tableId === null || key.split(\"|\")[1] === tableId) primed.delete(key);\n}\n\n/** Tests only: forget every primed answer. */\nexport function forgetPrimedTablePageBundles(): void {\n registry().clear();\n}\n\n/**\n * A RECORD PAGE'S BUNDLE (`custom.record_page_bundle`), asked elsewhere as the same person — the\n * record-page twin of `primeTablePageBundle`, held in the same registry, used once, while fresh.\n */\nexport function primeRecordPageBundle(input: {\n organizationId: string;\n recordId: string;\n answer: Promise<PrimedBundleAnswer> | PrimedBundleAnswer;\n}): void {\n primeTablePageBundle({ organizationId: input.organizationId, tableId: `record:${input.recordId}`, answer: input.answer });\n}\n\n// ─────────────────────────────────────────────────────────────────────────────────────────────\n// ANY DOOR'S ANSWER, ASKED ON THE SERVER, SERVED TO THE BROWSER'S OWN CALL, WHILE IT IS YOUNG (lane SEED-ENTITY)\n//\n// THE USE CASE: a grouped Visits table. Its group counts and its link labels are read by the grid in\n// effects, after the first paint — not in a first pass a seed can suspend. The server asked them too\n// (`askTablePageSeed`), so the provider hands every seeded answer here; the records client's own\n// `callDoor` finds the exact call (door name and every argument) and answers it while it is\n// young (10 s). A call that differs by any argument is asked of the store as always. A write (any door that\n// is not a read) empties the registry, so nothing stale is ever served after a change.\n// ─────────────────────────────────────────────────────────────────────────────────────────────\n\nconst DOOR_REGISTRY = Symbol.for(\"@ai-matrx/records/primed-door-answers\");\ntype DoorRegistry = Map<string, { data: unknown; at: number }>;\nfunction doorRegistry(): DoorRegistry {\n const g = globalThis as unknown as Record<symbol, DoorRegistry | undefined>;\n return (g[DOOR_REGISTRY] ??= new Map());\n}\n\n/** How long a primed door answer stays servable, counted from when the server asked. */\nexport const PRIMED_DOOR_TTL_MS = 10_000;\n\n/** Keep one door's answer (`key` = door name + canonical arguments, as `seedKey` builds it). */\nexport function primeDoorAnswer(key: string, data: unknown, at: number): void {\n doorRegistry().set(key, { data, at });\n}\n\n/**\n * The primed answer to this exact call — or null (none, or older than the window). Served for the whole\n * window, not once: a grid's effect runs again when its rows land (same call, same answer). A write drops it.\n */\nexport function takePrimedDoorAnswer(key: string): { data: unknown } | null {\n const registry = doorRegistry();\n const held = registry.get(key);\n if (!held) return null;\n if (Date.now() - held.at < PRIMED_DOOR_TTL_MS) return { data: held.data };\n registry.delete(key);\n return null;\n}\n\n/**\n * A write happened: nothing primed is trusted any more — or, with `doors`, only what those doors answered\n * (a saved view changes the views and the layout, never a record's value or a count of records).\n */\nexport function dropPrimedDoorAnswers(doors?: readonly string[]): void {\n const registry = doorRegistry();\n if (!doors) {\n registry.clear();\n return;\n }\n for (const key of [...registry.keys()]) if (doors.some((door) => key.startsWith(`${door}|`))) registry.delete(key);\n}\n\n/** Writes that change only how a table is LOOKED AT: they drop these reads, and no others. */\nexport const LOOK_WRITES: Record<string, readonly string[]> = {\n view_declare: [\"views\", \"view_look_read\", \"grid_layout\", \"table_page_bundle\"],\n view_designate: [\"views\", \"view_look_read\", \"grid_layout\", \"table_page_bundle\"],\n view_look_set: [\"views\", \"view_look_read\", \"grid_layout\", \"table_page_bundle\"],\n view_record_order_set: [\"views\", \"view_look_read\", \"grid_layout\", \"table_page_bundle\"],\n};\n\n/**\n * A door that WRITES, by the verbs the store names its writers with. Anything this matches drops the\n * registry; a read that merely looks like a writer only costs a primed answer, never a stale one.\n */\nexport function isWritingDoor(door: string): boolean {\n return /(_declare|_set(_|$)|_update|_write|_delete|_restore|_archive|_upsert|_reparent|_change|_duplicate|_move|_decide|_run$|_submit|_publish|_import_|_start$|_complete|_sign$|_add$|_retire|_propose|_promote|_land$|_pin$|_mute|_snooze|_unsnooze|_clear|_unclear|_revoke|_issue|_bind|_unbind|_apply|_backfill|_sync$|_decorate|_designate|_ensure|^migrate_|^set_table_|^home_add|^capture_|^claim_|^record_stage|^anon_|^io_import_|^io_comment_resolve|^enrich_(declare|land|pin)|^field_(declare|duplicate|propose|restore|retire|update)|^table_(declare|ensure|from_example|move|sync)|^value_restore|^relation_own)/.test(door);\n}\n","// src/core/doorCall.ts — @ai-matrx/records · THE ONE DOOR CALL (HEADLESS, LIGHT)\n//\n// Every typed method of the records client, and the light door clients a host's shell uses\n// (`@ai-matrx/records/door-call`: the scope doors, the pick-list doors, `storeDoors`), ask the store\n// through THIS function. It holds the door-call semantics once:\n//\n// - a primed answer (the server render asked the same door as the same person) is served first;\n// - a write empties what was primed (all of it, or only a look write's reads);\n// - ONE READ IN FLIGHT, ONE ANSWER FOR EVERY ASKER (lane DEDUPE-READS): two askers of the same\n// door with the same arguments in the same moment share one request; a writing door always goes\n// out on its own, and a flight is forgotten the moment it lands;\n// - the schema is said out loud (`custom`), never PostgREST's `public` default;\n// - a door the store lacks is refused `door_absent` (never an empty answer), and every other\n// refusal is the store's own words (`mapPgError`), said once through the error sink.\n//\n// What only the full client has (the table/record page bundle, the generated door catalogue) is\n// handed in as hooks, so this file imports no table registry, no field-kind vocabulary and no UI:\n// a shell that only reads scopes or a pick list never carries the store client.\n\nimport type { RecordsDataSource, RecordsErrorSink } from \"../ports\";\nimport type { RecordsError, RecordsErrorCode, RecordsResult } from \"../results\";\nimport { err, ok } from \"../results\";\nimport { mapPgError } from \"./pgError\";\nimport { LOOK_WRITES, dropPrimedDoorAnswers, forgetPrimedTablePageBundlesOf, isWritingDoor, takePrimedDoorAnswer } from \"./primedBundle\";\n\n/** The schema every door of the record store lives in, unless the host's config says otherwise. */\nexport const DEFAULT_DOOR_SCHEMA = \"custom\";\n\n/** An argument object as one stable string: keys sorted at every depth (PAGE-BUNDLE's match key). */\nexport function canonicalArgs(value: unknown): string {\n return JSON.stringify(value, (_key, held) =>\n held && typeof held === \"object\" && !Array.isArray(held)\n ? Object.fromEntries(Object.keys(held as object).sort().map((k) => [k, (held as Record<string, unknown>)[k]]))\n : held,\n );\n}\n\n/**\n * 🚨 A REFUSAL IS NOT AN APP ERROR (lane RECORDS-UI-FIX, guide re-walk 2026-09-23).\n *\n * A person typing `-3` into a column that takes \"at least 0\" is the store WORKING: the\n * rule said no, the screen said so in the one notice, and the person fixed it. The default\n * sink printed every one of those through `console.error`, and the app's error capture\n * (matrx-frontend `lib/diagnostics/globalErrorCapture.ts`) counts every `console.error` —\n * so one refused value lit a red \"2 errors\" pill in the corner, telling an admin the\n * product had failed when a person had simply been told no.\n *\n * These are the codes a PERSON causes by what they typed or when they typed it; each one\n * is already drawn on the screen that asked. They are still said (`console.info`), never\n * silenced. Everything else — a door, the store switched off, a timeout, a class this\n * package did not recognise — is a failure of the system and stays `console.error`.\n */\nexport const A_PERSONS_REFUSAL: ReadonlySet<RecordsErrorCode> = new Set<RecordsErrorCode>([\n \"refused_by_rule\",\n \"stale_write\",\n \"invalid_argument\",\n \"already_exists\",\n \"missing_reference\",\n]);\n\nexport function isAPersonsRefusal(code: RecordsErrorCode | string): boolean {\n return A_PERSONS_REFUSAL.has(code as RecordsErrorCode);\n}\n\n/** The host's error sink, or the default one: the store's own words, naming where it happened. */\nexport function recordsErrorSink(onError: RecordsErrorSink | undefined): RecordsErrorSink {\n return (\n onError ??\n ((e) => {\n // The defined degradation, stated: with the store's own words, and naming where it\n // happened. Never silence — but a person's refusal is information, not an error.\n const line = `[@ai-matrx/records] ${e.where}: ${e.code} — ${e.message}${e.hint ? ` (${e.hint})` : \"\"}`;\n if (isAPersonsRefusal(e.code)) console.info(line);\n else console.error(line);\n })\n );\n}\n\n/** The refusal a missing door gets. It always says who owes it (`owedBy`, when a lane claims it). */\nexport function doorAbsentRefusal(name: string, owedBy?: string): RecordsError {\n return {\n code: \"door_absent\",\n message:\n `The record store has no door \\`custom.${name}\\` yet, so this call was not made. ` +\n `Nothing was read and nothing was written.`,\n hint: owedBy\n ? `That door is ${owedBy}. Until it lands, this call refuses rather than guessing: ` +\n `an empty answer here would read like \"there is nothing\", which is a different sentence.`\n : `No lane in the build book claims this door. Either the name is wrong, or the door was ` +\n `removed from the store and this package has not been regenerated — run \\`pnpm records:generate\\`.`,\n };\n}\n\n/**\n * What the server render already asked as this person, for this exact door and arguments — or null.\n * A write (or a look write) empties what is primed instead, and is never answered from it.\n */\nexport function primedDoorAnswer(door: string, args: Record<string, unknown>): { data: unknown } | null {\n const look = LOOK_WRITES[door];\n if (look) {\n dropPrimedDoorAnswers(look);\n return null;\n }\n if (isWritingDoor(door)) {\n dropPrimedDoorAnswers();\n return null;\n }\n return takePrimedDoorAnswer(`${door}|${canonicalArgs(args)}`);\n}\n\n/** One door call: the door's name, its arguments, and where the caller is (for the refusal). */\nexport type DoorCall = <T>(\n door: string,\n args: Record<string, unknown>,\n where: string,\n /**\n * `quiet`: this refusal is an ANSWER the caller already draws (a door that says \"not yours\" to a\n * person who only has table-level access), not a failure of the system. It is returned to the\n * caller and said once with `console.info` - never through the error sink, which lights the\n * error badge. Everything else about the call is unchanged.\n */\n opts?: { quiet?: boolean },\n) => Promise<RecordsResult<T>>;\n\nexport interface DoorCallOptions {\n /** The store's data seam (`asRecordsDataSource(supabase)`). */\n dataSource: RecordsDataSource;\n /** Defaults to `custom`. */\n schema?: string;\n /** The host's error sink (defaults to `recordsErrorSink(undefined)`). */\n onError?: RecordsErrorSink;\n /**\n * MAY THIS DOOR BE ASKED AT ALL (the full client's generated catalogue). False refuses with\n * `absent(door)` and asks nobody. Absent ⇒ every door is asked, and a store that answers \"no such\n * function\" (PostgREST's PGRST202 or Postgres's 42883) is refused `door_absent` all the same.\n */\n doorReady?: (door: string) => boolean;\n /** The refusal a missing door gets (defaults to `doorAbsentRefusal(door)`). */\n absent?: (door: string) => RecordsError;\n /** An answer this page already holds for the exact call (the full client's page bundle), else null. */\n held?: (door: string, args: Record<string, unknown>) => Promise<{ data: unknown } | null | undefined>;\n /** A write landed: drop what this page still holds of it (the full client's page bundle). */\n wrote?: (door: string, args: Record<string, unknown>) => void;\n}\n\n/** Build the one door call over a data source. Every records client, light or full, asks through this. */\nexport function createDoorCall(options: DoorCallOptions): DoorCall {\n const { dataSource, doorReady, held, wrote } = options;\n const schema = options.schema ?? DEFAULT_DOOR_SCHEMA;\n const scream = recordsErrorSink(options.onError);\n const absent = options.absent ?? ((door: string) => doorAbsentRefusal(door));\n const readsInFlight = new Map<string, Promise<Awaited<ReturnType<RecordsDataSource[\"rpc\"]>>>>();\n\n const say = (refusal: RecordsError, where: string): void =>\n scream({ code: refusal.code, message: refusal.message, ...(refusal.hint ? { hint: refusal.hint } : {}), where });\n\n return async function callDoor<T>(\n door: string,\n args: Record<string, unknown>,\n where: string,\n opts?: { quiet?: boolean },\n ): Promise<RecordsResult<T>> {\n // A WRITE EMPTIES WHAT THE SERVER ASKED; A READ FINDS ITS EXACT ANSWER THERE FIRST (lane SEED-ENTITY).\n const primed = primedDoorAnswer(door, args);\n if (primed) return ok(primed.data as T);\n if (held) {\n const bundled = await held(door, args);\n if (bundled) return ok(bundled.data as T);\n }\n // The generated catalogue, or a store the host says already has the door (`knownDoors`) —\n // the bridge between a chair's production apply and the next `pnpm records:generate`.\n if (doorReady && !doorReady(door)) {\n const refusal = absent(door);\n say(refusal, where);\n return err(refusal);\n }\n // THE SCHEMA IS SAID OUT LOUD. A door of the store is `custom.<name>`, and\n // a host's supabase client resolves an unqualified `rpc()` against its own\n // default PostgREST profile — `public` in every client we ship. Leaving it\n // off therefore asked `public.store_is_open`, which the browser extension\n // found for us on its first real turn (2026-09-18, W6-EXT): \"Could not find\n // the function public.store_is_open(p_organization_id) in the schema cache\".\n // The package knows which schema it lives in, so it is the package that\n // says so, once, here — never every host remembering to.\n // ONE READ IN FLIGHT, ONE ANSWER FOR EVERY ASKER (lane DEDUPE-READS). Two hooks asking the same\n // door with the same arguments in the same moment (`custom.enrich_cells` fired twice in one\n // millisecond) share ONE request. Only reads share; a writing door always goes out on its own.\n // The flight is forgotten the moment it lands, so the next ask is a fresh read.\n const flightKey = isWritingDoor(door) ? null : `${door}|${canonicalArgs(args)}`;\n const flying = flightKey ? readsInFlight.get(flightKey) : undefined;\n const response = await (flying ??\n (() => {\n const call = Promise.resolve(dataSource.rpc(`${door}`, args, { schema }));\n if (flightKey) {\n readsInFlight.set(flightKey, call);\n const forget = (): void => {\n if (readsInFlight.get(flightKey) === call) readsInFlight.delete(flightKey);\n };\n call.then(forget, forget);\n }\n return call;\n })());\n if (response.error) {\n const code = (response.error as { code?: string }).code;\n // Without a catalogue, \"no such function\" is the store saying it lacks the door.\n const refusal =\n !doorReady && (code === \"PGRST202\" || code === \"42883\") ? absent(door) : mapPgError(response.error, where);\n if (opts?.quiet) console.info(`[@ai-matrx/records] ${where}: ${refusal.code} - ${refusal.message}`);\n else say(refusal, where);\n return err(refusal);\n }\n // A WRITE THAT LANDED EMPTIES WHAT THE PAGE STILL HOLDS OF THE TABLE (lane COPY-VIEW): \"Copy\n // settings from…\" saved the view and the bar's re-read of the views was answered from the bundle, as\n // of before the write — no request left the page and the grid kept the old filter until a reload.\n if (isWritingDoor(door) || LOOK_WRITES[door]) {\n const tableId = args[\"p_table_id\"];\n wrote?.(door, args);\n forgetPrimedTablePageBundlesOf(typeof tableId === \"string\" ? tableId : null);\n dropPrimedDoorAnswers(LOOK_WRITES[door]);\n }\n return ok(response.data as T);\n };\n}\n","// src/core/pickListDoors.ts — @ai-matrx/records · THE PICK-LIST DOORS (HEADLESS, LIGHT)\n//\n// One call each, through the one door call (./doorCall). The records client spreads these into\n// itself; `@ai-matrx/records/door-call` hands them to a shell that only reads or rewrites a pick\n// list, so it never carries the store client. The list is read by its own id; its organization is\n// the list's own, never the client's.\n\nimport type { Uuid } from \"../record\";\nimport type { RecordsResult } from \"../results\";\nimport type { PickListDocument, PickListItemInput } from \"../pick-list\";\nimport type { DoorCall } from \"./doorCall\";\n\nexport interface PickListDoors {\n /**\n * PICK-LISTS: a pick list with its choices, grouped (`custom.pick_list_get`; viewer access on the list).\n * The list is read by its own id; its organization is the list's own, never the client's.\n */\n pickListGet(args: { list_id: Uuid }): Promise<RecordsResult<PickListDocument | null>>;\n /** PICK-LISTS: a pick list for a selection control (`custom.pick_list_for_selection`): labels, help, groups, icons, NEVER the secret description. */\n pickListForSelection(args: { list_id: Uuid }): Promise<RecordsResult<PickListDocument | null>>;\n /**\n * PICK-LISTS: rename / describe a pick list and, with `items`, REPLACE its choices\n * (`custom.pick_list_update`; editor access). The replaced choices are archived, soft and restorable.\n */\n pickListUpdate(args: {\n list_id: Uuid;\n list_name?: string | null;\n description?: string | null;\n items?: readonly PickListItemInput[] | null;\n }): Promise<RecordsResult<PickListDocument | null>>;\n}\n\n/** The door names (guard: each is in the generated catalogue — `door-call-entry.test.ts`). */\nexport const PICK_LIST_DOORS = {\n pickListGet: \"pick_list_get\",\n pickListForSelection: \"pick_list_for_selection\",\n pickListUpdate: \"pick_list_update\",\n} as const;\n\nexport function createPickListDoors(callDoor: DoorCall): PickListDoors {\n return {\n async pickListGet({ list_id }) {\n return callDoor<PickListDocument | null>(PICK_LIST_DOORS.pickListGet, { p_list_id: list_id }, \"pickListGet\");\n },\n\n async pickListForSelection({ list_id }) {\n return callDoor<PickListDocument | null>(\n PICK_LIST_DOORS.pickListForSelection,\n { p_list_id: list_id },\n \"pickListForSelection\",\n );\n },\n\n async pickListUpdate({ list_id, list_name, description, items }) {\n return callDoor<PickListDocument | null>(\n PICK_LIST_DOORS.pickListUpdate,\n {\n p_list_id: list_id,\n p_list_name: list_name ?? null,\n p_description: description ?? null,\n p_items: items ? [...items] : null,\n },\n \"pickListUpdate\",\n );\n },\n };\n}\n","// src/scopes/types.ts — @ai-matrx/records/scopes\n//\n// SCOPES ARE CUSTOM DATA (Arman, 2026-10-09: \"Scopes are now nothing more than custom data… A scope\n// type is nothing more than a row [a custom Table flagged kept_for='context'], a context item is\n// nothing more than a column.\").\n//\n// scope type a Table of the store kept for context (`kept_for = 'context'`)\n// scope a Record of that Table\n// context field a Field (column) of that Table — what the old screens called a \"context item\"\n// context value the Record's cell under the Field's key\n//\n// These are the shapes the `custom.context_*` doors answer, in the store's words. Nothing here is a\n// row of the archived `context.*` tables, and nothing re-creates one: a value is the cell (`value`),\n// never a set of `value_text` / `value_number` / … columns; a field says `context_policy` and the\n// store's `sensitivity`, never the old `fetch_hint` words.\n\nimport type { Uuid } from \"../record\";\n\n/**\n * What a context field holds, as a person thinks of it — derived from the Field's behaviour, `multi`,\n * `format`, display format and `config.kind` (`contextFieldKind`). The value is always `value`; the\n * kind says how to read and edit it.\n */\nexport type ContextFieldKind =\n | \"string\"\n | \"markdown\"\n | \"email\"\n | \"url\"\n | \"phone\"\n | \"color\"\n | \"number\"\n | \"percent\"\n | \"currency\"\n | \"boolean\"\n | \"date\"\n | \"datetime\"\n | \"time\"\n | \"object\"\n | \"array\"\n | \"reference\"\n | \"document\";\n\nexport const CONTEXT_FIELD_KINDS: readonly ContextFieldKind[] = [\n \"string\",\n \"markdown\",\n \"email\",\n \"url\",\n \"phone\",\n \"color\",\n \"number\",\n \"percent\",\n \"currency\",\n \"boolean\",\n \"date\",\n \"datetime\",\n \"time\",\n \"object\",\n \"array\",\n \"reference\",\n \"document\",\n];\n\n/** The store's context policy on a Field: whether an agent receives it every turn, on request, or never. */\nexport type ContextPolicy = \"include\" | \"on_request\" | \"exclude\";\n\n/** The store's sensitivity words on a Field. */\nexport type ContextSensitivity = \"public\" | \"internal\" | \"confidential\" | \"restricted\";\n\n/** A scope type: a Table kept for context. */\nexport interface ScopeType {\n id: Uuid;\n organization_id: Uuid;\n label_singular: string;\n label_plural: string;\n icon: string;\n color: string;\n /** The Table's slug in the store's grammar (`practice_areas`). */\n slug: string | null;\n description: string;\n sort_order: number;\n max_assignments_per_entity: number | null;\n default_variable_keys: string[];\n /** Who made the type: with the organization's owners and admins, they shape it (`canShapeScopeType`). */\n created_by: Uuid | null;\n created_at: string;\n updated_at: string;\n}\n\n/** A scope type with its live scopes, as the tree doors answer it. */\nexport interface ScopeTypeWithScopes extends ScopeType {\n scopes: Scope[];\n}\n\n/** A scope: a Record of its type's Table. */\nexport interface Scope {\n id: Uuid;\n scope_type_id: Uuid;\n organization_id: Uuid;\n name: string;\n description: string;\n slug: string | null;\n sort_order: number;\n parent_scope_id: Uuid | null;\n /** Free settings keys of the scope (each a Field of its Table the scope door derived). */\n settings: Record<string, unknown>;\n created_by: Uuid | null;\n created_at: string;\n updated_at: string;\n}\n\n/** A scope with its type's presentation (`custom.context_scopes`). */\nexport interface ScopeWithType extends Scope {\n scope_type: ScopeTypeLabel | null;\n}\n\n/** The presentation of a scope type: what a chip or a breadcrumb shows. */\nexport interface ScopeTypeLabel {\n id: Uuid;\n /** The type's slug in the store's grammar (`practice_areas`), when it has one. */\n slug: string | null;\n label_singular: string;\n label_plural: string;\n icon: string | null;\n color: string | null;\n}\n\n/** A scope type that was archived, with how many scopes went with it. */\nexport interface ArchivedScopeType {\n id: Uuid;\n organization_id: Uuid;\n label_singular: string;\n label_plural: string;\n icon: string;\n color: string;\n archived_at: string;\n created_by: Uuid | null;\n archived_scope_count: number;\n}\n\n/** A scope that was archived (a Record in the archive of its type's Table). */\nexport interface ArchivedScope {\n id: Uuid;\n name: string | null;\n slug: string | null;\n archived_at: string | null;\n}\n\n/** A context field: a Field (column) of a scope type's Table. */\nexport interface ContextField {\n id: Uuid;\n scope_type_id: Uuid;\n organization_id: Uuid;\n key: string;\n label: string;\n description: string;\n kind: ContextFieldKind;\n /** The Field's own words, for a caller that needs them (`type` is the store's behaviour word). */\n type: string;\n multi: boolean;\n format: string | null;\n config: Record<string, unknown>;\n relation_target: Uuid | null;\n /** Its place among the type's context fields, from 0. */\n sort: number;\n context_policy: ContextPolicy;\n sensitivity: ContextSensitivity;\n source: string;\n status: string;\n status_note: string | null;\n category: string | null;\n tags: string[];\n max_items: number;\n custom_component: unknown;\n reference_source: unknown;\n allowed_scope_type_ids: Uuid[] | null;\n allowed_reference_types: string[] | null;\n review_interval_days: number | null;\n depends_on: string[];\n /** The store's clock on this Field. */\n version: number;\n created_by: Uuid | null;\n created_at: string;\n updated_at: string;\n}\n\n/** One thing a reference cell points at. */\nexport interface ContextReference {\n /** The record id (for a file: the File record's id). */\n id: Uuid;\n /** What it is: `scope`, `file`, `table`, or another entity token. */\n type: string;\n /** Its name, where the door named it to this caller. */\n label?: string;\n /** For a file: the `files.files` id a viewer opens. */\n file_id?: Uuid;\n}\n\n/** The cell holds only the first words of a text kept as a file, and the whole could not be read. */\nexport interface IncompleteValue {\n /** The cell's own first words. */\n head: string;\n /** The whole text's length in characters, when known. */\n chars: number | null;\n /** The file holding the whole text, when it has one yet. */\n file_id: Uuid | null;\n /** Why the whole text is not here, in one sentence. */\n why: string;\n}\n\n/** A context value: one cell of a scope's Record. */\nexport interface ContextValue {\n scope_id: Uuid;\n field_id: Uuid;\n key: string;\n kind: ContextFieldKind;\n /**\n * THE CELL, as the store holds it (a text, a number, a boolean, an ISO date, a list, an object).\n * A reference or document cell is its `references` (ids here). A text kept as a file is its whole\n * text when the read could open the file (`completeWholeValues`), else the first words and `incomplete`.\n */\n value: unknown;\n /** A reference / document cell, decoded: what it points at, with names the caller may see. */\n references: ContextReference[];\n /** The version a PERSON made (system rewrites never move it). */\n version: number;\n set_at: string | null;\n source_type: string | null;\n authored_by: Uuid | null;\n /** The pointer to the file holding a text too big for one cell, when the cell holds only its start. */\n whole_value: StoreWholeValue | null;\n /** Present only when `value` is not the whole text — never save it back as the value. */\n incomplete: IncompleteValue | null;\n}\n\n/** The file fields of a whole-value pointer, as `custom.context_values` answers them. */\nexport interface StoreWholeValue {\n kind: string;\n file_id?: Uuid | null;\n file_record?: Uuid | null;\n bytes?: number | null;\n chars?: number | null;\n sha256?: string | null;\n shown_chars?: number | null;\n mime?: string | null;\n pending?: boolean | null;\n in_value?: boolean | null;\n}\n\n/** The scope types of some organizations, without their scopes, and how many each holds. */\nexport interface ScopeTypeSkeleton {\n types: ScopeType[];\n /** type id → how many scopes the caller sees in it; null when asked without counts. */\n counts: Record<Uuid, number> | null;\n}\n\n/** One page of one type's scopes. */\nexport interface ScopePage {\n scopes: Scope[];\n total: number;\n next_offset: number | null;\n}\n\n/**\n * The pseudo scope-type id a System Context field carries. System Context (what is simply TRUE on the\n * platform) has no scope type; its fields share this sentinel so a holder can keep them beside a\n * type's fields. A client-side key only — a binding to one of these carries `scope_type_id: null`.\n */\nexport const SYSTEM_CONTEXT_TYPE_ID = \"__system__\";\n\n/** What a System Context item is: a curated fact, an ambient fact of the moment, or a dataset. */\nexport type SystemContextItemClass = \"curated\" | \"ambient\" | \"dataset\" | (string & {});\n\n/**\n * A System Context item (`custom.context_system_items`), as a `ContextField` of the\n * `SYSTEM_CONTEXT_TYPE_ID` pseudo-type, plus its class.\n */\nexport interface SystemContextField extends ContextField {\n item_class: SystemContextItemClass | null;\n}\n\n/** One column of a table template. */\nexport interface TableTemplateField {\n field_name: string;\n display_name: string;\n data_type: string;\n field_order: number;\n is_required: boolean;\n}\n\n/**\n * A table template (a `custom.template` of kind `table`) a scope's dataset field may lock its\n * table's columns to: the organization's own or a platform one, as `custom.table_templates` answers it.\n */\nexport interface TableTemplate {\n id: Uuid;\n organization_id: Uuid | null;\n name: string;\n description: string;\n version: number;\n is_platform: boolean;\n fields: TableTemplateField[];\n}\n\n/** One scope template of the gallery, as `custom.context_templates` answers it. */\nexport interface ScopeTemplate {\n [key: string]: unknown;\n}\n\n// ─── writes ──────────────────────────────────────────────────────────────────────────────────────\n\n/** A new scope type, or the parts of one to change (`undefined` = leave as it is). */\nexport interface ScopeTypeSpec {\n label_singular?: string;\n label_plural?: string;\n icon?: string;\n color?: string;\n description?: string;\n sort_order?: number;\n max_assignments_per_entity?: number | null;\n default_variable_keys?: string[];\n /** Any spelling; the package writes it in the store's grammar. Absent on create = from the label. */\n slug?: string;\n}\n\n/** A new scope, or the parts of one to change. */\nexport interface ScopeSpec {\n name?: string;\n description?: string;\n settings?: Record<string, unknown>;\n parent_scope_id?: Uuid | null;\n slug?: string;\n sort_order?: number;\n}\n\n/** A new context field, or the parts of one to change (`null` clears). */\nexport interface ContextFieldSpec {\n key?: string;\n label?: string;\n kind?: ContextFieldKind;\n description?: string;\n category?: string | null;\n context_policy?: ContextPolicy;\n sensitivity?: ContextSensitivity;\n tags?: string[];\n sort?: number;\n status?: string;\n status_note?: string | null;\n custom_component?: unknown;\n review_interval_days?: number | null;\n allowed_reference_types?: string[] | null;\n max_items?: number | null;\n allowed_scope_type_ids?: Uuid[] | null;\n reference_source?: unknown;\n}\n\n/** One cell to write. `value` is the cell as `ContextValue.value` reads it; a reference cell takes `references`. */\nexport interface ContextValueWrite {\n scope_id: Uuid;\n field_id: Uuid;\n kind: ContextFieldKind;\n value?: unknown;\n /** A reference / document cell: the things it points at (replaces the cell). */\n references?: ContextReference[];\n /** Who wrote it: `manual` from a person's own edit (the store's default is `ai_enriched`). */\n source_type?: string;\n change_summary?: string;\n}\n\n/** What a written cell answers. */\nexport interface ContextValueWritten {\n scope_id: Uuid;\n field_id: Uuid;\n version: number;\n source_type: string;\n}\n","// src/scopes/codec.ts — @ai-matrx/records/scopes\n//\n// THE ONE PLACE THE SCOPE DOORS' WORDS ARE READ AND WRITTEN.\n//\n// The `custom.context_*` doors answer the store's rows (a Table, a Record, a Field document, a\n// cell) and, for the write doors, still TAKE a few of the words the old screens wrote\n// (`display_name`, `value_type`, `fetch_hint`, `value_text`…) and answer the field they wrote in\n// those words. That grammar is the door's contract, so it is spoken here, once, and never by a\n// caller: everything above this file holds `ScopeType`, `Scope`, `ContextField` and `ContextValue`.\n// The server's reader (aidream `matrx_records/store/scopes.py`) reads the same doors.\n\nimport type { Uuid } from \"../record\";\nimport type {\n ArchivedScopeType,\n ContextField,\n ContextFieldKind,\n ContextFieldSpec,\n ContextPolicy,\n ContextReference,\n ContextSensitivity,\n ContextValue,\n ContextValueWrite,\n Scope,\n ScopeType,\n ScopeTypeLabel,\n ScopeWithType,\n StoreWholeValue,\n SystemContextField,\n} from \"./types\";\nimport { SYSTEM_CONTEXT_TYPE_ID } from \"./types\";\nimport { isUuidShape } from \"@ai-matrx/kit/uuid\";\n\n// ─── the doors' answers ─────────────────────────────────────────────────────────────────────────\n\n/** A scope type as the tree doors answer it. */\nexport interface StoreTypeRow {\n id: string;\n organization_id: string;\n label_singular?: string | null;\n label_plural?: string | null;\n name?: string | null;\n icon?: string | null;\n color?: string | null;\n slug?: string | null;\n description?: string | null;\n sort_order?: number | null;\n max_assignments_per_entity?: number | null;\n default_variable_keys?: string[] | null;\n created_by?: string | null;\n created_at?: string | null;\n updated_at?: string | null;\n scope_count?: number | null;\n}\n\n/** A scope as the tree and scope doors answer it. */\nexport interface StoreScopeRow {\n id: string;\n scope_type_id: string;\n organization_id: string;\n name?: string | null;\n description?: string | null;\n slug?: string | null;\n sort_order?: number | string | null;\n parent_scope_id?: string | null;\n settings?: Record<string, unknown> | null;\n created_by?: string | null;\n created_at?: string | null;\n updated_at?: string | null;\n scope_type?: (Partial<StoreTypeRow> & { id: string }) | null;\n}\n\n/** A Field document, as `custom.context_items` / `custom.context_values` answer it. */\nexport interface StoreFieldDoc {\n key?: string;\n label?: string;\n type?: string;\n multi?: boolean | null;\n format?: string | null;\n display_format?: { id?: string } | null;\n config?: ({ kind?: string } & Record<string, unknown>) | null;\n relation_target?: string | null;\n sort?: number | string | null;\n description?: string | null;\n sensitivity?: string | null;\n context_policy?: string | null;\n source?: string | null;\n status?: string | null;\n status_note?: string | null;\n category?: string | null;\n tags?: string[] | null;\n max_items?: number | null;\n custom_component?: unknown;\n reference_source?: unknown;\n allowed_scope_type_ids?: string[] | null;\n allowed_reference_types?: string[] | null;\n review_interval_days?: number | null;\n depends_on?: string[] | null;\n [extra: string]: unknown;\n}\n\n/** What the store remembers about a field it moved from the old tables and could not type. */\nexport interface StoreCarried {\n value_type?: string;\n as_text?: boolean;\n is_active?: boolean;\n}\n\n/** A context field as `custom.context_items` answers it. */\nexport interface StoreItemRow {\n id: string;\n scope_type_id: string;\n organization_id: string;\n data: StoreFieldDoc;\n carried?: StoreCarried | null;\n created_by?: string | null;\n created_at?: string | null;\n updated_at?: string | null;\n version?: number | null;\n}\n\n/** A cell as `custom.context_values` answers it. */\nexport interface StoreValueRow {\n scope_id: string;\n context_item_id: string;\n key: string;\n value: unknown;\n field?: (Pick<StoreFieldDoc, \"type\" | \"multi\" | \"format\" | \"display_format\" | \"config\" | \"relation_target\"> & {\n carried?: StoreCarried | null;\n }) | null;\n version?: number | null;\n store_version?: number | null;\n set_at?: string | null;\n source_type?: string | null;\n value_id?: string | null;\n authored_by?: string | null;\n labels?: Record<string, string> | null;\n files?: Record<string, string> | null;\n whole_value?: StoreWholeValue | null;\n}\n\n/** An archived scope type as `custom.context_archived_types` answers it. */\nexport interface StoreArchivedTypeRow {\n id: string;\n organization_id: string;\n label_singular?: string | null;\n label_plural?: string | null;\n icon?: string | null;\n color?: string | null;\n deleted_at?: string | null;\n created_by?: string | null;\n archived_scope_count?: number | null;\n}\n\n// ─── reading ────────────────────────────────────────────────────────────────────────────────────\n\nconst str = (v: unknown, fallback = \"\"): string => (typeof v === \"string\" ? v : fallback);\nconst strOrNull = (v: unknown): string | null => (typeof v === \"string\" ? v : null);\nconst num = (v: unknown, fallback = 0): number => {\n const n = typeof v === \"number\" ? v : typeof v === \"string\" ? Number(v) : NaN;\n return Number.isFinite(n) ? n : fallback;\n};\n\nexport function scopeTypeFromStore(row: StoreTypeRow): ScopeType {\n const singular = row.label_singular ?? row.name ?? \"\";\n return {\n id: row.id,\n organization_id: row.organization_id,\n label_singular: singular,\n label_plural: row.label_plural ?? singular,\n icon: row.icon ?? \"folder\",\n color: row.color ?? \"\",\n slug: row.slug ?? null,\n description: row.description ?? \"\",\n sort_order: num(row.sort_order),\n max_assignments_per_entity: row.max_assignments_per_entity ?? null,\n default_variable_keys: Array.isArray(row.default_variable_keys) ? row.default_variable_keys : [],\n created_by: row.created_by ?? null,\n created_at: row.created_at ?? \"\",\n updated_at: row.updated_at ?? \"\",\n };\n}\n\nexport function scopeTypeLabelFromStore(t: Partial<StoreTypeRow> & { id: string }): ScopeTypeLabel {\n const singular = t.label_singular ?? t.name ?? \"\";\n return { id: t.id, slug: t.slug ?? null, label_singular: singular, label_plural: t.label_plural ?? singular, icon: t.icon ?? null, color: t.color ?? null };\n}\n\n/**\n * A settings value as it was written. The scope door keeps a list-of-objects setting (a class's exam\n * dates) as a list of their JSON texts (`custom._ctx_words`); read back, each is the object again.\n */\nexport function settingFromStore(value: unknown): unknown {\n if (!Array.isArray(value)) return value;\n return value.map((el) => {\n if (typeof el !== \"string\") return el;\n const t = el.trim();\n if (!(t.startsWith(\"{\") && t.endsWith(\"}\")) && !(t.startsWith(\"[\") && t.endsWith(\"]\"))) return el;\n try {\n return JSON.parse(t) as unknown;\n } catch {\n return el;\n }\n });\n}\n\nexport function scopeFromStore(row: StoreScopeRow): Scope {\n const settings: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(row.settings ?? {})) settings[k] = settingFromStore(v);\n return {\n id: row.id,\n scope_type_id: row.scope_type_id,\n organization_id: row.organization_id,\n name: row.name ?? \"\",\n description: row.description ?? \"\",\n slug: row.slug ?? null,\n sort_order: num(row.sort_order),\n parent_scope_id: row.parent_scope_id ?? null,\n settings,\n created_by: row.created_by ?? null,\n created_at: row.created_at ?? \"\",\n updated_at: row.updated_at ?? \"\",\n };\n}\n\nexport function scopeWithTypeFromStore(row: StoreScopeRow): ScopeWithType {\n return { ...scopeFromStore(row), scope_type: row.scope_type ? scopeTypeLabelFromStore(row.scope_type) : null };\n}\n\nexport function archivedScopeTypeFromStore(row: StoreArchivedTypeRow): ArchivedScopeType {\n const singular = row.label_singular ?? \"\";\n return {\n id: row.id,\n organization_id: row.organization_id,\n label_singular: singular,\n label_plural: row.label_plural ?? singular,\n icon: row.icon ?? \"folder\",\n color: row.color ?? \"\",\n archived_at: row.deleted_at ?? \"\",\n created_by: row.created_by ?? null,\n archived_scope_count: row.archived_scope_count ?? 0,\n };\n}\n\n/** The file kernel: a relation at it is a document (a file), never a reference to a row. */\nexport const FILE_KERNEL_ID = \"11111111-0000-4000-8000-000000000006\";\n\nconst KINDS = new Set<string>([\n \"string\", \"markdown\", \"email\", \"url\", \"phone\", \"color\", \"number\", \"percent\", \"currency\", \"boolean\",\n \"date\", \"datetime\", \"time\", \"object\", \"array\", \"reference\", \"document\",\n]);\n\n/** What a Field holds, as a person thinks of it. */\nexport function contextFieldKind(\n doc: Pick<StoreFieldDoc, \"type\" | \"multi\" | \"format\" | \"display_format\" | \"config\" | \"relation_target\">,\n carried?: StoreCarried | null,\n): ContextFieldKind {\n // A field the store landed as text keeps the word it had (custom._ctx_store_item carries it).\n if (carried?.as_text && carried.value_type && KINDS.has(carried.value_type)) return carried.value_type as ContextFieldKind;\n const behavior = String(doc.type ?? \"text\");\n const fmt = doc.format ? String(doc.format) : \"\";\n const shown = doc.display_format && typeof doc.display_format === \"object\" ? String(doc.display_format.id ?? \"\") : \"\";\n const kind = String(doc.config?.kind ?? \"\");\n const multi = Boolean(doc.multi);\n if (behavior === \"boolean\") return \"boolean\";\n if (behavior === \"relation\") return doc.relation_target === FILE_KERNEL_ID && !multi ? \"document\" : \"reference\";\n if (behavior === \"range\") {\n if (kind === \"date\") return \"date\";\n if (kind === \"datetime\") return \"datetime\";\n if (fmt === \"percent\" || fmt === \"currency\") return fmt;\n return \"number\";\n }\n if (behavior === \"text\") {\n if (multi) return \"array\";\n if (fmt === \"json\") return \"object\";\n for (const word of [fmt, shown]) {\n if (word === \"time\" || word === \"email\" || word === \"url\" || word === \"phone\" || word === \"color\" || word === \"markdown\") return word;\n }\n }\n return \"string\";\n}\n\nconst POLICIES = new Set<string>([\"include\", \"on_request\", \"exclude\"]);\nconst SENSITIVITIES = new Set<string>([\"public\", \"internal\", \"confidential\", \"restricted\"]);\n\nexport function contextFieldFromStore(row: StoreItemRow): ContextField {\n const d = row.data ?? {};\n const key = str(d.key);\n const policy = str(d.context_policy, \"include\");\n const sensitivity = str(d.sensitivity, \"internal\");\n return {\n id: row.id,\n scope_type_id: row.scope_type_id,\n organization_id: row.organization_id,\n key,\n label: str(d.label, key),\n description: str(d.description),\n kind: contextFieldKind(d, row.carried),\n type: str(d.type, \"text\"),\n multi: Boolean(d.multi),\n format: strOrNull(d.format),\n config: (d.config ?? {}) as Record<string, unknown>,\n relation_target: strOrNull(d.relation_target),\n // The store's sort counts the scope's own two columns first (custom._ctx_store_item: + 2).\n sort: Math.max(0, num(d.sort) - 2),\n context_policy: (POLICIES.has(policy) ? policy : \"include\") as ContextPolicy,\n sensitivity: (SENSITIVITIES.has(sensitivity) ? sensitivity : \"internal\") as ContextSensitivity,\n source: str(d.source, \"manual\"),\n status: str(d.status, \"active\"),\n status_note: strOrNull(d.status_note),\n category: strOrNull(d.category),\n tags: Array.isArray(d.tags) ? d.tags : [],\n max_items: typeof d.max_items === \"number\" ? d.max_items : 1,\n custom_component: d.custom_component ?? null,\n reference_source: d.reference_source ?? null,\n allowed_scope_type_ids: Array.isArray(d.allowed_scope_type_ids) ? d.allowed_scope_type_ids : null,\n allowed_reference_types: Array.isArray(d.allowed_reference_types) ? d.allowed_reference_types : null,\n review_interval_days: typeof d.review_interval_days === \"number\" ? d.review_interval_days : null,\n depends_on: Array.isArray(d.depends_on) ? d.depends_on : [],\n version: num(row.version, 1),\n created_by: row.created_by ?? null,\n created_at: row.created_at ?? \"\",\n updated_at: row.updated_at ?? \"\",\n };\n}\n\n// The write doors still speak three old words for a field; these are their meanings, both ways.\nconst POLICY_TO_DOOR: Record<ContextPolicy, string> = { include: \"always\", on_request: \"on_demand\", exclude: \"never\" };\nconst POLICY_FROM_DOOR: Record<string, ContextPolicy> = { always: \"include\", on_demand: \"on_request\", never: \"exclude\" };\nconst SENSITIVITY_TO_DOOR: Record<ContextSensitivity, string> = {\n public: \"public\",\n internal: \"internal\",\n confidential: \"restricted\",\n restricted: \"privileged\",\n};\nconst SENSITIVITY_FROM_DOOR: Record<string, ContextSensitivity> = {\n public: \"public\",\n internal: \"internal\",\n restricted: \"confidential\",\n privileged: \"restricted\",\n};\n\n/** The field a write door answered (`custom.context_item_row_of`), as a `ContextField`. */\nexport function contextFieldFromWriteAnswer(row: Record<string, unknown>, organizationId: Uuid): ContextField {\n const key = str(row.key);\n const kind = str(row.value_type, \"string\");\n return {\n id: str(row.id),\n scope_type_id: str(row.scope_type_id),\n organization_id: organizationId,\n key,\n label: str(row.display_name, key),\n description: str(row.description),\n kind: (KINDS.has(kind) ? kind : \"string\") as ContextFieldKind,\n type: \"\",\n multi: kind === \"array\",\n format: null,\n config: {},\n relation_target: null,\n sort: num(row.sort_order),\n context_policy: POLICY_FROM_DOOR[str(row.fetch_hint)] ?? \"include\",\n sensitivity: SENSITIVITY_FROM_DOOR[str(row.sensitivity)] ?? \"internal\",\n source: \"manual\",\n status: str(row.status, \"active\"),\n status_note: strOrNull(row.status_note),\n category: strOrNull(row.category),\n tags: Array.isArray(row.tags) ? (row.tags as string[]) : [],\n max_items: typeof row.max_items === \"number\" ? row.max_items : 1,\n custom_component: row.custom_component ?? null,\n reference_source: row.reference_source ?? null,\n allowed_scope_type_ids: Array.isArray(row.allowed_scope_type_ids) ? (row.allowed_scope_type_ids as string[]) : null,\n allowed_reference_types: Array.isArray(row.allowed_reference_types) ? (row.allowed_reference_types as string[]) : null,\n review_interval_days: typeof row.review_interval_days === \"number\" ? row.review_interval_days : null,\n depends_on: Array.isArray(row.depends_on) ? (row.depends_on as string[]) : [],\n version: num(row.version, 1),\n created_by: strOrNull(row.created_by),\n created_at: str(row.created_at),\n updated_at: str(row.updated_at),\n };\n}\n\n/** A System Context item, as `custom.context_system_items` answers it (the door's own words). */\nexport interface StoreSystemItemRow {\n id?: string | null;\n key?: string | null;\n display_name?: string | null;\n description?: string | null;\n item_class?: string | null;\n value_type?: string | null;\n sensitivity?: string | null;\n sort_order?: number | null;\n}\n\n/** A System Context item as a field of the `SYSTEM_CONTEXT_TYPE_ID` pseudo-type, with its class. */\nexport function systemContextFieldFromStore(row: StoreSystemItemRow, index: number): SystemContextField {\n const key = str(row.key);\n const kind = str(row.value_type, \"string\");\n return {\n id: str(row.id),\n scope_type_id: SYSTEM_CONTEXT_TYPE_ID,\n organization_id: \"\",\n key,\n label: str(row.display_name, key),\n description: str(row.description),\n kind: (KINDS.has(kind) ? kind : \"string\") as ContextFieldKind,\n type: \"system\",\n multi: kind === \"array\",\n format: null,\n config: {},\n relation_target: null,\n sort: typeof row.sort_order === \"number\" ? row.sort_order : index,\n context_policy: \"include\",\n // The system table keeps the old sensitivity words (`restricted`/`privileged`), like the write doors.\n sensitivity: SENSITIVITY_FROM_DOOR[str(row.sensitivity)] ?? \"public\",\n source: \"system\",\n status: \"active\",\n status_note: null,\n category: null,\n tags: [],\n max_items: 0,\n custom_component: null,\n reference_source: null,\n allowed_scope_type_ids: null,\n allowed_reference_types: null,\n review_interval_days: null,\n depends_on: [],\n version: 0,\n created_by: null,\n created_at: \"\",\n updated_at: \"\",\n item_class: strOrNull(row.item_class),\n };\n}\n\n\n/** A reference / document cell's targets, with the names and files the door gave this caller. */\nexport function referencesOf(row: Pick<StoreValueRow, \"value\" | \"field\" | \"labels\" | \"files\">): ContextReference[] {\n const v = row.value;\n const list = Array.isArray(v) ? v : v == null ? [] : [v];\n const labels = row.labels ?? {};\n const files = row.files ?? {};\n const toFile = row.field?.relation_target === FILE_KERNEL_ID;\n const out: ContextReference[] = [];\n for (const el of list) {\n let ref: ContextReference | null = null;\n if (typeof el === \"string\" && isUuidShape(el)) ref = { id: el, type: toFile ? \"file\" : \"scope\" };\n else if (el && typeof el === \"object\" && typeof (el as { id?: unknown }).id === \"string\") {\n const token = String((el as { token?: unknown }).token ?? \"\");\n const own = (el as { label?: unknown }).label;\n ref = { id: (el as { id: string }).id, type: token === \"dataset\" ? \"table\" : token || (toFile ? \"file\" : \"scope\") };\n // A reference outside the scope system carries its own label in the store; the door names scopes only.\n if (typeof own === \"string\" && own) ref.label = own;\n }\n if (!ref) continue;\n const label = labels[ref.id];\n if (label) ref.label = label;\n const fileId = files[ref.id];\n if (fileId) ref.file_id = fileId;\n out.push(ref);\n }\n return out;\n}\n\n/** One cell, as a `ContextValue` (its whole text not yet read — see `completeWholeValues`). */\nexport function contextValueFromStore(row: StoreValueRow): ContextValue {\n const kind = contextFieldKind(row.field ?? {}, row.field?.carried);\n const carriedText = Boolean(row.field?.carried?.as_text);\n const isRef = !carriedText && (kind === \"reference\" || kind === \"document\");\n return {\n scope_id: row.scope_id,\n field_id: row.context_item_id,\n key: row.key,\n kind,\n value: row.value ?? null,\n references: isRef ? referencesOf(row) : [],\n version: num(row.version, 1),\n set_at: row.set_at ?? null,\n source_type: row.source_type ?? null,\n authored_by: row.authored_by ?? null,\n whole_value: row.whole_value ?? null,\n incomplete: null,\n };\n}\n\n// ─── whole texts kept as files ──────────────────────────────────────────────────────────────────\n\n/** Reads a file's whole text as the person (the host's one file reader). */\nexport type ReadContextFileText = (fileId: Uuid) => Promise<string>;\n\nasync function sha256Hex(text: string): Promise<string | null> {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) return null;\n const digest = await subtle.digest(\"SHA-256\", new TextEncoder().encode(text));\n return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n/**\n * A CELL THAT HOLDS ONLY THE FIRST WORDS OF A TEXT KEPT AS A FILE GETS ITS WHOLE TEXT.\n *\n * The store keeps a value over its one-cell ceiling as a file and the cell holds its first words;\n * `custom.context_values` names the file (`whole_value`). Each such value is given the file's whole\n * text — read once per file through the host's reader, checked against the size and SHA-256 the\n * pointer names. A file that cannot be read, or does not match, leaves the first words AND sets\n * `incomplete` (with why) — never the first words passed off as the value. Mutates `values`.\n */\nexport async function completeWholeValues(values: ContextValue[], read: ReadContextFileText | null): Promise<void> {\n const texts = new Map<string, Promise<string>>();\n await Promise.all(\n values.map(async (cell) => {\n const w = cell.whole_value;\n if (!w || w.in_value || typeof cell.value !== \"string\") return;\n const head = cell.value;\n const chars = typeof w.chars === \"number\" ? w.chars : null;\n const incomplete = (fileId: string | null, why: string): void => {\n cell.incomplete = { head, chars, file_id: fileId, why };\n };\n if (!w.file_id) return incomplete(null, \"The rest of this text is still being saved.\");\n if (!read) return incomplete(w.file_id, \"This place cannot open the file that holds the whole text.\");\n if (!texts.has(w.file_id)) texts.set(w.file_id, read(w.file_id));\n try {\n const text = await texts.get(w.file_id)!;\n if (chars !== null && [...text].length !== chars) {\n return incomplete(w.file_id, `The file holds ${[...text].length} characters, not ${chars}.`);\n }\n if (w.sha256) {\n const sha = await sha256Hex(text);\n if (sha === null) return incomplete(w.file_id, \"This browser cannot check the file.\");\n if (sha !== w.sha256) return incomplete(w.file_id, \"The file's content is not the text the cell points at.\");\n }\n cell.value = text;\n } catch (thrown) {\n incomplete(w.file_id, thrown instanceof Error ? thrown.message : String(thrown));\n }\n }),\n );\n}\n\n/** The refusal a person sees when saving would cut a value that was not read whole. */\nexport const INCOMPLETE_SAVE_REFUSAL = \"Only the start of this value loaded. Paste the whole text to replace it.\";\n\n/**\n * The refusal sentence when saving `draft` over a cell that was not read whole would cut the real\n * value — else `null`. Refused: the first words unchanged, and a draft built on them that is shorter\n * than the whole. Allowed: a draft that replaces the text, an explicit clear.\n */\nexport function incompleteSaveRefusal(cell: Pick<ContextValue, \"incomplete\"> | undefined, draft: unknown): string | null {\n const incomplete = cell?.incomplete;\n if (!incomplete || typeof draft !== \"string\" || draft === \"\") return null;\n if (draft === incomplete.head) return INCOMPLETE_SAVE_REFUSAL;\n if (incomplete.head && draft.startsWith(incomplete.head)) {\n const whole = incomplete.chars ?? Number.POSITIVE_INFINITY;\n if ([...draft].length < whole) return INCOMPLETE_SAVE_REFUSAL;\n }\n return null;\n}\n\n// ─── writing ────────────────────────────────────────────────────────────────────────────────────\n\n/** Drop keys whose value is `undefined`, keep `null` (a clear). */\nexport function definedOnly(fields: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(fields)) if (v !== undefined) out[k] = v;\n return out;\n}\n\n/** A field spec in the words `custom.context_item_write` takes. */\nexport function fieldSpecForDoor(spec: ContextFieldSpec): Record<string, unknown> {\n return definedOnly({\n key: spec.key,\n display_name: spec.label,\n value_type: spec.kind,\n description: spec.description,\n category: spec.category,\n fetch_hint: spec.context_policy ? POLICY_TO_DOOR[spec.context_policy] : undefined,\n sensitivity: spec.sensitivity ? SENSITIVITY_TO_DOOR[spec.sensitivity] : undefined,\n tags: spec.tags,\n sort_order: spec.sort,\n status: spec.status,\n status_note: spec.status_note,\n custom_component: spec.custom_component,\n review_interval_days: spec.review_interval_days,\n allowed_reference_types: spec.allowed_reference_types,\n max_items: spec.max_items,\n allowed_scope_type_ids: spec.allowed_scope_type_ids,\n reference_source: spec.reference_source,\n });\n}\n\n/** The canonical reference fence (the same grammar `@ai-matrx/agents/envelope` builds). */\nexport function referenceFence(references: readonly ContextReference[]): string {\n const kinds = [...new Set(references.map((r) => r.type))];\n const type = kinds.length === 1 ? kinds[0]! : \"mixed\";\n const items = references.map((r) => {\n if (r.type === \"file\" && r.file_id) return r.label ? { file_id: r.file_id, label: r.label } : { file_id: r.file_id };\n const item: { id: string; label?: string; type?: string } = { id: r.id };\n if (r.label) item.label = r.label;\n if (kinds.length > 1) item.type = r.type;\n return item;\n });\n return \"```matrx\\n\" + JSON.stringify({ matrx_version: 1, kind: \"reference\", type, items }, null, 2) + \"\\n```\";\n}\n\nconst FENCE_BODY = /```matrx[^\\n]*\\n([\\s\\S]*?)\\n?```/;\n\n/**\n * The things a reference fence points at (the inverse of `referenceFence`). Reads the canonical\n * grammar `{ kind: \"reference\", type, items }`, with or without the ```matrx wrapper; anything that\n * is not a reference fence answers `[]`.\n */\nexport function referencesFromFence(text: string | null | undefined): ContextReference[] {\n if (typeof text !== \"string\" || text.trim() === \"\") return [];\n const body = FENCE_BODY.exec(text)?.[1] ?? text;\n let parsed: unknown;\n try {\n parsed = JSON.parse(body.trim());\n } catch {\n return [];\n }\n if (!parsed || typeof parsed !== \"object\") return [];\n const fence = parsed as { kind?: unknown; type?: unknown; items?: unknown };\n if (fence.kind !== \"reference\" || !Array.isArray(fence.items)) return [];\n const noun = typeof fence.type === \"string\" ? fence.type : \"\";\n return fence.items.flatMap((raw): ContextReference[] => {\n if (!raw || typeof raw !== \"object\") return [];\n const item = raw as { id?: unknown; file_id?: unknown; label?: unknown; type?: unknown };\n const label = typeof item.label === \"string\" && item.label ? { label: item.label } : {};\n if (typeof item.file_id === \"string\" && item.file_id) {\n return [{ id: typeof item.id === \"string\" ? item.id : item.file_id, type: \"file\", file_id: item.file_id, ...label }];\n }\n if (typeof item.id !== \"string\" || !item.id) return [];\n const type = typeof item.type === \"string\" && item.type ? item.type : noun || \"scope\";\n return [{ id: item.id, type, ...label }];\n });\n}\n\nconst isContextReference = (v: unknown): v is ContextReference =>\n !!v && typeof v === \"object\" && typeof (v as { id?: unknown }).id === \"string\" && typeof (v as { type?: unknown }).type === \"string\";\n\n/**\n * THE ONE WRITE AN EDIT BECOMES: an editor's raw value for `field` on `scopeId`, as a\n * `ContextValueWrite`. A reference / document field takes a fence (what the reference picker edits)\n * or a list of `ContextReference`s and writes `references`; a clear (`null`, `undefined`, `\"\"`)\n * writes no references. Any other field writes `value`, with `\"\"` and `undefined` a clear (`null`).\n * Written by a person (`source_type: \"manual\"`) unless `options` says otherwise.\n */\nexport function contextValueWrite(\n field: Pick<ContextField, \"id\" | \"kind\">,\n scopeId: Uuid,\n raw: unknown,\n options: { source_type?: string; change_summary?: string } = {},\n): ContextValueWrite {\n const base: ContextValueWrite = {\n scope_id: scopeId,\n field_id: field.id,\n kind: field.kind,\n source_type: options.source_type ?? \"manual\",\n ...(options.change_summary ? { change_summary: options.change_summary } : {}),\n };\n if (field.kind === \"reference\" || field.kind === \"document\") {\n if (typeof raw === \"string\") return { ...base, references: referencesFromFence(raw) };\n if (Array.isArray(raw)) {\n return {\n ...base,\n references: raw.flatMap((el): ContextReference[] =>\n isContextReference(el) ? [el] : typeof el === \"string\" ? referencesFromFence(el) : [],\n ),\n };\n }\n return { ...base, references: [] };\n }\n return { ...base, value: raw === \"\" || raw === undefined ? null : raw };\n}\n\n/**\n * One cell in the payload `custom.context_value_write` takes: the value lands in the slot the door\n * reads for the field's kind; a reference cell is the canonical fence the door's reference rule reads.\n */\nexport function valuePayloadForDoor(write: ContextValueWrite): Record<string, unknown> {\n const base: Record<string, unknown> = definedOnly({\n scope_id: write.scope_id,\n context_item_id: write.field_id,\n source_type: write.source_type,\n change_summary: write.change_summary,\n });\n const v = write.value;\n if (write.kind === \"reference\" || write.kind === \"document\") {\n if (write.references) return { ...base, value_text: write.references.length ? referenceFence(write.references) : null };\n // A document cell may also be written as a url.\n if (write.kind === \"document\" && typeof v === \"string\") return { ...base, value_document_url: v || null };\n return { ...base, value_text: typeof v === \"string\" ? v || null : null };\n }\n if (v === null || v === undefined || v === \"\") {\n return { ...base, value_text: null };\n }\n switch (write.kind) {\n case \"number\":\n case \"percent\":\n return typeof v === \"number\" ? { ...base, value_number: v } : { ...base, value_text: String(v) };\n case \"currency\":\n return typeof v === \"object\" ? { ...base, value_json: v } : typeof v === \"number\" ? { ...base, value_number: v } : { ...base, value_text: String(v) };\n case \"boolean\":\n return typeof v === \"boolean\" ? { ...base, value_boolean: v } : { ...base, value_text: String(v) };\n case \"date\":\n return { ...base, value_date: String(v) };\n case \"datetime\":\n return { ...base, value_timestamp: String(v) };\n case \"time\":\n return { ...base, value_time: String(v) };\n case \"object\":\n case \"array\":\n return typeof v === \"object\" ? { ...base, value_json: v } : { ...base, value_text: String(v) };\n default:\n return typeof v === \"object\" ? { ...base, value_json: v } : { ...base, value_text: String(v) };\n }\n}\n","// src/scopes/rules.ts — @ai-matrx/records/scopes\n//\n// The few rules a screen needs BEFORE it asks a door, each a mirror of what the door itself decides\n// (the door is the authority; this only spares a person a button that would be refused).\n\nimport type { RecordsResult } from \"../results\";\nimport type { Uuid } from \"../record\";\n\n/** An organization role, as `iam.organization_member` holds it. */\nexport type ScopeSeatRole = \"owner\" | \"admin\" | \"member\" | string;\n\n/**\n * WHO MAY CHANGE A SCOPE TYPE'S STRUCTURE — rename it, add/edit/archive its fields, archive or restore\n * it: an organization owner or admin, or the person who made the type. Every member works the DATA\n * (adds, renames, archives and restores scopes, writes values). Arman 2026-10-07: \"structure is the\n * org admins' and the creator's\". Mirrors `custom.context_type_write` / `_archive` / `_restore` and\n * `custom.context_item_write` / `_archive` / `_restore`.\n */\nexport function canShapeScopeType(\n role: ScopeSeatRole | null | undefined,\n userId: Uuid | null | undefined,\n type: { created_by?: Uuid | null } | null | undefined,\n): boolean {\n if (role === \"owner\" || role === \"admin\") return true;\n return !!userId && !!type?.created_by && type.created_by === userId;\n}\n\n/** Display name → kebab URL slug. */\nexport function toSlug(name: string): string {\n return name\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\n/** Display name → snake_case field key. */\nexport function toFieldKey(name: string): string {\n return name\n .toLowerCase()\n .trim()\n .replace(/[\\s-]+/g, \"_\")\n .replace(/[^a-z0-9_]/g, \"\")\n .replace(/_+/g, \"_\")\n .replace(/^_|_$/g, \"\");\n}\n\n/** True when `s` is a clean slug: a-z, 0-9, single hyphens or underscores between words. */\nexport function isValidSlug(s: string): boolean {\n return /^[a-z0-9]+(?:[-_][a-z0-9]+)*$/.test(s);\n}\n\n/** Route segments that are literal pages of the scope screens; no slug may equal one. */\nexport const RESERVED_SCOPE_SLUGS: ReadonlySet<string> = new Set([\"context-items\", \"scopes\", \"edit\", \"manage\", \"new\", \"settings\"]);\n\nexport function isReservedSlug(s: string): boolean {\n return RESERVED_SCOPE_SLUGS.has(s.toLowerCase().replace(/_/g, \"-\"));\n}\n\n/**\n * Two slugs name the same thing when they differ only by `-` ↔ `_` (the store's Table grammar is\n * `practice_areas`; a link a person typed may say `practice-areas`).\n */\nexport function sameSlug(a: string | null | undefined, b: string | null | undefined): boolean {\n if (!a || !b) return false;\n return a.toLowerCase().replace(/_/g, \"-\") === b.toLowerCase().replace(/_/g, \"-\");\n}\n\n/** The slug a write sends: the one supplied, else one made from the name; refused when unusable. */\nexport function resolveSlug(supplied: string | undefined, fallbackName: string): RecordsResult<string> {\n const slug = supplied?.trim() || toSlug(fallbackName);\n if (!slug || !isValidSlug(slug)) {\n return {\n ok: false,\n error: { code: \"invalid_argument\", message: \"Use letters, numbers and single hyphens for the short name.\" },\n };\n }\n if (isReservedSlug(slug)) {\n return { ok: false, error: { code: \"invalid_argument\", message: `\"${slug}\" is a page name here. Pick another short name.` } };\n }\n return { ok: true, data: slug };\n}\n","// src/scopes/doors.ts — @ai-matrx/records/scopes\n//\n// THE SCOPE DOORS, ONE CALL EACH, THROUGH THE RECORDS CLIENT'S OWN DOOR PATH.\n//\n// `client.scopes` is built from the same `callDoor` every other method of the client uses, so a scope\n// read gets what every store read gets: the schema said out loud, one request in flight per question,\n// a door the store lacks refused as `door_absent` (never an empty list), and every refusal in the\n// store's own words (`RecordsError`). Nothing here talks to Supabase itself.\n//\n// The doors take explicit organizations (a scope read spans every organization the person belongs\n// to; a write names its own), so the client's `organizationId` is never used here.\n\nimport type { RecordsErrorCode, RecordsResult } from \"../results\";\nimport type { Uuid } from \"../record\";\nimport {\n archivedScopeTypeFromStore,\n completeWholeValues,\n contextFieldFromStore,\n contextValueFromStore,\n definedOnly,\n fieldSpecForDoor,\n scopeFromStore,\n scopeTypeFromStore,\n scopeWithTypeFromStore,\n systemContextFieldFromStore,\n valuePayloadForDoor,\n type ReadContextFileText,\n type StoreArchivedTypeRow,\n type StoreItemRow,\n type StoreScopeRow,\n type StoreSystemItemRow,\n type StoreTypeRow,\n type StoreValueRow,\n} from \"./codec\";\nimport { resolveSlug } from \"./rules\";\nimport type {\n ArchivedScope,\n ArchivedScopeType,\n ContextField,\n ContextFieldSpec,\n ContextValue,\n ContextValueWrite,\n ContextValueWritten,\n Scope,\n ScopePage,\n ScopeSpec,\n ScopeTemplate,\n ScopeType,\n ScopeTypeSkeleton,\n ScopeTypeSpec,\n ScopeTypeWithScopes,\n ScopeWithType,\n SystemContextField,\n TableTemplate,\n} from \"./types\";\n\n/** The client's one door call (`callDoor` in core/client.ts). */\nexport type ScopeDoorCall = <T>(door: string, args: Record<string, unknown>, where: string) => Promise<RecordsResult<T>>;\n\n/** The kernel Table every Field is a record of. */\nexport const FIELD_KERNEL_ID = \"11111111-0000-4000-8000-000000000002\";\n\n/** How many ids one call of each batched door takes. */\nexport const SCOPES_PER_CALL = 500;\nexport const SCOPE_TYPES_PER_FIELDS_CALL = 100;\n/** `custom.context_values` refuses more than this many scopes in one call. */\nexport const SCOPES_PER_VALUES_CALL = 200;\n/** One page of a type's scopes (the door's default; it answers at most 1000). */\nexport const TYPE_SCOPES_PAGE = 200;\n/** The archive answers at most this many rows a call (`custom.page_size` ceiling). */\nexport const ARCHIVED_SCOPES_PAGE = 200;\n\nexport interface ScopeDoors {\n // ── reads ──────────────────────────────────────────────────────────────────────────────────\n /** Every live scope type of these organizations, each with its live scopes. */\n tree(organizationIds: readonly Uuid[]): Promise<RecordsResult<ScopeTypeWithScopes[]>>;\n /** The scope types of these organizations without their scopes (the first paint), with or without counts. */\n types(organizationIds: readonly Uuid[], options?: { withCounts?: boolean }): Promise<RecordsResult<ScopeTypeSkeleton>>;\n /** One page of one type's scopes, in the tree's order. */\n typeScopesPage(scopeTypeId: Uuid, offset?: number, limit?: number): Promise<RecordsResult<ScopePage>>;\n /** The scopes whose name holds `query` (case-insensitive), across these organizations. */\n search(organizationIds: readonly Uuid[], query: string, limit?: number): Promise<RecordsResult<{ scopes: Scope[]; total: number }>>;\n /** Scopes by id, each with its type's label, in whichever organization each lives. */\n scopes(ids: readonly Uuid[]): Promise<RecordsResult<ScopeWithType[]>>;\n /**\n * The context fields (columns) of these scope types, each type's fields in their order (`sort`,\n * then label) as the door answers them.\n */\n fields(scopeTypeIds: readonly Uuid[]): Promise<RecordsResult<ContextField[]>>;\n /**\n * One context field by its id, read in whichever of these organizations holds it (a Field is a\n * record of the field kernel; its scope type is the Table it is defined on). Refused `not_found`\n * when no organization answers it.\n */\n field(fieldId: Uuid, organizationIds: readonly Uuid[]): Promise<RecordsResult<ContextField>>;\n /**\n * The cells of these scopes. A text kept as a file is read whole through `readFileText`; without\n * one (or when the file cannot be read) the cell keeps its first words and says so (`incomplete`).\n */\n values(scopeIds: readonly Uuid[], options?: { readFileText?: ReadContextFileText | null }): Promise<RecordsResult<ContextValue[]>>;\n /** The archived scope types of one organization. */\n archivedTypes(organizationId: Uuid): Promise<RecordsResult<ArchivedScopeType[]>>;\n /** Of these scope ids, the ones that are ARCHIVED scopes of this type. */\n archivedScopesOfType(organizationId: Uuid, scopeTypeId: Uuid, wanted: ReadonlySet<Uuid>): Promise<RecordsResult<ArchivedScope[]>>;\n /** The System Context items (not scopes: the platform's own ambient context). */\n systemItems(): Promise<RecordsResult<SystemContextField[]>>;\n /** The table templates an organization's scope dataset fields may use (its own and the platform's). */\n tableTemplates(organizationId: Uuid): Promise<RecordsResult<TableTemplate[]>>;\n /** The scope templates of the gallery. */\n templates(): Promise<RecordsResult<ScopeTemplate[]>>;\n\n // ── writes ─────────────────────────────────────────────────────────────────────────────────\n /** A new scope type in `organizationId`. */\n createType(organizationId: Uuid, spec: ScopeTypeSpec): Promise<RecordsResult<ScopeType>>;\n /** Change a scope type (only the keys given). */\n updateType(typeId: Uuid, spec: ScopeTypeSpec): Promise<RecordsResult<ScopeType>>;\n /** Archive a scope type; its scopes and fields come back with a restore. */\n archiveType(typeId: Uuid): Promise<RecordsResult<{ id: Uuid }>>;\n restoreType(typeId: Uuid): Promise<RecordsResult<{ id: Uuid }>>;\n /** A new scope of `typeId` in `organizationId`. */\n createScope(organizationId: Uuid, typeId: Uuid, spec: ScopeSpec): Promise<RecordsResult<Scope>>;\n updateScope(scopeId: Uuid, spec: ScopeSpec): Promise<RecordsResult<Scope>>;\n archiveScope(scopeId: Uuid): Promise<RecordsResult<{ id: Uuid }>>;\n restoreScope(scopeId: Uuid): Promise<RecordsResult<{ id: Uuid }>>;\n /** A new context field (column) on a scope type. Answers the field as the read door does. */\n createField(scopeTypeId: Uuid, spec: ContextFieldSpec): Promise<RecordsResult<ContextField>>;\n /** Change a context field (`null` clears a key). Answers the field as the read door does. */\n updateField(fieldId: Uuid, scopeTypeId: Uuid, spec: ContextFieldSpec): Promise<RecordsResult<ContextField>>;\n archiveField(fieldId: Uuid): Promise<RecordsResult<{ id: Uuid }>>;\n restoreField(fieldId: Uuid): Promise<RecordsResult<{ id: Uuid }>>;\n /** Write one cell. */\n writeValue(write: ContextValueWrite): Promise<RecordsResult<ContextValueWritten>>;\n /**\n * G11. The record-store Table a context scope's template-bound item provisions — one per item and\n * scope (`custom.scope_table_provision`). A scope provisioned before the move answers with its moved\n * Table (same id); the Home defaults to the organization's own. `organization_id` null lets the door\n * read the scope's own organization.\n */\n tableProvision(args: { organization_id: Uuid | null; item_id: Uuid; scope_id: Uuid; home_id?: Uuid | null }): Promise<RecordsResult<Uuid>>;\n}\n\nconst uniq = (ids: readonly string[]): string[] => [...new Set(ids.filter(Boolean))];\n\n/** The ids in batches of `size`, each batch one call, answers concatenated in order. */\nasync function inBatches<T>(\n ids: readonly string[],\n size: number,\n call: (batch: string[]) => Promise<RecordsResult<T[] | null>>,\n): Promise<RecordsResult<T[]>> {\n const unique = uniq(ids);\n const batches: string[][] = [];\n for (let i = 0; i < unique.length; i += size) batches.push(unique.slice(i, i + size));\n const answers = await Promise.all(batches.map(call));\n const out: T[] = [];\n for (const a of answers) {\n if (!a.ok) return a;\n out.push(...(a.data ?? []));\n }\n return { ok: true, data: out };\n}\n\n/** A write door's answer: `{ ok, writer, row, store }`. */\ninterface WriteAnswer {\n ok?: boolean;\n row?: Record<string, unknown> | null;\n}\n\nfunction noRow<T>(door: string): RecordsResult<T> {\n return { ok: false, error: { code: \"internal\", message: `${door} answered without the row it wrote.`, diagnostic: `@ai-matrx/records/scopes: ${door}` } };\n}\n\n/** The value door answers its own envelope; its codes, as the package's. */\nconst VALUE_DOOR_CODES: Record<string, RecordsErrorCode> = {\n unauthorized: \"door\",\n forbidden: \"door\",\n forbidden_org: \"door\",\n not_found: \"not_found\",\n invalid_argument: \"invalid_argument\",\n conflict: \"stale_write\",\n unavailable: \"not_supported\",\n};\n\nexport function createScopeDoors(call: ScopeDoorCall): ScopeDoors {\n async function write(door: string, args: Record<string, unknown>): Promise<RecordsResult<Record<string, unknown>>> {\n const res = await call<WriteAnswer>(door, args, `scopes.${door}`);\n if (!res.ok) return res;\n const row = res.data?.row;\n if (!row || typeof row !== \"object\") return noRow(door);\n return { ok: true, data: row };\n }\n\n async function archiveOrRestore(door: string, args: Record<string, unknown>, id: Uuid): Promise<RecordsResult<{ id: Uuid }>> {\n const res = await call<unknown>(door, args, `scopes.${door}`);\n return res.ok ? { ok: true, data: { id } } : res;\n }\n\n async function fieldById(scopeTypeId: Uuid, fieldId: Uuid, door: string): Promise<RecordsResult<ContextField>> {\n const fields = await doors.fields([scopeTypeId]);\n if (!fields.ok) return fields;\n const field = fields.data.find((f) => f.id === fieldId);\n return field ? { ok: true, data: field } : noRow(door);\n }\n\n const doors: ScopeDoors = {\n async tree(organizationIds) {\n const ids = uniq(organizationIds);\n if (ids.length === 0) return { ok: true, data: [] };\n const res = await call<{ types?: StoreTypeRow[]; scopes?: StoreScopeRow[] } | null>(\"context_tree\", { p_organization_ids: ids }, \"scopes.tree\");\n if (!res.ok) return res;\n const byType = new Map<string, Scope[]>();\n for (const s of res.data?.scopes ?? []) {\n const scope = scopeFromStore(s);\n const list = byType.get(scope.scope_type_id) ?? [];\n list.push(scope);\n byType.set(scope.scope_type_id, list);\n }\n return { ok: true, data: (res.data?.types ?? []).map((t) => ({ ...scopeTypeFromStore(t), scopes: byType.get(t.id) ?? [] })) };\n },\n\n async types(organizationIds, options) {\n const withCounts = options?.withCounts ?? true;\n const ids = uniq(organizationIds);\n if (ids.length === 0) return { ok: true, data: { types: [], counts: withCounts ? {} : null } };\n const res = await call<{ types?: StoreTypeRow[] } | null>(\"context_tree_types\", { p_organization_ids: ids, p_with_counts: withCounts }, \"scopes.types\");\n if (!res.ok) return res;\n const rows = res.data?.types ?? [];\n const counts: Record<string, number> | null = withCounts ? {} : null;\n if (counts) for (const r of rows) counts[r.id] = Number(r.scope_count ?? 0);\n return { ok: true, data: { types: rows.map(scopeTypeFromStore), counts } };\n },\n\n async typeScopesPage(scopeTypeId, offset = 0, limit = TYPE_SCOPES_PAGE) {\n const res = await call<{ scopes?: StoreScopeRow[]; total?: number; next_offset?: number | null } | null>(\n \"context_tree_type_scopes\",\n { p_scope_type_id: scopeTypeId, p_offset: offset, p_limit: limit },\n \"scopes.typeScopesPage\",\n );\n if (!res.ok) return res;\n return {\n ok: true,\n data: { scopes: (res.data?.scopes ?? []).map(scopeFromStore), total: Number(res.data?.total ?? 0), next_offset: res.data?.next_offset ?? null },\n };\n },\n\n async search(organizationIds, query, limit = 100) {\n const ids = uniq(organizationIds);\n const q = query.trim();\n if (ids.length === 0 || q === \"\") return { ok: true, data: { scopes: [], total: 0 } };\n const res = await call<{ scopes?: StoreScopeRow[]; total?: number } | null>(\n \"context_tree_search\",\n { p_organization_ids: ids, p_query: q, p_limit: limit },\n \"scopes.search\",\n );\n if (!res.ok) return res;\n return { ok: true, data: { scopes: (res.data?.scopes ?? []).map(scopeFromStore), total: Number(res.data?.total ?? 0) } };\n },\n\n async scopes(ids) {\n const res = await inBatches(ids, SCOPES_PER_CALL, (batch) => call<StoreScopeRow[]>(\"context_scopes\", { p_scope_ids: batch }, \"scopes.scopes\"));\n return res.ok ? { ok: true, data: res.data.map(scopeWithTypeFromStore) } : res;\n },\n\n async fields(scopeTypeIds) {\n const res = await inBatches(scopeTypeIds, SCOPE_TYPES_PER_FIELDS_CALL, (batch) =>\n call<StoreItemRow[]>(\"context_items\", { p_scope_type_ids: batch }, \"scopes.fields\"),\n );\n return res.ok ? { ok: true, data: res.data.map(contextFieldFromStore) } : res;\n },\n\n async field(fieldId, organizationIds) {\n const orgs = uniq(organizationIds);\n const answers = await Promise.all(\n orgs.map((org) =>\n call<Array<{ id: string; document?: { entity_definition_id?: unknown } | null }> | null>(\n \"read_records_by_ids\",\n { p_organization_id: org, p_table_id: FIELD_KERNEL_ID, p_record_ids: [fieldId], p_by_id: false },\n \"scopes.field\",\n ),\n ),\n );\n let refusal: RecordsResult<ContextField> | null = null;\n for (const answer of answers) {\n if (!answer.ok) {\n refusal ??= answer;\n continue;\n }\n const typeId = answer.data?.find((r) => r.id === fieldId)?.document?.entity_definition_id;\n if (typeof typeId !== \"string\") continue;\n const fields = await doors.fields([typeId]);\n if (!fields.ok) return fields;\n const field = fields.data.find((f) => f.id === fieldId);\n if (field) return { ok: true, data: field };\n }\n return (\n refusal ?? {\n ok: false,\n error: { code: \"not_found\", message: \"This context field could not be found.\", diagnostic: `@ai-matrx/records/scopes: field ${fieldId}` },\n }\n );\n },\n\n async values(scopeIds, options) {\n const res = await inBatches(scopeIds, SCOPES_PER_VALUES_CALL, (batch) =>\n call<StoreValueRow[]>(\"context_values\", { p_scope_ids: batch }, \"scopes.values\"),\n );\n if (!res.ok) return res;\n const cells = res.data.map(contextValueFromStore);\n await completeWholeValues(cells, options?.readFileText ?? null);\n return { ok: true, data: cells };\n },\n\n async archivedTypes(organizationId) {\n const res = await call<StoreArchivedTypeRow[] | null>(\"context_archived_types\", { p_organization_id: organizationId }, \"scopes.archivedTypes\");\n return res.ok ? { ok: true, data: (res.data ?? []).map(archivedScopeTypeFromStore) } : res;\n },\n\n async archivedScopesOfType(organizationId, scopeTypeId, wanted) {\n const out: ArchivedScope[] = [];\n for (let offset = 0; out.length < wanted.size; offset += ARCHIVED_SCOPES_PAGE) {\n const res = await call<Array<{ id: string; document?: { name?: unknown; slug?: unknown } | null; archived_at?: string | null }> | null>(\n \"read_records_archived\",\n { p_organization_id: organizationId, p_table_id: scopeTypeId, p_lane: \"org\", p_by_id: false, p_limit: ARCHIVED_SCOPES_PAGE, p_offset: offset },\n \"scopes.archivedScopesOfType\",\n );\n if (!res.ok) return res;\n const rows = res.data ?? [];\n for (const r of rows) {\n if (!wanted.has(r.id)) continue;\n out.push({\n id: r.id,\n name: typeof r.document?.name === \"string\" ? r.document.name : null,\n slug: typeof r.document?.slug === \"string\" ? r.document.slug : null,\n archived_at: r.archived_at ?? null,\n });\n }\n if (rows.length < ARCHIVED_SCOPES_PAGE) break;\n }\n return { ok: true, data: out };\n },\n\n async systemItems() {\n const res = await call<StoreSystemItemRow[] | null>(\"context_system_items\", {}, \"scopes.systemItems\");\n return res.ok ? { ok: true, data: (res.data ?? []).map(systemContextFieldFromStore) } : res;\n },\n\n async tableTemplates(organizationId) {\n const res = await call<TableTemplate[] | null>(\"table_templates\", { p_org_id: organizationId }, \"scopes.tableTemplates\");\n return res.ok ? { ok: true, data: Array.isArray(res.data) ? res.data : [] } : res;\n },\n\n async templates() {\n const res = await call<ScopeTemplate[] | null>(\"context_templates\", {}, \"scopes.templates\");\n return res.ok ? { ok: true, data: res.data ?? [] } : res;\n },\n\n async createType(organizationId, spec) {\n const slug = resolveSlug(spec.slug, spec.label_plural || spec.label_singular || \"\");\n if (!slug.ok) return slug;\n const res = await write(\"context_type_write\", {\n p_organization_id: organizationId,\n p_type_id: null,\n p_spec: definedOnly({\n label_singular: spec.label_singular,\n label_plural: spec.label_plural,\n icon: spec.icon ?? \"folder\",\n description: spec.description ?? \"\",\n sort_order: spec.sort_order ?? 0,\n max_assignments: spec.max_assignments_per_entity ?? undefined,\n default_variable_keys: spec.default_variable_keys ?? [],\n color: spec.color,\n slug: slug.data,\n }),\n });\n return res.ok ? { ok: true, data: scopeTypeFromStore(res.data as unknown as StoreTypeRow) } : res;\n },\n\n async updateType(typeId, spec) {\n let slug: string | undefined;\n if (spec.slug !== undefined) {\n const resolved = resolveSlug(spec.slug, spec.label_plural ?? spec.label_singular ?? \"\");\n if (!resolved.ok) return resolved;\n slug = resolved.data;\n }\n const res = await write(\"context_type_write\", {\n p_organization_id: null,\n p_type_id: typeId,\n p_spec: definedOnly({\n label_singular: spec.label_singular,\n label_plural: spec.label_plural,\n icon: spec.icon,\n description: spec.description,\n sort_order: spec.sort_order,\n max_assignments: spec.max_assignments_per_entity,\n color: spec.color,\n slug,\n }),\n });\n return res.ok ? { ok: true, data: scopeTypeFromStore(res.data as unknown as StoreTypeRow) } : res;\n },\n\n archiveType: (typeId) => archiveOrRestore(\"context_type_archive\", { p_type_id: typeId }, typeId),\n restoreType: (typeId) => archiveOrRestore(\"context_type_restore\", { p_type_id: typeId }, typeId),\n\n async createScope(organizationId, typeId, spec) {\n const slug = resolveSlug(spec.slug, spec.name ?? \"\");\n if (!slug.ok) return slug;\n const res = await write(\"context_scope_write\", {\n p_organization_id: organizationId,\n p_scope_id: null,\n p_type_id: typeId,\n p_spec: definedOnly({\n name: spec.name,\n parent_scope_id: spec.parent_scope_id,\n description: spec.description ?? \"\",\n settings: spec.settings ?? {},\n slug: slug.data,\n sort_order: spec.sort_order,\n }),\n });\n return res.ok ? { ok: true, data: scopeFromStore(res.data as unknown as StoreScopeRow) } : res;\n },\n\n async updateScope(scopeId, spec) {\n let slug: string | undefined;\n if (spec.slug !== undefined) {\n const resolved = resolveSlug(spec.slug, spec.name ?? \"\");\n if (!resolved.ok) return resolved;\n slug = resolved.data;\n }\n const res = await write(\"context_scope_write\", {\n p_organization_id: null,\n p_scope_id: scopeId,\n p_type_id: null,\n p_spec: definedOnly({ name: spec.name, description: spec.description, settings: spec.settings, slug, sort_order: spec.sort_order }),\n });\n return res.ok ? { ok: true, data: scopeFromStore(res.data as unknown as StoreScopeRow) } : res;\n },\n\n archiveScope: (scopeId) => archiveOrRestore(\"context_scope_archive\", { p_scope_id: scopeId }, scopeId),\n restoreScope: (scopeId) => archiveOrRestore(\"context_scope_restore\", { p_scope_id: scopeId }, scopeId),\n\n async createField(scopeTypeId, spec) {\n const res = await write(\"context_item_write\", {\n p_item_id: null,\n p_scope_type_id: scopeTypeId,\n p_spec: fieldSpecForDoor({ kind: \"string\", description: \"\", context_policy: \"on_request\", sensitivity: \"internal\", tags: [], ...spec }),\n });\n if (!res.ok) return res;\n return fieldById(scopeTypeId, String(res.data.id), \"context_item_write\");\n },\n\n async updateField(fieldId, scopeTypeId, spec) {\n const res = await write(\"context_item_write\", { p_item_id: fieldId, p_scope_type_id: null, p_spec: fieldSpecForDoor(spec) });\n if (!res.ok) return res;\n return fieldById(scopeTypeId, fieldId, \"context_item_write\");\n },\n\n archiveField: (fieldId) => archiveOrRestore(\"context_item_archive\", { p_item_id: fieldId }, fieldId),\n restoreField: (fieldId) => archiveOrRestore(\"context_item_restore\", { p_item_id: fieldId }, fieldId),\n\n async writeValue(cell) {\n const res = await call<{ ok?: boolean; data?: { version?: number; source_type?: string }; error?: { code?: string; message?: string } } | null>(\n \"context_value_write\",\n { p_payload: { source_type: \"ai_enriched\", ...valuePayloadForDoor(cell) } },\n \"scopes.writeValue\",\n );\n if (!res.ok) return res;\n const envelope = res.data ?? {};\n if (!envelope.ok) {\n const code = VALUE_DOOR_CODES[envelope.error?.code ?? \"\"] ?? \"internal\";\n return { ok: false, error: { code, message: envelope.error?.message ?? \"The value was not saved.\" } };\n }\n return {\n ok: true,\n data: {\n scope_id: cell.scope_id,\n field_id: cell.field_id,\n version: Number(envelope.data?.version ?? 1),\n source_type: String(envelope.data?.source_type ?? cell.source_type ?? \"ai_enriched\"),\n },\n };\n },\n\n tableProvision({ organization_id, item_id, scope_id, home_id }) {\n return call<Uuid>(\n \"scope_table_provision\",\n { p_organization_id: organization_id, p_item_id: item_id, p_scope_id: scope_id, p_home_id: home_id ?? null },\n \"scopeTableProvision\",\n );\n },\n };\n return doors;\n}\n","// src/core/storeDoors.ts — @ai-matrx/records (HEADLESS)\n//\n// THE ONE PLACE AN APP'S OWN CODE REACHES THE STORE'S DOORS WITHOUT A TYPED CLIENT METHOD\n// (lane ONE-DOOR, 2026-10-10). Only this package says `custom`; an app file never types the\n// schema, so `check:no-custom-store-code` (matrx-frontend) holds the line at zero.\n//\n// WHAT IT IS: `storeDoors(client)` binds ANY supabase-js client to the store's schema and hands\n// back `rpc(fn, args)`. It is a pure move of the hand-written `.schema(\"custom\")` layers the\n// website grew (public form, booking, e-sign and portal lanes; the template gallery; the page\n// seeds): the answer is exactly what PostgREST gave, `{ data, error }`, nothing wrapped,\n// nothing softened, nothing retried.\n//\n// PRIVILEGES ARE THE CLIENT'S, NEVER THIS FILE'S. This holds no key and opens no connection.\n// Hand it the person's browser client and every door runs as the person; hand it a server\n// session client and it runs as that session; hand it the service-role (admin) client — as the\n// public form / booking / e-sign / portal lanes must, for a visitor with no session — and it\n// runs as the service role. A call never gets wider or narrower by passing through here.\n// `/core` and the server both use the same function: it needs no DOM and no React.\n//\n// The named doors below are one-line members of the same `rpc` (door name + argument names live\n// here, once). Each returns the raw `{ data, error }` so a caller that already reads that shape\n// moves with no behaviour change; a caller that wants `RecordsResult` uses `RecordsClient`.\n\nimport { supabaseDataSource } from \"./supabase\";\nimport type { RecordsDataSource } from \"../ports\";\n\n/** The schema every door of the record store lives in. The only place an app-facing string says it. */\nexport const STORE_SCHEMA = \"custom\";\n\n/** What a door refused with, as PostgREST gave it. */\nexport interface StoreDoorError {\n message: string;\n code?: string | null;\n hint?: string | null;\n details?: string | null;\n}\n\nexport interface StoreDoorAnswer<T = unknown> {\n data: T | null;\n error: StoreDoorError | null;\n}\n\n/** The bare caller: the same `rpc(fn, args)` shape the hand-written layers declared. */\nexport interface StoreCaller {\n rpc(fn: string, args?: Record<string, unknown>): PromiseLike<{ data: unknown; error: StoreDoorError | null }>;\n}\n\n/** The named doors an app calls most. Every member is a thin call over `rpc`; nothing is added to the answer. */\nexport interface StoreDoors extends StoreCaller {\n /** `custom.where_id_opens(p_id)` — which organization an object lives in. `data` is null when it is not given to the caller; the error is plain JSON (it streams to a browser as is). */\n whereIdOpens(id: string): PromiseLike<{ data: unknown; error: { code: string | null; message: string } | null }>;\n /** `custom.table_kernel_id()` — the id of the store's Table kernel (a constant of the store). */\n tableKernelId(): PromiseLike<StoreDoorAnswer<string>>;\n /** `custom.read_records_by_ids` — the records of `ids` the caller may read in `tableId`, in `organizationId`. */\n readRecordsByIds(organizationId: string, tableId: string, ids: readonly string[]): PromiseLike<StoreDoorAnswer>;\n /** `custom.read_records_page` — one page; `args` are the door's own named arguments. */\n readRecordsPage(args: Record<string, unknown>): PromiseLike<StoreDoorAnswer>;\n /** `custom.record_table` — the table a record lives in. */\n recordTable(organizationId: string, recordId: string): PromiseLike<StoreDoorAnswer<string>>;\n /** `custom.applicable_fields` — the fields of a table. */\n applicableFields(organizationId: string, tableId: string): PromiseLike<StoreDoorAnswer>;\n /** `custom.field_declare` — declare one field on a table. */\n fieldDeclare(organizationId: string, tableId: string, spec: Record<string, unknown>): PromiseLike<StoreDoorAnswer<string>>;\n /** `custom.record_update` — patch a record's values. */\n recordUpdate(organizationId: string, recordId: string, patch: Record<string, unknown>): PromiseLike<StoreDoorAnswer>;\n /** `custom.entity_reference_words` — the labels of `{token,id}` refs, withheld when the caller may not open them. */\n entityReferenceWords(organizationId: string, refs: ReadonlyArray<{ token: string; id: string }>): PromiseLike<StoreDoorAnswer>;\n /** `custom.templates` — the catalogue (one page of cards for `filter`). */\n templates(filter: Record<string, unknown>): PromiseLike<StoreDoorAnswer>;\n /** `custom.template_from_tables` — draft a template spec from existing tables. */\n templateFromTables(args: { organizationId: string; tableIds: readonly string[]; includeRows: boolean; rowsPerTable: number }): PromiseLike<StoreDoorAnswer>;\n /** `custom.template_declare` — declare a template (`scope` is `\"org\"` for an organization's own). */\n templateDeclare(scope: string, spec: Record<string, unknown>): PromiseLike<StoreDoorAnswer>;\n /** `custom.template_keep` — keep a one-off template in the organization's own. */\n templateKeep(templateId: string): PromiseLike<StoreDoorAnswer>;\n /** `custom.template_archive` — archive (or, with `restore`, bring back) an organization's own template. */\n templateArchive(templateId: string, restore?: boolean): PromiseLike<StoreDoorAnswer>;\n /** `custom.template_install_claim` — the host step's lease on one install step. */\n templateInstallClaim(args: { organizationId: string; installId: string; kind: string; label: string; sourceId?: string | null; leaseSeconds: number }): PromiseLike<StoreDoorAnswer>;\n /** `custom.template_install_note` — record the thing a host step made. */\n templateInstallNote(args: { organizationId: string; installId: string; kind: string; id: string; label: string }): PromiseLike<StoreDoorAnswer>;\n}\n\n/**\n * Bind a supabase-js client (browser, server session, anon, or service-role) to the store's\n * doors. A client with no `schema()` is refused by name on every call (`data_source_unbound`), never\n * a thrown `undefined is not a function` in a render.\n */\nexport function storeDoors(client: unknown): StoreDoors {\n const source: RecordsDataSource = supabaseDataSource((client ?? {}) as object);\n const call = (fn: string, args: Record<string, unknown> = {}) =>\n source.rpc(fn, args, { schema: STORE_SCHEMA }) as PromiseLike<{ data: unknown; error: StoreDoorError | null }>;\n const typed = <T>(fn: string, args: Record<string, unknown>) => call(fn, args) as PromiseLike<StoreDoorAnswer<T>>;\n return {\n rpc: call,\n async whereIdOpens(id) {\n const raw = await call(\"where_id_opens\", { p_id: id });\n const e = raw.error as { code?: unknown; message?: unknown } | null;\n return {\n data: raw.data ?? null,\n error: e\n ? { code: typeof e.code === \"string\" ? e.code : null, message: typeof e.message === \"string\" ? e.message : \"The record store refused.\" }\n : null,\n };\n },\n tableKernelId: () => typed<string>(\"table_kernel_id\", {}),\n readRecordsByIds: (organizationId, tableId, ids) =>\n typed(\"read_records_by_ids\", { p_organization_id: organizationId, p_table_id: tableId, p_record_ids: ids }),\n readRecordsPage: (args) => typed(\"read_records_page\", args),\n recordTable: (organizationId, recordId) => typed<string>(\"record_table\", { p_organization_id: organizationId, p_record_id: recordId }),\n applicableFields: (organizationId, tableId) => typed(\"applicable_fields\", { p_organization_id: organizationId, p_table_id: tableId }),\n fieldDeclare: (organizationId, tableId, spec) =>\n typed<string>(\"field_declare\", { p_organization_id: organizationId, p_table_id: tableId, p_spec: spec }),\n recordUpdate: (organizationId, recordId, patch) =>\n typed(\"record_update\", { p_organization_id: organizationId, p_record_id: recordId, p_patch: patch }),\n entityReferenceWords: (organizationId, refs) =>\n typed(\"entity_reference_words\", { p_organization_id: organizationId, p_refs: refs.map((r) => ({ token: r.token, id: r.id })) }),\n templates: (filter) => typed(\"templates\", { p_filter: filter }),\n templateFromTables: ({ organizationId, tableIds, includeRows, rowsPerTable }) =>\n typed(\"template_from_tables\", {\n p_organization_id: organizationId,\n p_table_ids: tableIds,\n p_include_rows: includeRows,\n p_rows_per_table: rowsPerTable,\n }),\n templateDeclare: (scope, spec) => typed(\"template_declare\", { p_scope: scope, p_spec: spec }),\n templateKeep: (templateId) => typed(\"template_keep\", { p_template_id: templateId }),\n templateArchive: (templateId, restore) =>\n typed(\"template_archive\", restore === undefined ? { p_template_id: templateId } : { p_template_id: templateId, p_restore: restore }),\n templateInstallClaim: ({ organizationId, installId, kind, label, sourceId, leaseSeconds }) =>\n typed(\"template_install_claim\", {\n p_organization_id: organizationId,\n p_install_id: installId,\n p_kind: kind,\n p_label: label,\n ...(sourceId ? { p_source_id: sourceId } : {}),\n p_lease_seconds: leaseSeconds,\n }),\n templateInstallNote: ({ organizationId, installId, kind, id, label }) =>\n typed(\"template_install_note\", {\n p_organization_id: organizationId,\n p_install_id: installId,\n p_kind: kind,\n p_id: id,\n p_label: label,\n }),\n };\n}\n","// src/core/table-logic.ts — the table owner's pure logic (HEADLESS: no React, no DOM, no network).\n//\n// Moved from matrx-frontend `features/data-tables` (W1-G2b, owner ruling 2026-10-16): the column and\n// row shapes the grid draws, the bulk-write op shapes and their guards, the service-result envelope,\n// and the two pure rules every importer shares (a value's data type; a display name's field key).\n// matrx-frontend `features/data-tables/types` re-exports these names; there is one definition.\n// `getTableMetadata` stays an app seam (it needs the app's table-home lookup) and is NOT here.\n\nimport type { RecordsError } from \"../results\";\n\n/** A database JSON column. Nothing is assumed about it; a reader narrows what it reads. */\nexport type Json = unknown;\n\n/** `public.field_data_type`. */\nexport type FieldDataType = \"string\" | \"number\" | \"integer\" | \"boolean\" | \"date\" | \"datetime\" | \"json\" | \"array\";\n\n/** A column as the grid draws it. */\nexport type DatasetField = {\n id: string;\n table_id: string;\n field_name: string;\n display_name: string;\n data_type: FieldDataType;\n field_order: number;\n is_required: boolean;\n is_public: boolean;\n default_value: Json | null;\n validation_rules: Json | null;\n metadata: Json;\n custom_fields: Json;\n organization_id: string;\n user_id: string;\n created_at: string;\n created_by: string | null;\n updated_at: string;\n updated_by: string | null;\n deleted_at: string | null;\n version: number;\n};\n\n/** A row as the grid holds it. */\nexport type DatasetRow = {\n id: string;\n table_id: string;\n data: Json;\n metadata: Json;\n custom_fields: Json;\n is_public: boolean;\n organization_id: string;\n user_id: string;\n source_row_ref: string | null;\n created_at: string;\n created_by: string | null;\n updated_at: string;\n updated_by: string | null;\n deleted_at: string | null;\n version: number;\n};\n\n\n// ─── Bulk-write op shapes ───────────────────────────────────────────────────\n\nexport type BulkInsertOp = {\n op: \"insert\";\n data: Record<string, unknown>;\n};\n\nexport type BulkUpdateOp = {\n op: \"update\";\n row_id: string;\n /** REPLACES the row's data wholesale. Keys not in `data` are dropped. */\n data: Record<string, unknown>;\n /**\n * The version the person saw this row at, when the caller holds it (an undo carries the version its\n * own write produced). Absent = the seam's ledger of the rows it drew (`lib/records/record-versions.ts`).\n */\n expected_version?: number | null;\n};\n\nexport type BulkMergeOp = {\n op: \"merge\";\n row_id: string;\n /**\n * Partial update — `data = existing_data || patch`. Keys in `data` overwrite\n * the row's matching keys; keys absent from `data` are preserved. Use this\n * when sending only changed fields.\n */\n data: Record<string, unknown>;\n /**\n * The version the person saw this row at, when the caller holds it (an undo carries the version its\n * own write produced). Absent = the seam's ledger of the rows it drew (`lib/records/record-versions.ts`).\n */\n expected_version?: number | null;\n};\n\nexport type BulkCellOp = {\n op: \"cell\";\n row_id: string;\n field_name: string;\n value: unknown;\n /**\n * The version the person saw this row at, when the caller holds it (an undo carries the version its\n * own write produced). Absent = the seam's ledger of the rows it drew (`lib/records/record-versions.ts`).\n */\n expected_version?: number | null;\n};\n\nexport type BulkDeleteOp = {\n op: \"delete\";\n row_id: string;\n};\n\nexport type BulkOp =\n | BulkInsertOp\n | BulkUpdateOp\n | BulkMergeOp\n | BulkCellOp\n | BulkDeleteOp;\n\n/**\n * Per-op result envelope returned inside `bulkWrite`'s `results[]`.\n *\n * Note: insert / update / cell / delete that succeed return the full row.\n * Update / cell / delete against a row that is gone return `row_not_found`;\n * update / cell / merge against a row that is in Trash return `row_in_trash`\n * (with the server's own sentence in `message`). Both are soft failures — the\n * rest of the batch continues. Inserts that fail RAISE and abort the batch.\n */\nexport type BulkOpError = {\n error: \"row_not_found\" | \"row_in_trash\";\n row_id: string;\n message?: string;\n};\nexport type BulkOpResult = DatasetRow | BulkOpError;\n\n/**\n * Narrow a bulk-write result slot to the error variant.\n * Successful results carry the full DatasetRow shape (no discriminator key\n * on the success side, so consumers narrow via this guard).\n */\nexport function isBulkOpError(r: BulkOpResult): r is BulkOpError {\n return typeof r === \"object\" && r !== null && \"error\" in r;\n}\n\n/**\n * One plain sentence for the rows a batch could not change — the ONE wording\n * every bulk surface uses. A row in Trash is named as such (it can be restored),\n * never reported as \"could not be found\".\n */\nexport function describeBulkFailures(failed: BulkOpError[]): string {\n const inTrash = failed.filter((f) => f.error === \"row_in_trash\").length;\n const missing = failed.length - inTrash;\n const parts: string[] = [];\n if (inTrash > 0) {\n parts.push(\n `${inTrash} row${inTrash === 1 ? \" is\" : \"s are\"} in Trash — restore ${inTrash === 1 ? \"it\" : \"them\"} from Trash to edit`,\n );\n }\n if (missing > 0) {\n parts.push(\n `${missing} row${missing === 1 ? \"\" : \"s\"} could not be found — ${missing === 1 ? \"it\" : \"they\"} may have been removed by someone else`,\n );\n }\n return `${parts.join(\"; \")}.`;\n}\n\n\nexport type BulkWriteResponse = {\n table_id: string;\n count: number;\n results: BulkOpResult[];\n};\n\n// ─── Service result envelope ────────────────────────────────────────────────\n\nexport type ServiceOk<T> = { success: true; data: T };\n/**\n * THE STORE'S OWN REFUSAL, kept whole (lane FIX-15, 2026-09-23).\n *\n * `error` is `PostgrestError.message` and nothing else, so a refusal written as\n * three parts — what happened, what the column is, what to do instead — reached\n * the screen as one third of itself, and the other two thirds (DETAIL and HINT)\n * were thrown away in this envelope. On production a name typed into a relation\n * column was refused by the store with a perfectly good sentence\n * and the person saw nothing usable.\n *\n * `refusal` carries the whole thing in the shape every Matrx screen already\n * knows how to draw (`RefusalNotice` / `RefusalLine` from `@ai-matrx/records-ui`,\n * which run it through `plainWords` so no machine identity is ever printed at a\n * person). `error` stays exactly what it was for the callers that print a line.\n */\nexport type ServiceErr = { success: false; error: string; refusal?: RecordsError };\nexport type ServiceResult<T> = ServiceOk<T> | ServiceErr;\n\n/**\n * Narrow a ServiceResult to the failure variant. Use instead of `!result.success`\n * inside generic functions where TS's narrow through `Promise<ServiceResult<T>>`\n * sometimes fails to discriminate the union members reliably.\n */\nexport function isServiceFailure<T>(r: ServiceResult<T>): r is ServiceErr {\n return r.success === false;\n}\n\n\n// ─── A value's data type ────────────────────────────────────────────────────\n\nconst DATE_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\nconst DATETIME_PATTERN = /^\\d{4}-\\d{2}-\\d{2}[T\\s]\\d{2}:\\d{2}/;\n\n/**\n * Infer a table column's data type for a single value. Used by both the\n * CSV/Excel import path and the JSON-to-table path. The returned strings\n * align with `VALID_DATA_TYPES` in `table-utils.ts`.\n */\nexport function inferDataType(value: unknown): string {\n if (value === null || value === undefined || value === \"\") return \"string\";\n\n if (typeof value === \"boolean\") return \"boolean\";\n\n if (typeof value === \"number\") {\n return Number.isInteger(value) ? \"integer\" : \"number\";\n }\n\n if (typeof value === \"object\") {\n return Array.isArray(value) ? \"array\" : \"json\";\n }\n\n // Strings — try numeric parse, then date patterns, then boolean keywords,\n // else fall back to string.\n const str = String(value);\n const num = Number(str);\n if (!isNaN(num) && str.trim() !== \"\") {\n return Number.isInteger(num) ? \"integer\" : \"number\";\n }\n\n const lower = str.toLowerCase().trim();\n if (lower === \"true\" || lower === \"false\") return \"boolean\";\n\n if (DATE_PATTERN.test(str)) return \"date\";\n if (DATETIME_PATTERN.test(str)) return \"datetime\";\n\n return \"string\";\n}\n\n// ─── A display name's field key ─────────────────────────────────────────────\n\n/**\n * Sanitize a display name into a valid field name\n * Converts to lowercase, replaces special chars with underscores, follows snake_case\n * \n * @param displayName - The user-entered display name\n * @returns Sanitized field name in snake_case format\n * \n * @example\n * sanitizeFieldName(\"Total Revenue\") // returns \"total_revenue\"\n * sanitizeFieldName(\"Price ($)\") // returns \"price\"\n * sanitizeFieldName(\"2024 Sales\") // returns \"_2024_sales\"\n */\nexport function sanitizeFieldName(displayName: string): string {\n if (!displayName || typeof displayName !== 'string') {\n return '';\n }\n\n return displayName\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9\\s_]/g, '') // Remove special chars (keep letters, numbers, spaces, underscores)\n .replace(/\\s+/g, '_') // Spaces to underscores\n .replace(/^_+|_+$/g, '') // Trim leading/trailing underscores\n .replace(/_+/g, '_') // Collapse multiple underscores\n .replace(/^(\\d)/, '_$1'); // Prefix if starts with number\n}\n\n/**\n * Validate that a field name follows the required format\n * Must start with lowercase letter, contain only lowercase letters, numbers, and underscores\n * \n * @param fieldName - The field name to validate\n * @returns true if valid, false otherwise\n * \n * @example\n * validateFieldName(\"total_revenue\") // returns true\n * validateFieldName(\"Total Revenue\") // returns false\n * validateFieldName(\"123_sales\") // returns false\n */\nexport function validateFieldName(fieldName: string): boolean {\n if (!fieldName || typeof fieldName !== 'string') {\n return false;\n }\n \n return /^[a-z][a-z0-9_]*$/.test(fieldName);\n}\n","// src/objectOrganization.ts — @ai-matrx/records (HEADLESS)\n//\n// WHICH ORGANIZATION OWNS THIS RECORD — READ FROM THE OBJECT, NEVER FROM THE PERSON (lane ACCESS-IS-PERSONAL;\n// moved from the website's features/unified-data/objectOrganization.ts, step 10, 2026-10-08).\n//\n// Every store door takes an organization and checks it first. An object page must hand the doors the\n// organization the OBJECT lives in, never the one the person picked: `custom.where_id_opens(p_id)` — the\n// store's one door that reads an object's organization from its own id (table, record, dashboard, digest,\n// form, booking, portal, rendered document) — answers only when the person could already open it.\n//\n// IT IS A PORT. `RecordOrganizationPort` is what `createRecords` accepts; `whereIdOpensPort(dataSource)` is\n// the default (one door call per ask). A host that keeps answers across remounts or seeds them from a server\n// render (the website's kept-answer store) supplies its own implementation over the same reader.\n//\n// THE ANSWER IS THE PERSON'S. Zero rows means \"not given to you\" and \"not there\" alike; \"we could not ask\"\n// is a third answer and is never folded into either. No stand-in: a miss says so and the page holds.\n\nimport type { RecordsDataSource } from \"./ports\";\n\n/** What kind of object the id is, as `custom.where_id_opens` names it — carried as the door's own word. */\nexport type ObjectKind = string;\n\nexport type ObjectOrganizationAnswer =\n /** The store named the object's organization, and the person may open the object. */\n | {\n state: \"found\";\n organizationId: string;\n kind: ObjectKind;\n /** The screen the store says opens it (`/data/<table>?record=…`), or null for a part with none. */\n path: string | null;\n /** False when it is in the trash — the person may still open it, to bring it back. */\n live: boolean;\n /** The id it answers as — a merged record's survivor. */\n resolvedId: string;\n }\n /** Not given to this person — or not there at all. The store does not say which, on purpose. */\n | { state: \"not-given\" }\n /** We could not ask. NOT an answer about the person's access. */\n | { state: \"unavailable\"; why: string };\n\n/** Which organization owns an object — the port `createRecords({ organizationOf })` accepts. */\nexport interface RecordOrganizationPort {\n organizationOf(id: string): Promise<ObjectOrganizationAnswer>;\n}\n\ninterface WhereIdOpens {\n kind?: unknown;\n organization_id?: unknown;\n path?: unknown;\n live?: unknown;\n resolved_id?: unknown;\n}\n\nexport const WHERE_ID_OPENS_DOOR = \"where_id_opens\";\n\nfunction doorIsAbsent(error: { code?: string | null; message?: string | null }): boolean {\n if (error.code === \"PGRST202\" || error.code === \"42883\") return true;\n return /could not find the function/i.test(error.message ?? \"\");\n}\n\nconst DOOR_ABSENT_WHY =\n \"custom.where_id_opens is missing from this database, so this page cannot tell which \" +\n \"organization the record lives in and holds instead of guessing. Remedy: the chair applies \" +\n \"migrations/campaign/openbyid_one_address_opens_any_id.sql and openbyid_the_resolver_can_be_reached.sql.\";\n\n/** Ask the store which organization `id` lives in — the one call an object page makes before any other door. */\nexport async function resolveObjectOrganization(dataSource: Pick<RecordsDataSource, \"rpc\">, id: string): Promise<ObjectOrganizationAnswer> {\n let answered: { data: unknown; error: { code?: string | null; message?: string | null } | null };\n try {\n answered = (await dataSource.rpc(WHERE_ID_OPENS_DOOR, { p_id: id }, { schema: \"custom\" })) as typeof answered;\n } catch (thrown) {\n return { state: \"unavailable\", why: thrown instanceof Error ? thrown.message : \"The record store did not answer.\" };\n }\n return readObjectOrganizationAnswer(answered, id);\n}\n\n/** Read one `custom.where_id_opens` answer — asked here, or asked by a server render as the same person. */\nexport function readObjectOrganizationAnswer(\n answered: { data: unknown; error: { code?: string | null; message?: string | null } | null },\n id: string,\n): ObjectOrganizationAnswer {\n if (answered.error) {\n if (doorIsAbsent(answered.error)) {\n console.warn(`[@ai-matrx/records] ${DOOR_ABSENT_WHY}`);\n return { state: \"unavailable\", why: DOOR_ABSENT_WHY };\n }\n return { state: \"unavailable\", why: answered.error.message ?? \"The record store refused to say where this is.\" };\n }\n const row = answered.data as WhereIdOpens | null;\n if (row === null || row === undefined) return { state: \"not-given\" };\n // READ STRICTLY. An answer this module cannot read is \"could not ask\", never a guess.\n if (typeof row !== \"object\" || typeof row.organization_id !== \"string\" || typeof row.kind !== \"string\") {\n return { state: \"unavailable\", why: \"The record store answered something this page cannot read.\" };\n }\n return {\n state: \"found\",\n organizationId: row.organization_id,\n kind: row.kind,\n path: typeof row.path === \"string\" ? row.path : null,\n live: row.live !== false,\n resolvedId: typeof row.resolved_id === \"string\" ? row.resolved_id : id,\n };\n}\n\n/** The default port: one `custom.where_id_opens` call per ask, nothing kept. */\nexport function whereIdOpensPort(dataSource: Pick<RecordsDataSource, \"rpc\">): RecordOrganizationPort {\n return { organizationOf: (id) => resolveObjectOrganization(dataSource, id) };\n}\n","// src/door-call/index.ts — @ai-matrx/records/door-call · THE LIGHT DOOR CLIENTS (HEADLESS)\n//\n// What a host's SHELL asks the store for — the scope doors (the chat's scope chip and sources, the\n// scope pickers), the pick-list doors, a raw door through `storeDoors` (the inbox count) — without the\n// records client: no table registry, no generated door catalogue, no field-kind vocabulary, no UI.\n// `/core` is ~600 KB; this entry is the one door call (`createDoorCall`, the SAME function every\n// method of the records client asks through, so primed answers, one-read-in-flight, the schema said\n// out loud and `door_absent` behave identically) plus the door wrappers. Where records UI renders,\n// the full client (`/core`) loads as before. Guard: `src/door-call/door-call-entry.test.ts`.\n\nimport { asRecordsDataSource } from \"../core/supabase\";\nimport { createDoorCall, type DoorCall, type DoorCallOptions } from \"../core/doorCall\";\nimport { createPickListDoors, type PickListDoors } from \"../core/pickListDoors\";\nimport { createScopeDoors, type ScopeDoors } from \"../scopes/doors\";\n\nexport {\n createDoorCall,\n canonicalArgs,\n doorAbsentRefusal,\n primedDoorAnswer,\n recordsErrorSink,\n isAPersonsRefusal,\n A_PERSONS_REFUSAL,\n DEFAULT_DOOR_SCHEMA,\n type DoorCall,\n type DoorCallOptions,\n} from \"../core/doorCall\";\nexport { createPickListDoors, PICK_LIST_DOORS, type PickListDoors } from \"../core/pickListDoors\";\nexport { createScopeDoors, type ScopeDoors, type ScopeDoorCall } from \"../scopes/doors\";\nexport { storeDoors, STORE_SCHEMA, type StoreDoors, type StoreCaller, type StoreDoorAnswer, type StoreDoorError } from \"../core/storeDoors\";\nexport { supabaseDataSource, asRecordsDataSource, type SupabaseLike } from \"../core/supabase\";\n\n// What shell services narrow and resolve with, also without the client: the bulk/service result\n// helpers (pure) and the \"which organization owns this object\" door read.\nexport {\n isBulkOpError,\n describeBulkFailures,\n isServiceFailure,\n type BulkOpError,\n type BulkOpResult,\n type ServiceErr,\n type ServiceOk,\n type ServiceResult,\n} from \"../core/table-logic\";\nexport {\n resolveObjectOrganization,\n readObjectOrganizationAnswer,\n type ObjectKind,\n type ObjectOrganizationAnswer,\n type RecordOrganizationPort,\n} from \"../objectOrganization\";\n\n/** The light options: everything `createDoorCall` takes except the data source, which is bound here. */\nexport type LightDoorOptions = Omit<DoorCallOptions, \"dataSource\">;\n\n/** The one door call over a supabase-js client (or a `RecordsDataSource`), in the store's schema. */\nexport function lightDoorCall(client: unknown, options: LightDoorOptions = {}): DoorCall {\n return createDoorCall({ ...options, dataSource: asRecordsDataSource(client) });\n}\n\n/** The scope doors (`client.scopes` of the records client, without the client). */\nexport function lightScopeDoors(client: unknown, options: LightDoorOptions = {}): ScopeDoors {\n return createScopeDoors(lightDoorCall(client, options));\n}\n\n/** The pick-list doors (`pickListGet` / `pickListForSelection` / `pickListUpdate`, without the client). */\nexport function lightPickListDoors(client: unknown, options: LightDoorOptions = {}): PickListDoors {\n return createPickListDoors(lightDoorCall(client, options));\n}\n"],"mappings":"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","names":["registry"]}
@@ -558,7 +558,19 @@ interface ScopeDoors {
558
558
  }>>;
559
559
  /** Write one cell. */
560
560
  writeValue(write: ContextValueWrite): Promise<RecordsResult<ContextValueWritten>>;
561
+ /**
562
+ * G11. The record-store Table a context scope's template-bound item provisions — one per item and
563
+ * scope (`custom.scope_table_provision`). A scope provisioned before the move answers with its moved
564
+ * Table (same id); the Home defaults to the organization's own. `organization_id` null lets the door
565
+ * read the scope's own organization.
566
+ */
567
+ tableProvision(args: {
568
+ organization_id: Uuid | null;
569
+ item_id: Uuid;
570
+ scope_id: Uuid;
571
+ home_id?: Uuid | null;
572
+ }): Promise<RecordsResult<Uuid>>;
561
573
  }
562
574
  declare function createScopeDoors(call: ScopeDoorCall): ScopeDoors;
563
575
 
564
- export { scopeWithTypeFromStore as $, ARCHIVED_SCOPES_PAGE as A, type ScopeTypeWithScopes as B, type ContextValue as C, type ScopeWithType as D, type StoreSystemItemRow as E, FIELD_KERNEL_ID as F, type StoreWholeValue as G, type SystemContextField as H, INCOMPLETE_SAVE_REFUSAL as I, type SystemContextItemClass as J, type TableTemplate as K, type TableTemplateField as L, completeWholeValues as M, contextFieldFromStore as N, contextFieldKind as O, contextValueFromStore as P, contextValueWrite as Q, type ReadContextFileText as R, type Scope as S, TYPE_SCOPES_PAGE as T, createScopeDoors as U, incompleteSaveRefusal as V, referenceFence as W, referencesFromFence as X, referencesOf as Y, scopeFromStore as Z, scopeTypeFromStore as _, type ContextField as a, settingFromStore as a0, systemContextFieldFromStore as a1, type ContextFieldKind as b, type ContextReference as c, type ArchivedScope as d, type ArchivedScopeType as e, CONTEXT_FIELD_KINDS as f, type ContextFieldSpec as g, type ContextPolicy as h, type ContextSensitivity as i, type ContextValueWrite as j, type ContextValueWritten as k, FILE_KERNEL_ID as l, type IncompleteValue as m, SCOPES_PER_CALL as n, SCOPES_PER_VALUES_CALL as o, SCOPE_TYPES_PER_FIELDS_CALL as p, SYSTEM_CONTEXT_TYPE_ID as q, type ScopeDoorCall as r, type ScopeDoors as s, type ScopePage as t, type ScopeSpec as u, type ScopeTemplate as v, type ScopeType as w, type ScopeTypeLabel as x, type ScopeTypeSkeleton as y, type ScopeTypeSpec as z };
576
+ export { scopeWithTypeFromStore as $, ARCHIVED_SCOPES_PAGE as A, type ScopeTypeSpec as B, type ContextValue as C, type ScopeTypeWithScopes as D, type ScopeWithType as E, FIELD_KERNEL_ID as F, type StoreSystemItemRow as G, type StoreWholeValue as H, INCOMPLETE_SAVE_REFUSAL as I, type SystemContextField as J, type SystemContextItemClass as K, type TableTemplate as L, type TableTemplateField as M, completeWholeValues as N, contextFieldFromStore as O, contextFieldKind as P, contextValueFromStore as Q, type ReadContextFileText as R, type ScopeDoors as S, TYPE_SCOPES_PAGE as T, contextValueWrite as U, incompleteSaveRefusal as V, referenceFence as W, referencesFromFence as X, referencesOf as Y, scopeFromStore as Z, scopeTypeFromStore as _, type ScopeDoorCall as a, settingFromStore as a0, systemContextFieldFromStore as a1, type Scope as b, createScopeDoors as c, type ContextField as d, type ContextFieldKind as e, type ContextReference as f, type ArchivedScope as g, type ArchivedScopeType as h, CONTEXT_FIELD_KINDS as i, type ContextFieldSpec as j, type ContextPolicy as k, type ContextSensitivity as l, type ContextValueWrite as m, type ContextValueWritten as n, FILE_KERNEL_ID as o, type IncompleteValue as p, SCOPES_PER_CALL as q, SCOPES_PER_VALUES_CALL as r, SCOPE_TYPES_PER_FIELDS_CALL as s, SYSTEM_CONTEXT_TYPE_ID as t, type ScopePage as u, type ScopeSpec as v, type ScopeTemplate as w, type ScopeType as x, type ScopeTypeLabel as y, type ScopeTypeSkeleton as z };
@@ -558,7 +558,19 @@ interface ScopeDoors {
558
558
  }>>;
559
559
  /** Write one cell. */
560
560
  writeValue(write: ContextValueWrite): Promise<RecordsResult<ContextValueWritten>>;
561
+ /**
562
+ * G11. The record-store Table a context scope's template-bound item provisions — one per item and
563
+ * scope (`custom.scope_table_provision`). A scope provisioned before the move answers with its moved
564
+ * Table (same id); the Home defaults to the organization's own. `organization_id` null lets the door
565
+ * read the scope's own organization.
566
+ */
567
+ tableProvision(args: {
568
+ organization_id: Uuid | null;
569
+ item_id: Uuid;
570
+ scope_id: Uuid;
571
+ home_id?: Uuid | null;
572
+ }): Promise<RecordsResult<Uuid>>;
561
573
  }
562
574
  declare function createScopeDoors(call: ScopeDoorCall): ScopeDoors;
563
575
 
564
- export { scopeWithTypeFromStore as $, ARCHIVED_SCOPES_PAGE as A, type ScopeTypeWithScopes as B, type ContextValue as C, type ScopeWithType as D, type StoreSystemItemRow as E, FIELD_KERNEL_ID as F, type StoreWholeValue as G, type SystemContextField as H, INCOMPLETE_SAVE_REFUSAL as I, type SystemContextItemClass as J, type TableTemplate as K, type TableTemplateField as L, completeWholeValues as M, contextFieldFromStore as N, contextFieldKind as O, contextValueFromStore as P, contextValueWrite as Q, type ReadContextFileText as R, type Scope as S, TYPE_SCOPES_PAGE as T, createScopeDoors as U, incompleteSaveRefusal as V, referenceFence as W, referencesFromFence as X, referencesOf as Y, scopeFromStore as Z, scopeTypeFromStore as _, type ContextField as a, settingFromStore as a0, systemContextFieldFromStore as a1, type ContextFieldKind as b, type ContextReference as c, type ArchivedScope as d, type ArchivedScopeType as e, CONTEXT_FIELD_KINDS as f, type ContextFieldSpec as g, type ContextPolicy as h, type ContextSensitivity as i, type ContextValueWrite as j, type ContextValueWritten as k, FILE_KERNEL_ID as l, type IncompleteValue as m, SCOPES_PER_CALL as n, SCOPES_PER_VALUES_CALL as o, SCOPE_TYPES_PER_FIELDS_CALL as p, SYSTEM_CONTEXT_TYPE_ID as q, type ScopeDoorCall as r, type ScopeDoors as s, type ScopePage as t, type ScopeSpec as u, type ScopeTemplate as v, type ScopeType as w, type ScopeTypeLabel as x, type ScopeTypeSkeleton as y, type ScopeTypeSpec as z };
576
+ export { scopeWithTypeFromStore as $, ARCHIVED_SCOPES_PAGE as A, type ScopeTypeSpec as B, type ContextValue as C, type ScopeTypeWithScopes as D, type ScopeWithType as E, FIELD_KERNEL_ID as F, type StoreSystemItemRow as G, type StoreWholeValue as H, INCOMPLETE_SAVE_REFUSAL as I, type SystemContextField as J, type SystemContextItemClass as K, type TableTemplate as L, type TableTemplateField as M, completeWholeValues as N, contextFieldFromStore as O, contextFieldKind as P, contextValueFromStore as Q, type ReadContextFileText as R, type ScopeDoors as S, TYPE_SCOPES_PAGE as T, contextValueWrite as U, incompleteSaveRefusal as V, referenceFence as W, referencesFromFence as X, referencesOf as Y, scopeFromStore as Z, scopeTypeFromStore as _, type ScopeDoorCall as a, settingFromStore as a0, systemContextFieldFromStore as a1, type Scope as b, createScopeDoors as c, type ContextField as d, type ContextFieldKind as e, type ContextReference as f, type ArchivedScope as g, type ArchivedScopeType as h, CONTEXT_FIELD_KINDS as i, type ContextFieldSpec as j, type ContextPolicy as k, type ContextSensitivity as l, type ContextValueWrite as m, type ContextValueWritten as n, FILE_KERNEL_ID as o, type IncompleteValue as p, SCOPES_PER_CALL as q, SCOPES_PER_VALUES_CALL as r, SCOPE_TYPES_PER_FIELDS_CALL as s, SYSTEM_CONTEXT_TYPE_ID as t, type ScopePage as u, type ScopeSpec as v, type ScopeTemplate as w, type ScopeType as x, type ScopeTypeLabel as y, type ScopeTypeSkeleton as z };