@ai-matrx/records 0.73.4 → 0.73.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/memory/index.cjs +99 -12
- package/dist/memory/index.cjs.map +1 -1
- package/dist/memory/index.d.cts +7 -1
- package/dist/memory/index.d.ts +7 -1
- package/dist/memory/index.js +99 -12
- package/dist/memory/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/memory/index.ts","../../src/memory/entity.ts","../../src/templates/payloads.ts","../../src/templates/types.ts","../../src/templates/confidential.ts","../../src/templates/extras.ts","../../src/store.generated.ts","../../src/templates/validate.ts","../../src/templates/plan.ts","../../src/choice.ts","../../src/memory/world.ts","../../src/memory/doors.ts"],"sourcesContent":["// src/memory/index.ts — @ai-matrx/records/memory (lane CHAIR-GALLERY-2, 2026-10-05)\n//\n// THE IN-MEMORY RECORD STORE. One call turns a template spec into a `RecordsConfig` every\n// @ai-matrx/records hook and every @ai-matrx/records-ui screen mounts on, read-only:\n//\n// const preview = templatePreview(spec, { today });\n// <RecordsMount config={preview.config}> <TablePage tableId={preview.tables[0].id} /> </RecordsMount>\n//\n// For: template pages, the describe box's \"here is what I will build\" before install, docs, and any\n// migration preview. Nothing it answers is sent anywhere and nothing a person does in it is saved.\n\nimport type { RecordsConfig } from \"../ports\";\nimport type { TemplateSpec } from \"../templates/types\";\nimport { memoryDataSource } from \"./doors\";\nimport { stableId as stableIdOf, templateWorld, type MemoryWorld, type TemplateWorldOptions } from \"./world\";\n\nexport { memoryDataSource, PREVIEW_REFUSAL } from \"./doors\";\nexport { MEMORY_KERNEL, stableId, templateWorld } from \"./world\";\nexport { memoryEntityDescribe, memoryEntityRows, memoryEntityWrite } from \"./entity\";\nexport type { MemoryEntity, MemoryEntityColumn, MemoryEntitySpec } from \"./entity\";\nimport type { MemoryEntitySpec } from \"./entity\";\n\n/** Add standard sources (`{ kind: \"entity\", token }`) to a memory world, in the live doors' shapes. */\nexport function withEntities(world: MemoryWorld, specs: MemoryEntitySpec[]): MemoryWorld {\n const entities = new Map(world.entities ?? []);\n for (const s of specs) entities.set(s.token, { ...s, rows: s.rows.map((r) => ({ ...r })) });\n world.entities = entities;\n return world;\n}\nexport type { MemoryDashboard, MemoryField, MemoryForm, MemoryOption, MemoryTable, MemoryView, MemoryWorld, TemplateWorldOptions } from \"./world\";\n\nexport interface TemplatePreview {\n /** Mount this: `<RecordsMount config={preview.config}>` / `<RecordsProvider config={preview.config}>`. */\n config: RecordsConfig;\n world: MemoryWorld;\n /** The template's tables in its own order: id (for `TablePage`), token, name. */\n tables: Array<{ id: string; token: string; name: string; rows: number }>;\n forms: Array<{ id: string; token: string; title: string; tableId: string; booking: boolean }>;\n dashboards: Array<{ id: string; token: string; name: string; tableId: string }>;\n}\n\n/** A template, installed into memory and ready to mount. Pure for a given spec and day. */\nexport function templatePreview(spec: TemplateSpec, options: TemplateWorldOptions = {}): TemplatePreview {\n const world = templateWorld(spec, options);\n const config: RecordsConfig = {\n dataSource: memoryDataSource(world),\n actor: { actor: \"user\", user_id: world.user_id },\n organizationId: world.organization_id,\n };\n return {\n config,\n world,\n tables: world.tables.map((t) => ({ id: t.id, token: t.token, name: String(t.document[\"name\"] ?? t.token), rows: t.order.length })),\n forms: world.forms.map((f) => ({ id: f.form_id, token: f.token, title: f.title, tableId: f.table_id, booking: f.booking !== null })),\n dashboards: world.dashboards.map((d) => ({ id: d.dashboard_id, token: d.token, name: d.name, tableId: d.table_id })),\n };\n}\n\n/** A memory store holding only standard sources — mount it like a template preview. */\nexport function entityStore(specs: MemoryEntitySpec[], options: { today?: string } = {}): { config: RecordsConfig; world: MemoryWorld } {\n const world: MemoryWorld = {\n organization_id: stableIdOf(\"entity-store-organization\"),\n user_id: stableIdOf(\"entity-store-person\"),\n timezone: \"UTC\",\n today: options.today ?? new Date().toISOString().slice(0, 10),\n businessName: \"\",\n tables: [], tableById: new Map(), views: [], forms: [], dashboards: [],\n recordTable: new Map(), stageField: new Map(),\n };\n withEntities(world, specs);\n return {\n world,\n config: { dataSource: memoryDataSource(world), actor: { actor: \"user\", user_id: world.user_id }, organizationId: world.organization_id },\n };\n}\n","// src/memory/entity.ts — @ai-matrx/records/memory · lane CHAIR-ENTITY-BLOCKS (2026-10-05)\n//\n// A STANDARD SOURCE IN MEMORY: `{ kind: \"entity\", token }` answered the way the live drill doors\n// answer it since chairblk_a (matrx-frontend migrations/campaign/): `drill_describe` names each\n// column already presented (`api.columns`: api_name, name, type, choices, lookup), `drill_rows`\n// returns rows in WORDS (a deal's `stage_id` reads \"Qualified\"), and `entity_row_write` takes a\n// choice by its word. A screen built on an entity source runs on this fake with the same shapes.\n\ntype Json = Record<string, unknown>;\n\n/** One presented column, exactly as `platform.drill_describe(...).api.columns[]` says it. */\nexport interface MemoryEntityColumn {\n api_name: string;\n name: string;\n /** \"text\" | \"number\" | \"choice\" | \"date\" | \"datetime\" | \"checkbox\" | … */\n type: string;\n writable?: boolean;\n choices?: string[];\n /** A column shown as the words another table holds (`replaces`: the id column itself). */\n lookup?: { via: string; token: string; column: string; replaces: boolean };\n}\n\nexport interface MemoryEntitySpec {\n token: string;\n label: string;\n columns: MemoryEntityColumn[];\n /** Rows as the door returns them: `id` plus api_name → value, lookups and choices in words. */\n rows: Json[];\n}\n\nexport interface MemoryEntity extends MemoryEntitySpec {\n rows: Json[];\n}\n\ntype Answer = { data: unknown; error: null } | { data: null; error: { code: string; message: string; details: null; hint: string | null } };\nconst ok = (data: unknown): Answer => ({ data, error: null });\nconst refuse = (message: string, code = \"22023\", hint: string | null = null): Answer => ({\n data: null,\n error: { code, message, details: null, hint },\n});\n\n/** What `drill_describe` answers for a memory entity (dimensions from its choices, count + sums). */\nexport function memoryEntityDescribe(e: MemoryEntity): Json {\n const dimensions = e.columns\n .filter((c) => c.type === \"choice\" && Array.isArray(c.choices))\n .map((c) => ({ key: c.api_name, label: c.name, from: c.api_name, kind: \"choice\", cardinality: \"low\",\n choices: (c.choices ?? []).map((w) => ({ value: w, label: w })) }));\n const measures = [\n { key: \"count\", label: `Number of ${e.label.toLowerCase()}`, op: \"count\", unit: \"count\", additive: true },\n ...e.columns.filter((c) => c.type === \"number\").map((c) => ({\n key: `sum_${c.api_name}`, label: `Total ${c.name.toLowerCase()}`, op: \"sum\", of: c.api_name, additive: true,\n })),\n ];\n return {\n key: e.token, label: e.label, grain: `one row per ${e.label.toLowerCase()}`, lanes: [\"organization\", \"platform\"],\n dimensions, measures, paths: [], inferred: [],\n detail: { columns: e.columns.map((c) => c.api_name) },\n source: { kind: \"entity\", token: e.token }, mode: \"invoker\",\n api: { label: e.label, reach: \"read_write\", columns: e.columns },\n calendar: { time_zone: \"UTC\", week_start: \"monday\" },\n };\n}\n\nfunction matches(row: Json, where: Json | undefined): boolean {\n for (const [k, want] of Object.entries(where ?? {})) {\n const have = row[k] ?? null;\n if (Array.isArray(want)) { if (!want.includes(have as never)) return false; }\n else if (want === null) { if (have !== null) return false; }\n else if (typeof want === \"object\") continue; // operators are the live door's; memory keeps equality\n else if (String(have).toLowerCase() !== String(want).toLowerCase()) return false;\n }\n return true;\n}\n\n/** What `drill_rows` answers: one page, rows in words. */\nexport function memoryEntityRows(e: MemoryEntity, question: Json): Json {\n const limit = Number(question[\"limit\"] ?? 50);\n const offset = Number(question[\"offset\"] ?? 0);\n const rows = e.rows.filter((r) => matches(r, question[\"where\"] as Json | undefined));\n const page = rows.slice(offset, offset + limit);\n return {\n rows: page, total: rows.length, limit, offset, as_of: null,\n columns: e.columns.map((c) => c.api_name),\n ...(offset + page.length < rows.length ? { next_offset: offset + page.length } : {}),\n };\n}\n\n/** What `entity_row_write` does: a choice by its word (any case), refused in the door's words otherwise. */\nexport function memoryEntityWrite(e: MemoryEntity, recordId: string, columns: Json): Answer {\n const row = e.rows.find((r) => r[\"id\"] === recordId);\n if (!row) return refuse(`There is no ${e.label} you can open with that id.`, \"02000\");\n const next: Json = {};\n for (const [k, v] of Object.entries(columns ?? {})) {\n const c = e.columns.find((x) => x.api_name === k);\n if (!c) return refuse(`This table has no column called \"${k}\".`);\n if (c.lookup && !c.lookup.replaces) return refuse(`\"${c.name}\" is shown from another table, so it is changed there. Nothing was written.`);\n if (!c.writable) return refuse(`\"${c.name}\" is not changed through this door.`, \"42501\");\n if (c.type === \"choice\" && v !== null && v !== \"\") {\n const word = (c.choices ?? []).find((w) => w === v) ?? (c.choices ?? []).find((w) => w.toLowerCase() === String(v).toLowerCase());\n if (!word) return refuse(`\"${String(v)}\" is not one of the choices of \"${c.name}\".`, \"22023\", \"The columns call lists its choices.\");\n next[k] = word;\n } else next[k] = v === \"\" ? null : v;\n }\n const changed = Object.entries(next).some(([k, v]) => row[k] !== v);\n Object.assign(row, next);\n return ok({ id: recordId, organization_id: row[\"organization_id\"] ?? null, changed, row });\n}\n\n/** The memory doors for entity sources; each answers only an `{ kind: \"entity\" }` it holds. */\nexport function memoryEntityDoors(entities: Map<string, MemoryEntity>) {\n const of = (args: Json) => {\n const src = args[\"p_source\"] as Json | undefined;\n return src && src[\"kind\"] === \"entity\" ? entities.get(String(src[\"token\"])) : undefined;\n };\n return {\n drill_describe: (args: Json): Answer | null => {\n const e = of(args);\n return e ? ok(memoryEntityDescribe(e)) : null;\n },\n drill_rows: (args: Json): Answer | null => {\n const e = of(args);\n return e ? ok(memoryEntityRows(e, (args[\"p_question\"] as Json | undefined) ?? {})) : null;\n },\n entity_row_write: (args: Json): Answer | null => {\n const e = entities.get(String(args[\"p_token\"] ?? \"\"));\n if (!e) return null;\n return memoryEntityWrite(e, String(args[\"p_record_id\"] ?? \"\"), (args[\"p_columns\"] as Json | undefined) ?? {});\n },\n };\n}\n","// src/templates/payloads.ts — @ai-matrx/records (templates)\n//\n// SPEC → DOOR PAYLOADS: the pure translation of a template spec into the arguments each store door\n// takes. The plan (./plan.ts) and the validator (./validate.ts) compile from these; the installed\n// path is the store's own one-call door, custom.template_install (lane TEMPLATES).\n//\n// The interim browser installer that walked these doors one by one (installTemplate,\n// archiveTemplateInstall, resumeArchive) was retired onto the template family (lane TEMPLATES,\n// RETIRE-1, 2026-10-04); what it shared with the plan lives on here.\n\nimport type {\n TemplateAgent,\n TemplateBooking,\n TemplateDashboard,\n TemplateDocument,\n TemplateField,\n TemplateForm,\n TemplateRowAction,\n TemplateSpec,\n TemplateAutomation,\n TemplateChecklist,\n TemplateDigest,\n TemplateDimensions,\n TemplateDrillDown,\n TemplateNotification,\n TemplatePortal,\n TemplateStageRules,\n TemplateTable,\n TemplateView,\n} from \"./types\";\n\ntype Uuid = string;\n\n/**\n * Who is writing, said on every record write: the person signed in. The store lifts `_actor` out\n * before storage (an envelope key, like `_op_id`).\n */\nconst ACTOR = \"user\";\n\n/** The binding a host writes onto the copied agent's variable (the kit `merge_field` shape). */\nexport interface TemplateAgentBinding {\n variable: string;\n tableToken: string;\n tableId: Uuid;\n describes: string;\n}\n\nexport interface TemplateAgentCopyRequest {\n organizationId: Uuid;\n platformAgentId: string;\n platformAgent: string;\n name: string;\n bindings: TemplateAgentBinding[];\n /**\n * The host calls this the moment the fork returns the new agent's id, BEFORE naming or binding\n * it, so a failure after the fork never loses the id: the footprint keeps it either way.\n */\n onCreated?: (agentId: Uuid) => void;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pure translation: spec → door payloads (exported so the suite pins each shape)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Columns the store works out on read: never in the shells, never seeded, declared after rows. */\nconst COMPUTED = new Set([\"lookup\", \"rollup\", \"formula\"]);\n/**\n * A date WITH a time (\"@today-3d 09:30\"), declared as `format: \"datetime\"`. custom.table_from_example\n * forwards no `kind`, and the store makes every datetime it is not told about a whole-day date — a\n * calendar of all-day blocks. These columns are declared through field_declare with kind datetime.\n */\nexport const isTimedField = (f: TemplateField): boolean => f.parityType === \"datetime\" && f.format === \"datetime\";\n\n/**\n * A column table_from_example cannot make as declared, so the installer declares it itself through\n * custom.field_declare, before any row: a date WITH a time (the door forwards no `kind`) and any\n * column with a `default` (the door forwards no default, and a form that does not ask a required\n * column relies on it — \"Patient status\" starts as New).\n */\nexport const isSelfDeclaredField = (f: TemplateField): boolean =>\n f.parityType !== \"relation\" &&\n !COMPUTED.has(f.parityType) &&\n (isTimedField(f) || f.default !== undefined || f.parityType === \"entity_reference\");\n/** A coloured choice list, kept the way the grid reads it: display_format.options.choices. */\nexport function choiceDisplayFormat(field: TemplateField): { id: string; options: { choices: Array<{ value: string; color: string }> } } | undefined {\n if (!field.choices?.length || !field.choiceColors) return undefined;\n return {\n id: field.parityType === \"multi_select\" ? \"multi_choice\" : \"choice\",\n options: {\n choices: field.choices\n .filter((c) => field.choiceColors?.[c])\n .map((c) => ({ value: c, color: field.choiceColors![c]! })),\n },\n };\n}\n\n/**\n * `custom.table_from_example`'s `p_example` for ONE table: its own columns (coloured choices\n * included), no relation columns and no rows. One table per call, because the person's\n * statement ceiling is 8 s and the door costs ~80 ms a column (measured on the clone,\n * 2026-10-02: this template's six tables, 63 columns and 106 rows in one call took 12.8 s).\n * Relations, derived columns and rows follow through their own doors, each call small.\n */\n/**\n * LANE 10 FD — THE TABLES A TEMPLATE MARKS FOUNDATION, from its ONE source: `spec.foundation` (R13),\n * the day-one tables it lists with what each is kept for. The main table (`tables[0]`, the day-to-day\n * work) is never one, even if a list names it (the validator refuses that list too). Both installers\n * read this through `tableShellPayload`: the table is MADE marked, in the table step itself\n * (`custom.table_from_example` writes `foundation: true` into its document), so the browser install\n * and the gallery's server install (`plan.ts` → `custom.template_install`) mark the same tables.\n */\nexport function foundationTokens(spec: Partial<Pick<TemplateSpec, \"foundation\" | \"tables\">>): Set<string> {\n const main = spec.tables?.[0]?.token;\n return new Set((spec.foundation ?? []).map((f) => f.table).filter((token) => token && token !== main));\n}\n\nexport function tableShellPayload(\n spec: Pick<TemplateSpec, \"business\"> & Partial<Pick<TemplateSpec, \"foundation\" | \"tables\">>,\n t: TemplateTable,\n): Record<string, unknown> {\n return {\n business: spec.business.name,\n tables: [\n {\n token: t.token,\n ...(foundationTokens(spec).has(t.token) ? { foundation: true } : {}),\n name: t.name,\n labelSingular: t.labelSingular,\n labelPlural: t.labelPlural,\n type: t.type,\n display: t.display,\n weight: t.weight,\n ordered: t.ordered,\n titleField: t.titleField,\n describes: t.describes,\n fields: t.fields\n .filter((f) => !COMPUTED.has(f.parityType) && f.parityType !== \"relation\" && !isSelfDeclaredField(f))\n .map((f) => {\n const displayFormat = choiceDisplayFormat(f);\n return {\n key: f.key,\n label: f.label,\n parityType: f.parityType,\n multi: f.multi,\n dated: f.dated,\n required: f.required,\n unit: f.unit ?? undefined,\n rules: f.rules,\n choices: f.choices,\n source: f.source,\n computeOn: f.computeOn,\n sensitivity: f.sensitivity,\n contextPolicy: f.contextPolicy,\n ...(displayFormat ? { displayFormat } : {}),\n };\n }),\n rows: [],\n },\n ],\n };\n}\n\n/** `custom.table_from_example`'s `p_example` for EVERY table at once: columns and relations, no rows. */\nexport function shellsPayload(\n spec: Pick<TemplateSpec, \"business\">,\n tables: TemplateTable[],\n deferred: Map<string, Set<string>> = deferredRelations(tables),\n): Record<string, unknown> {\n // A relation that points BACK (a circle, or at its own table) is left out: table_from_example\n // refuses a circle of tables (\"Make one side of the circle optional\"), and the installer\n // declares those columns itself once every table exists (deferredRelationSteps).\n return {\n business: spec.business.name,\n tables: tables.map((t) => {\n const one = (tableShellPayload(spec, t)[\"tables\"] as Array<Record<string, unknown>>)[0]!;\n const relations = t.fields\n .filter((f) => f.parityType === \"relation\" && f.relationTarget && !deferred.get(t.token)?.has(f.key))\n .map((f) => ({\n key: f.key,\n label: f.label,\n parityType: \"relation\",\n relationTarget: f.relationTarget,\n multi: f.multi,\n relationMax: f.relationMax,\n required: f.required,\n sensitivity: f.sensitivity,\n contextPolicy: f.contextPolicy,\n }));\n return { ...one, fields: [...(one[\"fields\"] as unknown[]), ...relations] };\n }),\n };\n}\n\n/** `custom.field_declare`'s spec for one date-and-time column. */\nexport function timedFieldSpec(field: TemplateField): Record<string, unknown> {\n return {\n key: field.key,\n label: field.label,\n type: \"datetime\",\n kind: \"datetime\",\n ...(field.required ? { required: true } : {}),\n ...(field.rules ? { rules: field.rules } : {}),\n sensitivity: field.sensitivity,\n context_policy: field.contextPolicy,\n };\n}\n\n/**\n * `custom.field_declare`'s spec for one self-declared column (isSelfDeclaredField): every declared\n * key, its coloured choices, its kind for a date-and-time, and its default.\n */\nexport function selfDeclaredFieldSpec(field: TemplateField): Record<string, unknown> {\n if (isTimedField(field)) return { ...timedFieldSpec(field), ...(field.default !== undefined ? { default: field.default } : {}) };\n // An entity reference (S4) names the platform kinds it may point at; table_from_example forwards\n // no allowed_types, and the store refuses one that names none.\n const allowed = field.parityType === \"entity_reference\" ? { allowed_types: field.allowedTypes ?? [] } : {};\n const displayFormat = choiceDisplayFormat(field);\n return {\n key: field.key,\n label: field.label,\n type: field.parityType,\n ...(field.multi ? { multi: true } : {}),\n ...(field.required ? { required: true } : {}),\n ...(field.unit ? { unit: field.unit } : {}),\n ...(field.rules ? { rules: field.rules } : {}),\n ...(field.choices ? { options: field.choices } : {}),\n ...(displayFormat ? { display_format: displayFormat } : {}),\n ...(field.default !== undefined ? { default: field.default } : {}),\n ...allowed,\n sensitivity: field.sensitivity,\n context_policy: field.contextPolicy,\n };\n}\n\n/** `custom.field_declare`'s spec for one relation column, its target already made. */\nexport function relationFieldSpec(field: TemplateField, targetTableId: Uuid): Record<string, unknown> {\n return {\n key: field.key,\n label: field.label,\n type: \"relation\",\n relation_target: targetTableId,\n ...(field.multi ? { multi: true } : {}),\n ...(field.relationMax ? { relation_max: field.relationMax } : {}),\n ...(field.required ? { required: true } : {}),\n sensitivity: field.sensitivity,\n context_policy: field.contextPolicy,\n };\n}\n\n/** Tables in levels their rows can be written in: every table after the tables it points at. */\nexport function rowLevels(tables: TemplateTable[]): TemplateTable[][] {\n const done = new Set<string>();\n const levels: TemplateTable[][] = [];\n let left = [...tables];\n while (left.length) {\n let ready = left.filter((t) =>\n t.fields.every((f) => f.parityType !== \"relation\" || !f.relationTarget || f.relationTarget === t.token || done.has(f.relationTarget)),\n );\n // Tables that point at each other in a circle: none can go first, so ONE goes first on its own\n // (the first whose waiting links are optional), and its links to tables not yet written are set after every\n // row exists (deferredRelations / relationPatches). One table breaks the circle; the rest wait.\n if (!ready.length) {\n // Break the circle at a table whose links to unwritten tables are all OPTIONAL: a required\n // link cannot wait for a later patch (the row would be refused \"Client is required\").\n const optionalOnly = left.find((t) =>\n t.fields.every(\n (f) => f.parityType !== \"relation\" || !f.relationTarget || f.relationTarget === t.token || done.has(f.relationTarget) || !f.required,\n ),\n );\n ready = [optionalOnly ?? left[0]!];\n }\n for (const t of ready) done.add(t.token);\n levels.push(ready);\n left = left.filter((t) => !done.has(t.token));\n }\n return levels;\n}\n\n/**\n * The relation columns whose values cannot travel WITH their row: a link to the table's own rows,\n * or to a table in the same or a later row level (a circle). Those rows are written without them,\n * and `relationPatches` sets them once every row exists. table token → field keys.\n */\nexport function deferredRelations(tables: TemplateTable[]): Map<string, Set<string>> {\n const levelOf = new Map<string, number>();\n rowLevels(tables).forEach((level, i) => level.forEach((t) => levelOf.set(t.token, i)));\n const out = new Map<string, Set<string>>();\n for (const t of tables) {\n const mine = levelOf.get(t.token) ?? 0;\n for (const f of t.fields) {\n if (f.parityType !== \"relation\" || !f.relationTarget) continue;\n if (f.relationTarget === t.token || (levelOf.get(f.relationTarget) ?? -1) >= mine) {\n out.set(t.token, new Set([...(out.get(t.token) ?? []), f.key]));\n }\n }\n }\n return out;\n}\n\n/** The relation columns `deferredRelations` holds back, with their tables, in template order. */\nexport function deferredRelationFields(tables: TemplateTable[], deferred: Map<string, Set<string>>): Array<{ table: TemplateTable; f: TemplateField }> {\n return tables.flatMap((table) => table.fields.filter((f) => f.parityType === \"relation\" && deferred.get(table.token)?.has(f.key)).map((f) => ({ table, f })));\n}\n\n/**\n * A deferred link that is REQUIRED: its rows would be refused before the link is set. Said before\n * install, the store's own way (\"make one side of the circle optional\").\n */\nexport function requiredCircleProblem(tables: TemplateTable[], deferred: Map<string, Set<string>>): string | null {\n for (const { table, f } of deferredRelationFields(tables, deferred)) {\n if (f.required && f.relationTarget !== table.token) {\n return `\"${table.name}\" and \"${tables.find((t) => t.token === f.relationTarget)?.name ?? f.relationTarget}\" point at each other and every link in the circle is required (\"${f.label}\"), so no table's rows can be written first. Make one side of the circle optional.`;\n }\n }\n return null;\n}\n\n/**\n * The deferred links of one table as `custom.record_change_many` changes:\n * [{op: \"update\", record_id, patch: {field: id | ids}}], one per row that has any.\n */\nexport function relationPatches(table: TemplateTable, ids: Map<string, Uuid>, deferred: Set<string> | undefined): Record<string, unknown>[] {\n if (!deferred?.size) return [];\n const rel = new Map(table.fields.filter((f) => deferred.has(f.key)).map((f) => [f.key, f.relationTarget!]));\n const out: Record<string, unknown>[] = [];\n for (const r of table.rows) {\n const patch: Record<string, unknown> = {};\n for (const [key, target] of rel) {\n const v = r.values?.[key];\n if (v === null || v === undefined) continue;\n const idOf = (k: unknown) => {\n const id = ids.get(`${target}.${String(k)}`);\n if (!id) throw new Error(`A row points at \"${String(k)}\" in \"${target}\", which the template does not have.`);\n return id;\n };\n patch[key] = Array.isArray(v) ? v.map(idOf) : idOf(v);\n }\n if (Object.keys(patch).length) out.push({ op: \"update\", record_id: ids.get(`${table.token}.${r.key}`), patch: { ...patch, _actor: ACTOR } });\n }\n return out;\n}\n\n/**\n * One table's rows as `custom.record_write_many` takes them, with ids minted here so every\n * relation value (a row key in the file) is already a record id. Derived columns carry no value.\n */\nexport function rowsFor(\n table: TemplateTable,\n ids: Map<string, Uuid>,\n deferred?: Set<string>,\n): { rows: Record<string, unknown>[]; ids: Uuid[] } {\n const relation = new Map(table.fields.filter((f) => f.parityType === \"relation\").map((f) => [f.key, f]));\n const derived = new Set(table.fields.filter((f) => COMPUTED.has(f.parityType)).map((f) => f.key));\n const idOf = (target: string, key: unknown): Uuid => {\n const id = ids.get(`${target}.${String(key)}`);\n if (!id) throw new Error(`A row points at \"${String(key)}\" in \"${target}\", which the template does not have.`);\n return id;\n };\n const rows = table.rows.map((r) => {\n const values: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(r.values ?? {})) {\n if (derived.has(key) || deferred?.has(key) || value === null || value === undefined) continue;\n const rel = relation.get(key);\n if (!rel?.relationTarget) {\n values[key] = value;\n continue;\n }\n values[key] = Array.isArray(value) ? value.map((v) => idOf(rel.relationTarget!, v)) : idOf(rel.relationTarget, value);\n }\n values[\"_actor\"] = ACTOR;\n return values;\n });\n return { rows, ids: table.rows.map((r) => ids.get(`${table.token}.${r.key}`)!) };\n}\n\n/** `custom.field_declare`'s spec for one lookup or rollup. */\nexport function derivedFieldSpec(field: TemplateField): Record<string, unknown> {\n const base = {\n key: field.key,\n label: field.label,\n type: field.parityType,\n via: field.via,\n sensitivity: field.sensitivity,\n context_policy: field.contextPolicy,\n ...(field.unit ? { unit: field.unit } : {}),\n };\n return field.parityType === \"rollup\"\n ? { ...base, agg: field.agg, of: field.pick, ...(field.filter ? { filter: field.filter } : {}) }\n : { ...base, pick: field.pick };\n}\n\n/** `custom.view_declare`'s spec. */\nexport function viewSpec(view: TemplateView, fieldIds: Record<string, string> = {}): Record<string, unknown> {\n const definition: Record<string, unknown> = { layout: view.kind };\n const where = anyOfWhere(view.anyOf, fieldIds);\n if (where) definition[\"where\"] = where;\n if (view.sorts?.length) definition[\"sorts\"] = view.sorts;\n if (view.isDefault) definition[\"is_default\"] = true;\n if (view.hiddenFields?.length) definition[\"presentation\"] = { hiddenFields: view.hiddenFields };\n switch (view.kind) {\n case \"kanban\":\n definition[\"group_field\"] = view.groupBy;\n if (view.swimlaneBy) definition[\"swimlane_field\"] = view.swimlaneBy;\n if (view.measure) definition[\"measure\"] = view.measure;\n break;\n case \"calendar\":\n definition[\"date_field\"] = view.dateField;\n break;\n case \"gallery\":\n definition[\"image_field\"] = view.coverField;\n break;\n case \"grid\":\n if (view.groupBy) {\n definition[\"presentation\"] = { ...((definition[\"presentation\"] as object) ?? {}), grouping: { field: view.groupBy } };\n }\n break;\n case \"timeline\":\n // The store keeps these keys (lane 10 VK); validateTemplate still holds a timeline template\n // as waiting until records-ui draws the layout (OWED_BY \"view.timeline\").\n definition[\"start_field\"] = view.startField;\n definition[\"end_field\"] = view.endField;\n if (view.groupBy) definition[\"group_field\"] = view.groupBy;\n break;\n }\n return { name: view.name, definition, ...(view.filters ? { filters: view.filters } : {}) };\n}\n\n/**\n * A view's any-of conditions as the store's Rule expression (S2-PRIME, Fields by id):\n * {op: \"and\", args: [{op: \"or\", args: [{op: \"eq\", args: [{field: <id>}, {const: v}]}, …]}, …]}.\n * A key with no id is a template error said by name, never a silently dropped condition.\n */\nexport function anyOfWhere(anyOf: Record<string, string[]> | undefined, fieldIds: Record<string, string>): Record<string, unknown> | undefined {\n const entries = Object.entries(anyOf ?? {}).filter(([, vals]) => vals.length);\n if (!entries.length) return undefined;\n return {\n op: \"and\",\n args: entries.map(([key, vals]) => {\n const id = fieldIds[key];\n if (!id) throw new Error(`The view filters on \"${key}\", which the install has no field id for.`);\n return { op: \"or\", args: vals.map((v) => ({ op: \"eq\", args: [{ field: id }, { const: v }] })) };\n }),\n };\n}\n\n/** `custom.field_declare`'s spec for a formula column: the store parses `formula_text` and computes it on read. */\nexport function formulaFieldSpec(field: TemplateField): Record<string, unknown> {\n return {\n key: field.key,\n label: field.label,\n type: \"formula\",\n formula_text: field.formula,\n ...(field.unit ? { unit: field.unit } : {}),\n sensitivity: field.sensitivity,\n context_policy: field.contextPolicy,\n };\n}\n\n/**\n * A table's formula columns in an order the store can parse: a formula that reads another formula\n * (by its label in braces) comes after it. A cycle keeps template order (the store refuses it by name).\n */\nexport function formulaOrder(table: TemplateTable): TemplateField[] {\n const formulas = table.fields.filter((f) => f.parityType === \"formula\");\n const out: TemplateField[] = [];\n const left = [...formulas];\n while (left.length) {\n const i = left.findIndex((f) => !left.some((g) => g !== f && (f.formula ?? \"\").includes(`{${g.label}}`)));\n out.push(...left.splice(i < 0 ? 0 : i, 1));\n }\n return out;\n}\n\n/** A form question in the door's words: {field, ask, help, required}. */\nfunction question(q: { fieldKey: string; ask: string; help?: string; required?: boolean }): Record<string, unknown> {\n return { field: q.fieldKey, ask: q.ask, ...(q.help ? { help: q.help } : {}), ...(q.required ? { required: true } : {}) };\n}\n\nexport function formArgs(org: Uuid, tableId: Uuid, form: TemplateForm): Record<string, unknown> {\n return {\n p_organization_id: org,\n p_table_id: tableId,\n p_title: form.name,\n p_questions: form.fields.map(question),\n p_presentation: { submit_label: form.submitLabel, thank_you: { title: \"Thank you\", body: form.confirmation } },\n p_submission_cap: null,\n p_quarantine_rule_id: null,\n p_notify_rule_id: null,\n p_form_id: null,\n p_slug: null,\n };\n}\n\nexport function bookingArgs(org: Uuid, tableId: Uuid, booking: TemplateBooking): Record<string, unknown> {\n const a = booking.availability;\n return {\n p_organization_id: org,\n p_table_id: tableId,\n p_title: booking.title,\n p_questions: booking.questions.map(question),\n p_availability: {\n timezone: a.timezone,\n slot_minutes: a.slotMinutes,\n buffer_minutes: a.bufferMinutes,\n lead_minutes: a.leadMinutes,\n max_per_day: a.maxPerDay,\n days: a.days,\n windows: a.windows,\n },\n p_presentation: {},\n p_submission_cap: null,\n p_quarantine_rule_id: null,\n p_notify_rule_id: null,\n p_form_id: null,\n p_slug: booking.slug ?? null,\n p_home_id: null,\n };\n}\n\nexport function dashboardBlocks(dashboard: TemplateDashboard, tables: Record<string, Uuid>): Record<string, unknown>[] {\n return dashboard.blocks.map((b) => ({\n title: b.title,\n kind: b.kind,\n ...(b.table && b.table !== dashboard.table ? { table_id: tables[b.table] } : {}),\n ...(b.groupBy ? { group_by: b.groupBy } : {}),\n ...(b.measures ? { measures: b.measures } : {}),\n ...(b.bucket ? { bucket: b.bucket } : {}),\n ...(b.filter ? { filter: b.filter } : {}),\n ...(b.span ? { span: b.span } : {}),\n ...(b.stateKey ? { state_key: b.stateKey } : {}),\n ...(b.days ? { days: b.days } : {}),\n }));\n}\n\nexport function stageRulesSpec(rules: TemplateStageRules): Record<string, unknown> {\n return {\n stage_field: { key: rules.stageField },\n ...(rules.transitions ? { transitions: rules.transitions } : {}),\n ...(rules.requires ? { requires: rules.requires } : {}),\n ...(rules.limits ? { limits: rules.limits } : {}),\n ...(rules.movesMessage ? { moves_message: rules.movesMessage } : {}),\n };\n}\n\n/**\n * A document body in the store's token form. `{{field_key}}` → `{{field:<id>}}` (REC-68: a token\n * names a Field by id, so a rename never breaks it); `{{business}}` → the business's own name.\n * A key with no field is left as written, and the door refuses it by name.\n */\nexport function documentBody(doc: TemplateDocument, fieldIds: Record<string, Uuid>, businessName: string): string {\n return doc.body.replace(/\\{\\{\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\s*\\}\\}/g, (whole, key: string) => {\n if (key === \"business\") return businessName;\n const id = fieldIds[key];\n return id ? `{{field:${id}}}` : whole;\n });\n}\n\nexport function rowActionList(actions: TemplateRowAction[], fieldIds: Record<string, Uuid>): Record<string, unknown>[] {\n return actions.map((a) =>\n a.actionKind === \"agent\"\n ? { name: a.name, kind: \"agent\", prompt: a.prompt, ...(a.color ? { color: a.color } : {}), confirm: !!a.confirm }\n : {\n name: a.name,\n kind: \"update\",\n ...(a.color ? { color: a.color } : {}),\n confirm: !!a.confirm,\n steps: (a.steps ?? []).map((s) =>\n s.set === \"value\" ? { field: fieldIds[s.field] ?? s.field, set: \"value\", value: s.value } : { field: fieldIds[s.field] ?? s.field, set: \"clear\" },\n ),\n },\n );\n}\n\nexport function agentCopyRequest(org: Uuid, agent: TemplateAgent, tables: Record<string, Uuid>): TemplateAgentCopyRequest {\n return {\n organizationId: org,\n platformAgentId: agent.platformAgent.id,\n platformAgent: agent.platformAgent.name,\n name: agent.name,\n bindings: agent.variables.map((v) => ({ variable: v.name, tableToken: v.table, tableId: tables[v.table] ?? \"\", describes: v.describes })),\n };\n}\n\n/** The choice field of `table` that holds `stage` as one of its choices. */\nexport function stageFieldOf(tables: TemplateTable[], table: string, stage: string | undefined): string | null {\n if (!stage) return null;\n const t = tables.find((x) => x.token === table);\n return t?.fields.find((f) => (f.parityType === \"select\" || f.parityType === \"multi_select\") && f.choices?.includes(stage))?.key ?? null;\n}\n\n/**\n * A drill-down extra as the store keeps one. The drill PATH is the table's own (declared through\n * `table_dimensions_set` with the template's Dimensions); there is no door that declares a drill\n * entry point for a custom table (platform.drill_* serves platform-declared definitions), so the\n * entry point is a dashboard whose one chart groups by the path's first level — clicking a bar is\n * the drill through custom.drill_resolve. `custom.dashboard_declare`'s name and blocks.\n */\nexport function drillDownDashboard(drill: TemplateDrillDown, dimensions: TemplateDimensions[]): { name: string; blocks: Record<string, unknown>[] } {\n const path = dimensions.find((d) => d.table === drill.table)?.paths?.find((p) => p.key === drill.path);\n if (!path?.levels.length) throw new Error(`The drill-down \"${drill.name}\" names the path \"${drill.path}\", which the Dimensions of \"${drill.table}\" do not declare.`);\n const [key, grain] = path.levels[0]!.split(\":\");\n const block: Record<string, unknown> = { title: drill.name, kind: grain ? \"line\" : \"bar\", measures: [{ op: \"count\" }] };\n if (grain) block[\"bucket\"] = { key, by: grain };\n else block[\"group_by\"] = [key];\n return { name: drill.name, blocks: [block] };\n}\n\n/** A digest as `custom.subscription_declare` takes it: the saved view it sends, how often, how. */\nexport function digestSpec(digest: TemplateDigest, viewId: string): Record<string, unknown> {\n return {\n name: digest.name,\n saved_view_id: viewId,\n cadence: digest.cadence,\n ...(digest.schedule ? { schedule: digest.schedule } : {}),\n channel: digest.channel ?? \"in_app\",\n event_key: \"records.changed\",\n };\n}\n\n/**\n * A checklist as `custom.checklist_declare` takes it (p_spec). Steps that ask for a form or a\n * document name it by the id the install made (`forms`, `documents`: token → id).\n */\nexport function checklistSpec(\n checklist: TemplateChecklist,\n tables: Record<string, string>,\n forms: Record<string, string>,\n documents: Record<string, string>,\n): Record<string, unknown> {\n const trigger = checklist.trigger ?? { kind: \"manual\" as const };\n return {\n name: checklist.name,\n about_table_id: tables[checklist.aboutTable],\n roles: (checklist.roles ?? []).map((r) => ({ role: r.role, ...(r.label ? { label: r.label } : {}) })),\n steps: checklist.steps.map((st) => {\n const req = st.requires;\n const requires =\n !req ? undefined\n : req.kind === \"form\" ? { kind: \"form\", form_id: forms[req.form] }\n : req.kind === \"document\" ? { kind: \"document\", template_id: documents[req.document] }\n : req;\n return {\n ref: st.ref,\n title: st.title,\n ...(st.role ? { role: st.role } : {}),\n ...(st.dueDays !== undefined ? { due_days: st.dueDays } : {}),\n ...(st.dependsOn?.length ? { depends_on: st.dependsOn } : {}),\n ...(requires ? { requires } : {}),\n };\n }),\n trigger:\n trigger.kind === \"manual\" ? { kind: \"manual\" }\n : trigger.kind === \"record_created\" ? { kind: \"record_created\", table_id: tables[trigger.table] }\n : { kind: \"status_reached\", table_id: tables[trigger.table], status: trigger.status },\n };\n}\n\n/** An automation has no door yet: lane 11 owes it, and the validator holds such a template. */\nexport function automationHeld(a: TemplateAutomation): string {\n return `The automation \"${a.name}\" is held for lane 11: no store door runs automations yet, so a template carrying one is held, never installed without it.`;\n}\n\n/**\n * What custom.booking_declare requires of its table, said BEFORE install: a `slot` column (the door\n * writes the booked time into it on confirm, and adds it as a required text column when missing),\n * and a `status` choice column holding \"booked\" and \"cancelled\". Null when the table has both.\n */\nexport function bookingColumnsProblem(tables: TemplateTable[], booking: TemplateBooking): string | null {\n const t = tables.find((x) => x.token === booking.table);\n if (!t) return `The booking page \"${booking.title}\" takes bookings into \"${booking.table}\", which the template does not have.`;\n const slot = t.fields.find((f) => f.key === \"slot\");\n if (!slot) {\n return `The booking page \"${booking.title}\" writes each booked time into a column keyed \"slot\" on \"${t.name}\", and that table has none. Declare it (a required date-and-time, like \"Visit time\") so the seeded rows carry it; the door would add it after the rows and leave every seeded row missing a required value.`;\n }\n if (!slot.required) return `\"${t.name}\"'s \"slot\" column holds the booked time and the door requires it; declare it required and seed it on every row.`;\n const missing = t.rows.filter((r) => r.values?.[\"slot\"] === undefined || r.values?.[\"slot\"] === null || r.values?.[\"slot\"] === \"\");\n if (missing.length) return `\"${t.name}\" has ${missing.length} seeded row(s) with no \"slot\" (${missing[0]!.key}); the booking page makes it required, so those rows could never be edited.`;\n // custom.booking_declare adds \"Status\" (key status) and \"With\" (key booked_with) when the table lacks those keys;\n // a column already labelled that way under another key makes the door refuse the whole page (T0399).\n for (const [key, label] of [[\"status\", \"Status\"], [\"booked_with\", \"With\"]] as const) {\n if (t.fields.some((f) => f.key === key)) continue;\n const clash = t.fields.find((f) => f.label.trim().toLowerCase() === label.toLowerCase());\n if (clash) return `The booking page adds a \"${label}\" column to \"${t.name}\", which already has one (\"${clash.key}\"). Rename that column, or key it \"${key}\".`;\n }\n const status = t.fields.find((f) => f.key === \"status\");\n const words = new Set((status?.choices ?? []).map((c) => c.toLowerCase()));\n if (status && (!words.has(\"booked\") || !words.has(\"cancelled\"))) {\n return `The booking page writes \"booked\" and \"cancelled\" into \"${t.name}\"'s status, and its choices do not hold both.`;\n }\n return null;\n}\n\n/** A notification as the store keeps one: a saved view of the stage, and an instant subscription. */\nexport function notificationParts(\n n: TemplateNotification,\n stageField: string | null,\n): { view: Record<string, unknown>; subscription: Record<string, unknown> } {\n const filters: Record<string, unknown> = {};\n if (n.when.event === \"stage_entered\" && n.when.stage && stageField) filters[stageField] = n.when.stage;\n return {\n view: { name: n.name, definition: { layout: \"grid\" }, filters },\n subscription: { name: n.name, cadence: \"instant\", channel: n.channel, event_key: \"records.changed\" },\n };\n}\n\n/** `custom.portal_declare`'s arguments: each exposed table names the relation that says \"theirs\". */\nexport function portalArgs(org: Uuid, portal: TemplatePortal, tables: Record<string, Uuid>): Record<string, unknown> {\n return {\n p_organization_id: org,\n p_title: portal.title,\n p_client_table_id: tables[portal.clientTable],\n p_tables: portal.tables.map((t) => ({\n table_id: tables[t.table],\n names_via: t.namesVia,\n visible_fields: t.visibleFields,\n editable_fields: t.editableFields ?? [],\n comments: !!t.comments,\n })),\n p_portal_id: null,\n p_slug: portal.slug ?? null,\n p_sign_in_method: \"magic_link\",\n p_config: null,\n };\n}\n","// src/templates/types.ts — @ai-matrx/records (templates, internal)\n//\n// THE SHAPE OF ONE TEMPLATE: a working business setup that teaches one feature.\n//\n// Lane 8 TEMPLATES (Unified Data System v6, handoff HANDOFF-TEMPLATES.md §5). A template\n// carries a real business (the `UseCase` law: who, what business, what job; realistic,\n// never real people) and everything that makes it installable and teachable: tables and\n// seed rows, relationships, views, forms with question text, Dimensions, extras, one\n// agent with a scripted question, a three-step walk, foundation markings and shared-block\n// references. `toUseCase` (./validate) derives the five singular artefacts a `UseCase`\n// carries (form, pipeline, dashboard question, document, notification) so every existing\n// use-case consumer keeps working; a template never states them twice.\n//\n// EVERY PIECE MAPS 1:1 ONTO A STORE DOOR'S PAYLOAD (bodies read on the clone 2026-10-02),\n// so the installer translates and never invents:\n//\n// tables / rows / relationships → custom.table_from_example\n// sharedBlocks → the block's table, seeded once per organization\n// (SHARED_BLOCKS[block].fields), rows from the template\n// dimensions[] → custom.table_dimensions_set(p_overrides)\n// {dimensions[{key,label,hidden}], measures[{key,label,hidden,op,of}],\n// paths[{key,levels[]}], default{by[],show[]}}\n// views[] → custom.view_declare(p_spec) {name, definition{layout, group_field,\n// swimlane_field, measure, date_field, image_field, sorts, is_default},\n// filters} (keys: custom.view_keys())\n// forms[] → custom.form_declare(p_title, p_questions[{field, ask, help, required}])\n// extras booking → custom.booking_declare(p_title, p_questions, p_availability, p_slug)\n// extras portal → custom.portal_declare(p_title, p_client_table_id,\n// p_tables[{table_id, names_via, visible_fields, editable_fields, comments}])\n// — it OPENS the organization's outside sign-in (footprint records it)\n// extras dashboard → custom.dashboard_declare(p_name, p_blocks[DashboardBlock]); a block may\n// name its own table (custom.dashboard_block_normalize)\n// extras drill_down → a `paths` entry of table_dimensions_set, opened by custom.drill_resolve\n// extras digest → custom.subscription_declare(p_spec{name, saved_view_id, cadence, schedule, channel})\n// extras checklist → custom.checklist_declare(p_spec{name, about_table_id, roles, trigger, steps})\n// extras document → custom.doc_template_save(p_name, p_body) — {{field_key}} becomes\n// {{field:<id>}}, the only token custom.doc_render_body resolves\n// extras notification → custom.rule_declare (a notify rule on the table)\n// extras stage_rules → custom.pipeline_declare(p_spec{stage_field, transitions, requires, who, limits})\n// extras row_action → custom.action_declare(p_actions[RowAction])\n// extras automation → lane 11's door (not landed: `requires` holds it)\n// walk import step → custom.io_import_begin(p_format 'csv', p_source_name, p_source_columns,\n// p_policy{on_duplicate 'update', unmapped 'ignore'}, p_dedupe_key) +\n// custom.io_import_rows(p_rows, p_mapping) + custom.io_import_finish\n// agent → the kit installer's agent-copy path (catalog_entries kit\n// `source_agent_id`), variables bound to table ids\n//\n// The JSON files live under `templates/**` at the PACKAGE ROOT (never `src/`), excluded\n// from the npm tarball and from every entry point: 1,000 files never ship to a browser.\n\nimport type { TemplateConfidential } from \"./confidential\";\nimport type { AggregateBucket, AggregateFilter, AggregateMeasure, AggregateOperation } from \"../aggregate\";\nimport type { DashboardBlockKind } from \"../dashboard\";\nimport type { SubscriptionCadence } from \"../subscription\";\nimport type {\n NotificationChannel,\n UseCase,\n UseCaseField,\n UseCaseForm,\n UseCaseFormField,\n UseCaseNotificationTrigger,\n UseCaseProvenance,\n UseCaseRow,\n UseCaseTable,\n} from \"../use-cases/types\";\n\n/** The schema version of this file format. Bumped only when the SHAPE changes. */\nexport const TEMPLATE_SPEC_VERSION = 1 as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Relative dates — seed dates are written relative to install day\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * THE RELATIVE-DATE GRAMMAR. A seed date is written relative to the day the template is\n * installed, so a calendar installed in March shows this week's work, not last year's:\n *\n * ANCHOR @today the install day\n * @mon … @sun that weekday of the install week (weeks start Monday)\n * @last-mon … @next-sun that weekday of the week before / after\n * OFFSET +3d -2w +1m -1y days / weeks / months / years (N ≤ 9999)\n * +2b -5b BUSINESS days (Monday–Friday): never lands on a weekend\n * SNAP ~b if the result is a Saturday or Sunday, move to Monday\n * TIME \" 09:30\" a moment that day, 24-hour local time in the business's\n * zone, written out with its offset\n *\n * \"@today-3b 08:30\" \"@today~b 10:00\" \"@next-tue\" \"@mon+1d 14:00\"\n *\n * Closed: anything else in a date field is an absolute date, which only a field flagged\n * `absoluteDates` (a date of birth) may hold. `resolveRelativeDates` (./validate) turns\n * every token into the store's own date or moment text.\n *\n * Groups: 1 anchor, 2 sign, 3 count, 4 unit, 5 snap, 6 hour, 7 minute.\n */\nexport const RELATIVE_DATE =\n /^@(today|(?:last-|next-)?(?:mon|tue|wed|thu|fri|sat|sun))(?:([+-])(\\d{1,4})([dwmyb]))?(~b)?(?: ([01]\\d|2[0-3]):([0-5]\\d))?$/;\n\n/** The day the validator resolves relative dates against, so every check is deterministic. */\nexport const TEMPLATE_REFERENCE_DATE = \"2026-10-05\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The closed vocabularies of the catalogue\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** The 20 industry groups of the catalogue (handoff §5 table). The quota per group is in CATALOGUE_QUOTAS. */\nexport const INDUSTRY_GROUPS = [\n \"healthcare\",\n \"legal_professional\",\n \"construction_trades\",\n \"real_estate_property\",\n \"hospitality_food\",\n \"agencies_creative\",\n \"field_home_services\",\n \"retail_ecommerce\",\n \"manufacturing_logistics\",\n \"education\",\n \"nonprofit_community\",\n \"software_it\",\n \"fitness_beauty_wellness\",\n \"media_creators\",\n \"staffing_hr_recruiting\",\n \"personal_family\",\n \"events_weddings\",\n \"automotive\",\n \"agriculture_environment\",\n \"cross_industry\",\n] as const;\nexport type IndustryGroup = (typeof INDUSTRY_GROUPS)[number];\n\n/** The first 1,000 rows' quota per group (sums to 1,000). G3 enforces it at 1,000 and proportionally before. */\nexport const CATALOGUE_QUOTAS: Readonly<Record<IndustryGroup, number>> = {\n healthcare: 90,\n legal_professional: 70,\n construction_trades: 70,\n real_estate_property: 60,\n hospitality_food: 60,\n agencies_creative: 60,\n field_home_services: 50,\n retail_ecommerce: 50,\n manufacturing_logistics: 50,\n education: 50,\n nonprofit_community: 50,\n software_it: 50,\n fitness_beauty_wellness: 50,\n media_creators: 40,\n staffing_hr_recruiting: 40,\n personal_family: 40,\n events_weddings: 30,\n automotive: 30,\n agriculture_environment: 30,\n cross_industry: 30,\n};\n\n/** The 12 jobs a template does for a business. */\nexport const TEMPLATE_JOBS = [\n \"intake\",\n \"scheduling\",\n \"crm_pipeline\",\n \"work_orders\",\n \"inventory\",\n \"billing\",\n \"team_hr\",\n \"projects\",\n \"content\",\n \"compliance_quality\",\n \"customer_service\",\n \"reporting\",\n] as const;\nexport type TemplateJob = (typeof TEMPLATE_JOBS)[number];\n\n/** The 16 features a template can teach. Each is taught by at least 40 of the first 1,000. */\nexport const TEACHES_FEATURES = [\n \"relations_rollups\",\n \"dimensions\",\n \"kanban\",\n \"calendar\",\n \"timeline\",\n \"gallery\",\n \"forms\",\n \"bookings\",\n \"portals\",\n \"dashboards\",\n \"drill_down\",\n \"agents\",\n \"field_governance\",\n \"import_upsert\",\n \"checklists\",\n \"documents_esign\",\n] as const;\nexport type TeachesFeature = (typeof TEACHES_FEATURES)[number];\n\n/**\n * The five places we beat the champions (ADV-P §4). Each is shown in at least 100 of the first 1,000.\n *\n * S1 — governed columns: every column says who sees it and whether AI may read it.\n * S2 — agents inside the data: an agent works on the table's own records.\n * S3 — every front door on one table: form, booking, portal, digest, webhook all land in one table.\n * S4 — a column can point at anything on the platform (entity reference).\n * S5 — imports and edits cannot lose data: an upsert import that updates and adds, or\n * archive → Trash → restore, shown in the walk.\n */\nexport const STRENGTHS = [\"S1\", \"S2\", \"S3\", \"S4\", \"S5\"] as const;\nexport type Strength = (typeof STRENGTHS)[number];\n\n/** Who installs it: a business, or a person for their own life. */\nexport const TEMPLATE_AUDIENCES = [\"organization\", \"individual\"] as const;\nexport type TemplateAudience = (typeof TEMPLATE_AUDIENCES)[number];\n\n/**\n * THE CAPABILITY WORDS a template may `require`. Closed: a word not here is a typo, and a\n * word the template does not use is refused. Whether each is PROVIDED today is derived by\n * `capabilityStatus` (./validate) from the store's registry and the records-ui layouts, so a\n * word flips to provided the day its lane lands, with no edit to this list.\n */\nexport const CAPABILITY_WORDS = [\n // views (custom.view_keys() layouts; records-ui VIEW_LAYOUTS)\n \"view.grid\",\n \"view.kanban\",\n \"view.kanban.swimlanes\",\n \"view.calendar\",\n \"view.calendar.month\",\n \"view.timeline\",\n \"view.gallery\",\n // field kinds (custom.field_kinds() / custom.parity_field_types())\n \"field.select\",\n \"field.multi_select\",\n \"field.datetime\",\n \"field.currency\",\n \"field.percent\",\n \"field.email\",\n \"field.phone\",\n \"field.url\",\n \"field.checkbox\",\n \"field.attachment\",\n \"field.member\",\n \"field.lookup\",\n \"field.rollup\",\n \"field.formula\",\n \"field.entity_reference\",\n \"field.signature\",\n \"field.rating\",\n // presentation and seed\n \"choice.colors\",\n \"seed.attachments\",\n // surfaces and machinery (store doors)\n \"form\",\n \"form.question_text\",\n \"booking\",\n \"portal\",\n \"dashboard\",\n \"dashboard.multi_table\",\n \"drill_down\",\n \"dimensions\",\n \"digest\",\n \"checklist\",\n \"document\",\n \"document.esign\",\n \"notification\",\n \"stage_rules\",\n \"row_action\",\n \"import.upsert\",\n \"archive.restore\",\n \"agent\",\n \"automation\",\n] as const;\nexport type CapabilityWord = (typeof CAPABILITY_WORDS)[number];\n\n/**\n * The platform kinds an entity_reference column may point at — custom.entity_reference_kinds(),\n * read on the clone 2026-10-02 (the TEMPLATES lane refreshes it the way it refreshes the agent\n * snapshot). A word outside it is refused: the store would refuse the column.\n */\nexport const ENTITY_REFERENCE_KINDS = [\n \"agent\", \"agent_shortcut\", \"agent_template\", \"ai_api\", \"ai_endpoint\", \"ai_model\", \"ai_provider\",\n \"ai_setting\", \"anon_form\", \"app\", \"assessment\", \"canvas_comment\", \"canvas_item\", \"canvas_score\",\n \"category\", \"code_file\", \"code_folder\", \"code_repository\", \"comparison_set\", \"contact_submission\",\n \"content_ir_kind\", \"content_ir_kind_instance\", \"context_item\", \"conversation\", \"crm_deal\",\n \"crm_outreach_list\", \"cx_agent_memory\", \"data_store\", \"fc_set\", \"feature_doc\", \"flexible_data\", \"folder\",\n \"game_result\", \"heatmap_save\", \"hr_asset\", \"hr_candidate\", \"hr_careers_portal\", \"hr_checklist_template\",\n \"hr_course\", \"hr_crew\", \"hr_deduction_code\", \"hr_department\", \"hr_earning_code\", \"hr_employee\",\n \"hr_holiday_calendar\", \"hr_interview_kit\", \"hr_job_title\", \"hr_jurisdiction\", \"hr_jurisdiction_rule_class\",\n \"hr_leave_policy\", \"hr_location\", \"hr_pay_group\", \"hr_posting\", \"hr_record_class\", \"hr_requisition\",\n \"hr_schedule\", \"hr_schedule_template\", \"hr_survey\", \"league_membership\", \"learn_doc\", \"mandate\",\n \"marketing_initiative\", \"meet_meeting\", \"message_template\", \"note\", \"note_folder\", \"organization\",\n \"page_extraction_job\", \"party\", \"pc_article\", \"pc_episode\", \"pc_show\", \"pc_studio_run\",\n \"processed_document\", \"project\", \"quiz_session\", \"research_template\", \"research_topic\", \"rulebook\",\n \"sch_task\", \"scope_type\", \"seo_topic\", \"shared_canvas_item\", \"skill\", \"skill_render_definition\",\n \"studio_session\", \"study_goal\", \"study_media\", \"study_plan\", \"study_plan_block\", \"surface\", \"task\",\n \"thread\", \"tool\", \"tool_bundle\", \"transcript\", \"udt_document\", \"user_markdown_sample\", \"voice\", \"war_room\",\n \"wbx_pattern\", \"web_analysis_item\", \"web_brand\", \"web_provider\", \"web_site\", \"workbook\", \"workflow\",\n \"workflow_template\", \"workflow_trigger\", \"working_document\",\n] as const;\n\n/** The colours a choice may wear — the palette `display_format.options.choices[].color` holds (design-system STYLE_COLORS). */\nexport const CHOICE_COLORS = [\"slate\", \"green\", \"amber\", \"red\", \"blue\", \"violet\", \"teal\"] as const;\nexport type ChoiceColor = (typeof CHOICE_COLORS)[number];\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Shared blocks — a seeded table referenced by relation, never copied\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SharedBlockField {\n key: string;\n label: string;\n parityType: UseCaseField[\"parityType\"];\n sensitivity: UseCaseField[\"sensitivity\"];\n contextPolicy: UseCaseField[\"contextPolicy\"];\n required?: boolean;\n /** Labels and keys that mean this field, for the copy check (normalised, lower-case words). */\n sameAs: readonly string[];\n}\n\nexport interface SharedBlock {\n /** The table's token in every organization: one table, shared by every template that uses it. */\n table: string;\n name: string;\n labelSingular: string;\n labelPlural: string;\n titleField: string;\n describes: string;\n fields: readonly SharedBlockField[];\n /** A template table matching this many of the block's fields (by type and meaning) has copied it. */\n copyThreshold: number;\n}\n\n/**\n * THE SHARED BLOCKS. The scope templates carried 26 byte-identical copies of a team-member\n * block (312 of 846 fields). Now the block is ONE seeded table per organization; a template\n * lists the block in `sharedBlocks` with the rows it seeds (its own people), and points its\n * \"assigned to\" columns at the block's table with an ordinary relation field — so the\n * column is filled, and no template declares those fields again.\n */\nexport const SHARED_BLOCKS = {\n team_member: {\n table: \"team_member\",\n name: \"Team\",\n labelSingular: \"Team member\",\n labelPlural: \"Team\",\n titleField: \"full_name\",\n describes: \"The people on the business's own team — who is assigned, who answers, who signs.\",\n fields: [\n { key: \"full_name\", label: \"Name\", parityType: \"text\", sensitivity: \"internal\", contextPolicy: \"include\", required: true, sameAs: [\"name\", \"full name\", \"employee name\", \"staff name\"] },\n { key: \"role\", label: \"Role\", parityType: \"text\", sensitivity: \"internal\", contextPolicy: \"include\", sameAs: [\"role\", \"job title\", \"title\", \"position\"] },\n { key: \"work_email\", label: \"Work email\", parityType: \"email\", sensitivity: \"confidential\", contextPolicy: \"summarize\", sameAs: [\"email\", \"work email\", \"email address\"] },\n { key: \"mobile\", label: \"Mobile\", parityType: \"phone\", sensitivity: \"confidential\", contextPolicy: \"exclude\", sameAs: [\"phone\", \"mobile\", \"work phone\", \"cell\", \"phone number\"] },\n { key: \"start_date\", label: \"Start date\", parityType: \"datetime\", sensitivity: \"internal\", contextPolicy: \"include\", sameAs: [\"start date\", \"hire date\", \"started\", \"date hired\"] },\n ],\n copyThreshold: 3,\n },\n} as const satisfies Record<string, SharedBlock>;\nexport type SharedBlockId = keyof typeof SHARED_BLOCKS;\nexport const SHARED_BLOCK_IDS = Object.keys(SHARED_BLOCKS) as SharedBlockId[];\n\n/** One shared block this template uses, with the rows it seeds into the block's table. */\nexport interface SharedBlockUse {\n block: SharedBlockId;\n /** Keyed by the block's field keys. Relation fields elsewhere point at these row keys. */\n rows: UseCaseRow[];\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Tables and fields\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface TemplateField extends UseCaseField {\n /** Every choice of a select/multi_select wears a colour: choice word → colour. */\n choiceColors?: Record<string, ChoiceColor>;\n /** For an `entity_reference` field (S4): the platform kinds it may point at. */\n allowedTypes?: string[];\n /** For a lookup / rollup: the relation field it reads through. */\n via?: string;\n /** Lookup: the field picked on the far side. Rollup: the field aggregated. */\n pick?: string;\n /** Rollup: the aggregate along the relation. */\n agg?: AggregateOperation;\n /**\n * Rollup: WHICH linked records it adds up — \"sessions booked\", \"unpaid balance\", \"open requests\"\n * per parent. The saved view's own filter grammar, written against the far table: a flat map of\n * far-side column keys (`{ status: \"open\" }`) or a Rule expression over far-side field IDs. The\n * store refuses an unknown column or op at install (custom.field_declare).\n */\n filter?: Record<string, unknown>;\n /**\n * For a `formula` field: the formula text custom.field_declare parses (`formula_text`, through\n * custom.formula_parse) — fields named by LABEL in braces, functions from\n * custom.formula_node_kinds(): `{Total} - {Paid}`, `DATEDIFF({Starts}, {Ends}, 'minutes') / 60`.\n * The store computes it on read; seeds never write it.\n */\n formula?: string;\n /**\n * ELIGIBILITY across tables, on a relation field: the record this field points at must hold a\n * row in `table` (linked back by `relation`) matching `where`, whose `until` date is on or after\n * this row's `onDate` — a shift's staff member holds an unexpired food-handler card on the\n * shift's day. Checked on the seed and on the walk's state after every step.\n */\n eligible?: { table: string; relation: string; where?: Record<string, string>; until: string; onDate: string };\n /**\n * A date field whose values are history, not schedule (a date of birth, a founding\n * date): its seed rows hold absolute dates. Every other date field is written in the\n * relative grammar (RELATIVE_DATE).\n */\n absoluteDates?: boolean;\n /**\n * A schedule date for a weekday-only business: every seed value must resolve to Monday–\n * Friday on EVERY install weekday (write it with business-day offsets \"+2b\" or the \"~b\" snap).\n */\n businessDays?: boolean;\n /** The value a new record gets when nobody gives one — lets a form or an import leave a required field out. */\n default?: unknown;\n /**\n * A public form may ask a confidential / restricted field only when it is the asker's OWN\n * data (a patient's member id on her own intake). Flag it here; never for anyone else's.\n */\n askOfSubject?: boolean;\n /** A parent or guardian answers this on a public form for a minor (youth league, school, pediatrics). */\n askOfGuardian?: boolean;\n /**\n * Required with `absoluteDates`: why these dates are history (\"date of birth\", \"the year\n * the firm was founded\"). A field flagged absolute may never drive a calendar, a timeline,\n * a booking, a digest, a stage rule, the Q6 question or a walk step — those are schedule.\n */\n historicalReason?: string;\n}\n\nexport interface TemplateTable extends UseCaseTable {\n fields: TemplateField[];\n /**\n * REUSE, NEVER DUPLICATE (CHAIR-DESCRIBE-2): this template table IS one the organization already has.\n * The install makes no table for it — `tables.<token>` is the existing table's id from the first step —\n * declares only the fields it lacks (`fields` = the keys it already has), seeds none of its rows, never\n * resets its Dimensions, and links the template's new tables to it. Uninstall archives only what the\n * install added (its new fields, views, forms), never the table.\n */\n bindsTo?: { tableId: string; fields: string[] };\n /**\n * Ordered date pairs that hold on every seed row: [earlier, later]. A side is a field of\n * this table (\"sent_on\") or a field reached through one of its relations (\"patient.date_of_birth\").\n * A table with two or more schedule date fields declares its order here, or says why the\n * dates are independent (`datesIndependent`).\n */\n before?: [string, string][];\n datesIndependent?: string;\n /**\n * A roster of recurring slots (weekly shifts, standing roles): rows may share a title when\n * they differ in a date and in who or what they are for (a relation).\n */\n schedule?: boolean;\n /**\n * Date coherence across relations, declared: on every seed row `earlier` is on or before\n * `later`. A side is a field of this table (\"invoice_date\") or one reached through a relation\n * (\"engagement.start_date\"). `onlyWhen` limits the pair to rows whose field holds one of the\n * values (a report is due only on an Awarded grant). A billing or grants template declares at\n * least one pair that crosses a relation.\n */\n datePairs?: { earlier: string; later: string; onlyWhen?: { field: string; values: string[] } }[];\n /**\n * CROSS-TABLE REALISM, stated once on the CHILD table (the one holding the relation) and\n * enforced on every seed row. A relation whose two sides both carry a schedule date needs a\n * childDates entry; both a status, a statusAgrees entry.\n *\n * childDates: this row's date is on or after its parent's (\"start_on\" ≥ \"requisition.opened_on\").\n */\n childDates?: { relation: string; field: string; parentField: string }[];\n /** withinParent: this row's number stays within its parent's (deal.price ≤ client.budget_max) unless a status says otherwise. */\n withinParent?: { relation: string; field: string; op: \"<=\" | \">=\"; parentField: string; unless?: { field: string; values: string[] } }[];\n /**\n * statusAgrees: a child in one of `childStatus` means its parent's `parentField` is one of\n * `parentStatus` (deal Closed ⇒ listing Sold); `maxPerParent` caps how many children of one\n * parent may sit in those statuses (one accepted offer per listing).\n */\n statusAgrees?: { relation: string; field: string; childStatus: string[]; parentField: string; parentStatus: string[]; maxPerParent?: number }[];\n /** countMatches: a stored count equals the number of linked rows. Prefer a rollup, which the store computes. */\n countMatches?: { field: string; childTable: string; childRelation: string }[];\n /**\n * STATUS IMPLIES FIELDS: a row in one of `when` (on `field`) has every `filled` field filled\n * and every `equals` field at that value — Paid ⇒ paid_on set and balance 0; Signed ⇒ the\n * signature filled. Checked on every seed row and after every walk step that changes a row.\n */\n statusImplies?: { field: string; when: string[]; filled?: string[]; equals?: Record<string, unknown> }[];\n /**\n * DATE-DRIVEN STATUS: `field` follows `dateField` measured from the install day, on every\n * install weekday — bands in days from today, `from` inclusive, `to` exclusive:\n * [{status: \"Expired\", to: 0}, {status: \"Renewal due\", from: 0, to: 61}, {status: \"Current\", from: 61}].\n * A row whose status is one of the bands' statuses sits in the band its date says. (A status the\n * store should compute is better a formula: IF(DATEDIFF(TODAY(), {Expires on}, 'days') < 0, …).)\n */\n statusByDate?: { field: string; dateField: string; bands: { status: string; from?: number; to?: number }[] };\n /** Relations (by field key) whose two sides' dates and statuses truly do not constrain each other, each with the reason. */\n independentOf?: Record<string, string>;\n /**\n * What one row is: a person, an animal or a thing. The personal-data floors (date of birth,\n * allergies, diagnoses, medications, member ids) bind people only — a dog's birthday is not\n * personal data. Undeclared, a table holds people when it has a name and a phone or email.\n */\n subject?: \"person\" | \"animal\" | \"thing\";\n /**\n * Lane 10 FD. An echo of the template's `foundation` list (R13), which is the ONE source the\n * installers read. Optional; when present the validator requires it to agree with the list.\n */\n foundation?: boolean;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Views → custom.view_declare\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const TEMPLATE_VIEW_KINDS = [\"grid\", \"kanban\", \"calendar\", \"gallery\", \"timeline\"] as const;\nexport type TemplateViewKind = (typeof TEMPLATE_VIEW_KINDS)[number];\n\nexport interface TemplateViewSort {\n field: string;\n direction: \"asc\" | \"desc\";\n}\n\ninterface TemplateViewBase {\n /** snake_case, unique within the template. */\n token: string;\n /** What a person clicks: \"Today's chairs\", \"Intake board\". */\n name: string;\n /** The table token it looks at. */\n table: string;\n /** The view the table opens on (at most one per table). */\n isDefault?: boolean;\n /** custom.view_declare `filters`: Field key → value (scalar equality, null = unset, object = window). */\n filters?: Record<string, AggregateFilter>;\n /**\n * Any-of conditions: Field key → the values a row may hold (\"Open requests\" = New, In progress,\n * Waiting). The store's flat `filters` map is equality only; this is declared as the view's\n * `where` Rule expression (S2-PRIME) — `{op: \"and\", args: [{op: \"or\", args: [{op: \"eq\", args:\n * [{field: <field id>}, {const: <value>}]}, …]}, …]}`, Fields by id — which custom.record_filter_sql\n * compiles for the grid and the board. Digests and the notifier read only `filters`, never this.\n */\n anyOf?: Record<string, string[]>;\n sorts?: TemplateViewSort[];\n /** Field keys hidden on this view (presentation.hiddenFields). */\n hiddenFields?: string[];\n}\n\nexport interface TemplateGridView extends TemplateViewBase {\n kind: \"grid\";\n groupBy?: string;\n}\n\nexport interface TemplateKanbanView extends TemplateViewBase {\n kind: \"kanban\";\n /** `group_field`: the choice field whose values are the columns. */\n groupBy: string;\n /** `swimlane_field`: never the column field itself. */\n swimlaneBy?: string;\n /** `measure`: a number field totalled under each column heading. */\n measure?: string;\n}\n\nexport interface TemplateCalendarView extends TemplateViewBase {\n kind: \"calendar\";\n /** `date_field`: a datetime, so every card has a time on the day. */\n dateField: string;\n /** The records are whole-day by intent (a deadline, a due date). */\n allDay?: boolean;\n /** \"month\" needs `view.calendar.month` (lane 10). */\n span?: \"month\" | \"week\";\n}\n\nexport interface TemplateGalleryView extends TemplateViewBase {\n kind: \"gallery\";\n /** `image_field`: the file field shown as each card's picture. Needs `seed.attachments`. */\n coverField: string;\n}\n\nexport interface TemplateTimelineView extends TemplateViewBase {\n kind: \"timeline\";\n startField: string;\n endField: string;\n groupBy?: string;\n}\n\nexport type TemplateView =\n | TemplateGridView\n | TemplateKanbanView\n | TemplateCalendarView\n | TemplateGalleryView\n | TemplateTimelineView;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Forms → custom.form_declare (with per-question text)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface TemplateFormField extends UseCaseFormField {\n /**\n * The question as it is ASKED: \"What brings you in today?\" — not the column label.\n * Sent as the question's `ask` to custom.form_declare / booking_declare (`help` rides beside it).\n */\n ask: string;\n}\n\nexport interface TemplateForm extends UseCaseForm {\n fields: TemplateFormField[];\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Dimensions → custom.table_dimensions_set(p_overrides)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface TemplateDimensionOverride {\n /** An inferred dimension key (custom._table_dimensions_infer): a single choice, a single relation, a tick box, a date, created_at or updated_at. */\n key: string;\n label?: string;\n hidden?: boolean;\n}\n\nexport interface TemplateMeasureOverride {\n /** An inferred measure key (count, sum_x, avg_x, min_x, max_x, filled_x) — rename/hide only — or a NEW key. */\n key: string;\n label?: string;\n hidden?: boolean;\n /** A NEW measure only: one of custom.agg_operations() except count. */\n op?: Exclude<AggregateOperation, \"count\">;\n /** A NEW measure only: the column it reads. */\n of?: string;\n}\n\nexport interface TemplateDrillPath {\n key: string;\n /** Dimension keys, coarsest first; a date takes \":year\" | \":quarter\" | \":month\" | \":week\" | \":day\". */\n levels: string[];\n}\n\nexport interface TemplateDimensions {\n table: string;\n dimensions?: TemplateDimensionOverride[];\n measures?: TemplateMeasureOverride[];\n paths?: TemplateDrillPath[];\n default?: { by?: string[]; show?: string[] };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Extras — at least two per template\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface TemplateBookingWindow {\n /** 0 = Sunday … 6 = Saturday. */\n weekday: number;\n /** \"09:00\". */\n from: string;\n /** \"17:00\", later than `from`. */\n to: string;\n}\n\nexport interface TemplateBooking {\n kind: \"booking\";\n token: string;\n title: string;\n table: string;\n questions: TemplateFormField[];\n availability: {\n timezone?: string;\n slotMinutes: number;\n bufferMinutes?: number;\n leadMinutes?: number;\n maxPerDay?: number;\n days?: number;\n windows: TemplateBookingWindow[];\n };\n slug?: string;\n /**\n * The statuses of rows that came through (or wait on) this booking page. Only those rows must\n * sit in its windows; rows that reached later stages by other routes (a same-day emergency\n * dispatch) do not. Default: Booked, Confirmed, Requested, Held, Pending, Scheduled, Cancelled.\n */\n bookedStages?: string[];\n}\n\nexport interface TemplatePortalTable {\n table: string;\n /** The relation field of `table` that points at the portal's client table — \"only theirs\". */\n namesVia: string;\n /** Never empty; never a restricted / confidential field or one the AI is kept from. */\n visibleFields: string[];\n editableFields?: string[];\n comments?: boolean;\n}\n\nexport interface TemplatePortal {\n kind: \"portal\";\n token: string;\n title: string;\n /** The table whose records are the portal's clients (patients, owners, tenants). */\n clientTable: string;\n tables: TemplatePortalTable[];\n /** Form tokens offered inside the portal. */\n forms?: string[];\n slug?: string;\n}\n\nexport interface TemplateDashboardBlock {\n title: string;\n kind: DashboardBlockKind;\n /** Absent = the dashboard's own table. */\n table?: string;\n groupBy?: string[];\n measures?: AggregateMeasure[];\n bucket?: { key: string; by: AggregateBucket };\n filter?: Record<string, AggregateFilter>;\n span?: number;\n /** `stuck` only. */\n stateKey?: string;\n days?: number;\n}\n\nexport interface TemplateDashboard {\n kind: \"dashboard\";\n token: string;\n name: string;\n table: string;\n /** At least two charts: bar, column, line or donut (`number`, `table` and `stuck` are not charts). */\n blocks: TemplateDashboardBlock[];\n}\n\nexport interface TemplateDrillDown {\n kind: \"drill_down\";\n token: string;\n name: string;\n table: string;\n /** A `paths[].key` of this table's `dimensions` entry. */\n path: string;\n}\n\nexport interface TemplateDigest {\n kind: \"digest\";\n token: string;\n name: string;\n /** The view token whose records the digest sends. */\n view: string;\n cadence: SubscriptionCadence;\n /** \"monday 08:00\". */\n schedule?: string;\n channel?: \"in_app\" | \"email\" | \"sms\";\n}\n\nexport interface TemplateChecklistStep {\n ref: string;\n title: string;\n role?: string;\n dueDays?: number;\n dependsOn?: string[];\n requires?:\n | { kind: \"none\" | \"note\" }\n | { kind: \"answer\"; key: string; label: string }\n | { kind: \"record_field\"; key: string; label?: string }\n | { kind: \"form\"; form: string }\n | { kind: \"document\"; document: string };\n}\n\nexport interface TemplateChecklist {\n kind: \"checklist\";\n token: string;\n name: string;\n aboutTable: string;\n roles?: { role: string; label?: string }[];\n trigger?: { kind: \"manual\" } | { kind: \"record_created\"; table: string } | { kind: \"status_reached\"; table: string; status: string };\n steps: TemplateChecklistStep[];\n}\n\nexport interface TemplateDocument {\n kind: \"document\";\n token: string;\n name: string;\n describes: string;\n table: string;\n /** The subject or title line; merge fields allowed. */\n title: string;\n /**\n * Prose with {{field_key}} merge fields, each a field of `table` (the installer writes\n * {{field:<id>}}, the only token custom.doc_render_body resolves). No {{today}}, no\n * {{business.x}}, no signature field (a signature never merges into the body).\n */\n body: string;\n /** Sent for e-signature (needs `document.esign`). */\n signature?: boolean;\n}\n\nexport interface TemplateNotification {\n kind: \"notification\";\n token: string;\n name: string;\n describes: string;\n when: UseCaseNotificationTrigger;\n /** Who it goes to, in the business's own words: \"the assigned hygienist\". */\n audience: string;\n channel: NotificationChannel;\n /** The message; {{field_key}} merge fields of the watched table only. */\n message: string;\n}\n\nexport interface TemplateStageRules {\n kind: \"stage_rules\";\n token: string;\n /** \"Route board\" — the lifecycle's own name. */\n name: string;\n table: string;\n /** The choice field holding the stage. */\n stageField: string;\n /** Stage → what is true of a record sitting there, in the staff's words (every stage). */\n stages: Record<string, string>;\n transitions?: { from: string; to: string }[];\n /** Stage → field keys that must be filled to land there. */\n requires?: Record<string, string[]>;\n /** Stage → how many cards may sit there at once. */\n limits?: Record<string, number>;\n movesMessage?: string;\n /**\n * Status ↔ date coherence, enforced on every seed row for every install weekday: the date\n * field, and per stage whether its date is in the past (on or before install day), today,\n * or the future (on or after install day). A stage left out is unconstrained.\n */\n dateField?: string;\n /** Every stage is listed once a dateField is declared; \"any\" says a stage's date is unconstrained, on purpose. */\n /** \"none\": this stage has no date yet (\"New call\", \"Draft\") — its date field is EMPTY. */\n stageDates?: Record<string, \"past\" | \"today\" | \"future\" | \"any\" | \"none\">;\n /** Why a time-bound stage (\"No-show\", \"Completed\", \"Scheduled\"…) is \"any\": one real sentence (≥ 6 words) per such stage. */\n anyBecause?: Record<string, string>;\n /**\n * Moves OUT of a terminal stage (Cancelled, No-show, Lost, Declined, Closed, Withdrawn…) are\n * refused unless declared here with the business reason — a reopened deal, a rebooked guest.\n */\n reopen?: { from: string; to: string; because: string }[];\n /**\n * A stage that needs a linked child: \"First pickup booked\" ⇒ at least `min` (default 1) row of\n * `table` whose `relation` points at this row and whose `field` is one of `in`. Checked on the\n * seed and on the walk's state after every step.\n */\n requiresChild?: Record<string, { table: string; relation: string; field?: string; in?: string[]; min?: number }>;\n}\n\nexport interface TemplateRowAction {\n kind: \"row_action\";\n token: string;\n table: string;\n name: string;\n actionKind: \"update\" | \"agent\";\n confirm?: boolean;\n color?: ChoiceColor;\n /** `update`: what it writes. Fields by key; the installer resolves ids. */\n steps?: ({ field: string; set: \"value\"; value: unknown } | { field: string; set: \"clear\" })[];\n /** `agent`: what the record chat opens with. */\n prompt?: string;\n}\n\nexport interface TemplateAutomation {\n kind: \"automation\";\n token: string;\n name: string;\n when: UseCaseNotificationTrigger;\n /** What happens, in the business's words: \"text the owner the pickup window\". */\n then: string;\n}\n\nexport type TemplateExtra =\n | TemplateBooking\n | TemplatePortal\n | TemplateDashboard\n | TemplateDrillDown\n | TemplateDigest\n | TemplateChecklist\n | TemplateDocument\n | TemplateNotification\n | TemplateStageRules\n | TemplateRowAction\n | TemplateAutomation;\nexport type TemplateExtraKind = TemplateExtra[\"kind\"];\nexport const TEMPLATE_EXTRA_KINDS: readonly TemplateExtraKind[] = [\n \"booking\",\n \"portal\",\n \"dashboard\",\n \"drill_down\",\n \"digest\",\n \"checklist\",\n \"document\",\n \"notification\",\n \"stage_rules\",\n \"row_action\",\n \"automation\",\n];\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The agent — a copy of a platform agent, variables bound, one scripted question (Q6)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface TemplateAgentVariable {\n /** One of the platform agent's own variable names (templates/AGENTS.snapshot.json). */\n name: string;\n /** The table token bound to it at install. */\n table: string;\n describes: string;\n /**\n * Optional (Kits → Template merge): the full merge-field binding instead of the whole-table\n * default. Its `table` must equal `table` above.\n */\n binding?: TemplateMergeBinding;\n}\n\n/**\n * Q6: one question, and the exact `custom.record_aggregate` answer it must give. The\n * validator recomputes the answer from the seed rows with the store's own semantics\n * (text-equality filters, half-open date windows, sum over nothing is null, no rounding).\n */\nexport interface TemplateAgentQuestion {\n ask: string;\n /** Why the owner asks it — what they do differently depending on the answer. */\n whyItMatters: string;\n expect: {\n table: string;\n measure: AggregateMeasure;\n /**\n * Scalar equality, null = unset, or a {from, to} window on a date field whose bounds are\n * relative tokens WITH a time (\"@today-7d 00:00\"), never a bare or absolute date. The\n * filter may not match 90% or more of the table's rows (that is \"how many are there\").\n */\n filter?: Record<string, AggregateFilter>;\n /** Never 0 and never null. */\n answer: number;\n unit: string;\n };\n}\n\n/** The platform agent every template copies unless it says why not (`agentReason`). */\nexport const DEFAULT_TEMPLATE_AGENT = { id: \"4cd676c6-f55d-4426-b7eb-a9d0273566ec\", name: \"Answers From Your Tables\" } as const;\n\nexport interface TemplateAgent {\n /** The platform agent copied — id AND name, as the committed catalogue snapshot has them. */\n platformAgent: { id: string; name: string };\n /** Required when platformAgent is not DEFAULT_TEMPLATE_AGENT: why this template needs another agent. */\n agentReason?: string;\n /** The copy's name in the installed org. */\n name: string;\n variables: TemplateAgentVariable[];\n question: TemplateAgentQuestion;\n /** Optional (Kits → Template merge): what \"Try it\" sends the copy. */\n tryIt?: TemplateTryIt;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Kits → Template merge (2026-10-04, ADDITIVE): more agents, full merge-field bindings,\n// workflows and a display guide. Every field below is optional on TemplateSpec; a template\n// without them installs exactly as before.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * The merge-field binding, with the two ids replaced by template-local handles the host resolves\n * at install: `table` (a table token) and `rowIndex` (the index of a seed row of that table).\n * `collection` = the table's rows (one text, via `transform`); `reference` = one row (`rowIndex`);\n * `value` = one field (`field`) of one row (`rowIndex`).\n */\nexport interface TemplateMergeBinding {\n semantic: \"collection\" | \"reference\" | \"value\";\n table: string;\n rowIndex?: number;\n field?: string;\n transform?: { name: \"list\"; template?: string; join?: string; max?: number; header?: string };\n limit?: number;\n sort?: { field: string; dir: \"asc\" | \"desc\" };\n match?: Record<string, unknown>;\n /** What the agent sees when nothing matches (default \"absent\"). */\n missing?: string;\n}\n\n/** What \"Try it\" sends a template's agent copy: the user's message and/or its other variables. */\nexport interface TemplateTryIt {\n userInput?: string;\n variables?: Record<string, string>;\n}\n\nexport interface TemplateExtraAgentVariable {\n /** One of the platform agent's own variable names (templates/AGENTS.snapshot.json). */\n name: string;\n describes: string;\n binding: TemplateMergeBinding;\n}\n\n/** One more agent a template copies (no Q6: its question is the primary agent's). */\nexport interface TemplateExtraAgent {\n /** Template-local handle: guide highlights and workflow `{{agent:key}}` placeholders use it. */\n key: string;\n platformAgent: { id: string; name: string };\n /** Why this template carries this agent — a full sentence (agents never author agents). */\n agentReason: string;\n name: string;\n variables: TemplateExtraAgentVariable[];\n tryIt?: TemplateTryIt;\n}\n\n/** A workflow made at install through aidream `POST /workflows`; `{{table:<token>}}` / `{{agent:<key>}}` are resolved. */\nexport interface TemplateWorkflow {\n key: string;\n name: string;\n description: string;\n definition: unknown;\n}\n\n/** One display step of how the template works (NOT the gated `walk`). */\nexport interface TemplateGuideStep {\n title: string;\n body: string;\n /** `agent` key \"agent\" names the primary agent. */\n highlight?: { kind: \"table\" | \"agent\" | \"workflow\" | \"binding\"; key: string };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The walk — three steps, each a machine-checkable, non-vacuous assertion (Q5)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** One CSV-shaped import: a header of field keys and the rows under it, as the file holds them. */\nexport interface WalkImport {\n kind: \"import\";\n table: string;\n /** What the file is called: \"October customer list.csv\". */\n sourceName: string;\n /** The field that makes a row the same row (`p_dedupe_key`); it carries a `unique` rule. */\n dedupeKey: string;\n /** The header row: field keys (the mapping is identity). */\n columns: string[];\n /** The data rows, cell by cell, as text — at least one updates a seed row and one is new. */\n rows: string[][];\n}\n\n/** One row's move inside a grouped `moves` step. */\nexport interface WalkMove {\n table: string;\n row: string;\n field: string;\n to: string;\n set?: Record<string, unknown>;\n}\n\nexport type WalkAction =\n | { kind: \"open\"; surface: string }\n /**\n * A stage move, optionally landing with the fields that stage requires or implies (`set`:\n * \"mark Paid\" writes paid_on and balance in the same step). Judged as ONE step: stage\n * requires, statusImplies, date pairs and the stage's date rule are checked on the result.\n * A checker or installer runs it as ONE store call, as the person:\n * `pipeline_move(p_record_id, p_to, p_also => set)` — the door writes `p_also` with the\n * stage in the same record write, judged by the same Rules (the board's \"this move needs\n * these fields\" prompt makes the same call). Never record_update first: that leaves a\n * half-moved row if the move is then refused.\n */\n | { kind: \"move\"; table: string; row: string; field: string; to: string; set?: Record<string, unknown> }\n /**\n * A GROUPED step: 2–3 linked moves made together (\"accept the quote AND move its lead to\n * Agreement signed\"). Each move is judged against its own table's transitions, requires,\n * statusImplies and date rules; the template's cross-table rules (statusAgrees,\n * withinParent, childDates) are judged on the state after the WHOLE group. A checker runs it\n * as one `pipeline_move(p_record_id, p_to, p_also => set)` per row, in the listed order, as\n * the person; the expect asserts where one of the moved rows landed.\n */\n | { kind: \"moves\"; moves: WalkMove[] }\n /**\n * One field (`field` + `value`) or several at once (`set: {field: value, …}` — \"mark paid\"\n * sets status, paid and balance together); the coherence rules judge the whole result.\n */\n | { kind: \"edit\"; table: string; row: string; field?: string; value?: unknown; set?: Record<string, unknown> }\n | { kind: \"submit_form\"; form: string; values: Record<string, unknown> }\n | { kind: \"archive\"; table: string; row: string }\n | { kind: \"restore\"; table: string; row: string }\n | WalkImport\n | { kind: \"ask_agent\" };\n\nexport type WalkAssertion =\n /** The surface renders with at least `minItems` (≥ 1) records. */\n /**\n * The surface renders with at least `minItems` (≥ 1) records. `within` is the date window the\n * step talks about (\"the next three weeks\"): relative tokens on the view's date field, checked\n * on every install weekday. A step that names a span on a calendar or timeline must carry it.\n */\n | { kind: \"renders\"; surface: string; minItems: number; within?: { from?: string; to?: string } }\n /** Over the walk's state after this step; never 0. */\n | { kind: \"count\"; table: string; where?: Record<string, AggregateFilter>; equals: number }\n | { kind: \"value\"; table: string; row: string; field: string; equals: unknown }\n | { kind: \"aggregate\"; table: string; measure: AggregateMeasure; where?: Record<string, AggregateFilter>; equals: number }\n /** After `ask_agent`: the exact number the agent must answer (= agent.question.expect.answer). */\n | { kind: \"agent_answer\"; equals: number }\n /** After `archive` / `restore`: the row it acted on is (or is no longer) archived. */\n | { kind: \"archived\"; table: string; row: string; equals: boolean };\n\nexport interface WalkStep {\n /** What the person does, in plain words: \"Drag Rosa to Scheduled\". */\n says: string;\n action: WalkAction;\n expect: WalkAssertion;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Foundation, provenance, footprint\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** A table marked as day-one foundation data (R13): kept for the reason given. */\nexport interface TemplateFoundation {\n table: string;\n keptFor: string;\n}\n\nexport interface TemplateSource {\n title: string;\n url?: string;\n /** What was taken: structure ideas only — never text, data or a real person. */\n took: string;\n}\n\nexport interface TemplateProvenance extends UseCaseProvenance {\n sources: TemplateSource[];\n /** Every domain an email, website or url in the file uses. Each must not resolve in DNS (G6). */\n fictionalDomains: string[];\n /** Every street a numbered address in the file is on: invented, never a real street. */\n fictionalStreets: string[];\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The template\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** The five singular artefacts a UseCase carries; a template derives them (toUseCase). */\nexport type UseCaseSingulars = \"form\" | \"pipeline\" | \"dashboardQuestion\" | \"documentTemplate\" | \"notificationRule\";\n\n/**\n * ONE TEMPLATE: the UseCase's business, tables and relationships, with the singulars\n * replaced by their plural, installable forms (forms[], stage_rules / document /\n * notification extras, the agent's question).\n */\nexport interface TemplateSpec extends Omit<UseCase, UseCaseSingulars | \"tables\" | \"provenance\" | \"industry\"> {\n /** The schema version of this file (TEMPLATE_SPEC_VERSION). */\n specVersion: typeof TEMPLATE_SPEC_VERSION;\n /** The CATALOGUE.json row this realises: \"T0042\". Stable, never positional. */\n catalogueId: string;\n industry: IndustryGroup;\n /** The practitioner's own vertical: \"Dental practice\", \"Residential HVAC\". */\n vertical: string;\n job: TemplateJob;\n audience: TemplateAudience;\n teaches: TeachesFeature;\n strengths: Strength[];\n requires: CapabilityWord[];\n tables: TemplateTable[];\n sharedBlocks: SharedBlockUse[];\n views: TemplateView[];\n forms: TemplateForm[];\n dimensions: TemplateDimensions[];\n extras: TemplateExtra[];\n agent: TemplateAgent;\n /** Three teaching steps, plus an optional fourth that is the ask_agent step. */\n walk: [WalkStep, WalkStep, WalkStep] | [WalkStep, WalkStep, WalkStep, WalkStep];\n foundation: TemplateFoundation[];\n provenance: TemplateProvenance;\n /** The gallery card's picture (lane 2), relative to the template file. */\n previewImage?: string;\n /** Content version: an integer, bumped on every published change. */\n version: number;\n /**\n * Lane 12 P7: tables that are Confidential (asked of the chair after install — a template never\n * sets the level itself) and tables whose members add their own rows. See ./confidential.\n */\n confidential?: TemplateConfidential[];\n membersAddRows?: string[];\n /** Kits → Template merge: more agents the install copies, after `agent`. */\n extraAgents?: TemplateExtraAgent[];\n /** Kits → Template merge: workflows the install creates. */\n workflows?: TemplateWorkflow[];\n /** Kits → Template merge: how-it-works steps, shown only (the gated teaching steps are `walk`). */\n guide?: TemplateGuideStep[];\n}\n\n/** \"3 tables · 2 views · 1 form · 1 booking\" plus the counts it is made of — what uninstall takes back. */\nexport interface TemplateFootprint {\n tables: number;\n /** Shared-block tables it seeds rows into (not owned: uninstall archives its rows only). */\n sharedBlocks: number;\n views: number;\n forms: number;\n dimensions: number;\n extras: Partial<Record<TemplateExtraKind, number>>;\n agents: number;\n /** Workflows an install creates (host step). */\n workflows: number;\n /**\n * custom.portal_declare opens the organization's outside sign-in. Q7: uninstall restores\n * the setting it found (the installer records the before-value).\n */\n opensOutsideSignIn: boolean;\n line: string;\n}\n\nconst EXTRA_WORDS: Record<TemplateExtraKind, [string, string]> = {\n booking: [\"booking page\", \"booking pages\"],\n portal: [\"portal\", \"portals\"],\n dashboard: [\"dashboard\", \"dashboards\"],\n drill_down: [\"drill-down\", \"drill-downs\"],\n digest: [\"digest\", \"digests\"],\n checklist: [\"checklist\", \"checklists\"],\n document: [\"document\", \"documents\"],\n notification: [\"notification\", \"notifications\"],\n stage_rules: [\"stage rule set\", \"stage rule sets\"],\n row_action: [\"row action\", \"row actions\"],\n automation: [\"automation\", \"automations\"],\n};\n\nfunction counted(n: number, [one, many]: [string, string]): string {\n return `${n} ${n === 1 ? one : many}`;\n}\n\n/** The footprint, DERIVED from the spec — never written by hand, so it cannot drift. */\nexport function footprintOf(\n spec: Pick<TemplateSpec, \"tables\" | \"views\" | \"forms\" | \"extras\" | \"agent\" | \"dimensions\" | \"sharedBlocks\"> &\n Partial<Pick<TemplateSpec, \"extraAgents\" | \"workflows\">>,\n): TemplateFootprint {\n const extras: Partial<Record<TemplateExtraKind, number>> = {};\n for (const extra of spec.extras ?? []) extras[extra.kind] = (extras[extra.kind] ?? 0) + 1;\n const dimensions = spec.dimensions?.length ?? 0;\n // Every table an install makes: the template's own and its shared blocks (a Team table is a table too —\n // a card that said \"3 tables\" installed 4).\n const tables = (spec.tables?.length ?? 0) + (spec.sharedBlocks?.length ?? 0);\n // A part the template does not make is left out (\"1 table · 3 agents\", never \"0 views · 0 forms\").\n const parts = [\n ...(tables ? [counted(tables, [\"table\", \"tables\"])] : []),\n ...(spec.views?.length ? [counted(spec.views.length, [\"view\", \"views\"])] : []),\n ...(spec.forms?.length ? [counted(spec.forms.length, [\"form\", \"forms\"])] : []),\n ...(dimensions ? [counted(dimensions, [\"dimension set\", \"dimension sets\"])] : []),\n ...TEMPLATE_EXTRA_KINDS.filter((k) => extras[k]).map((k) => counted(extras[k] ?? 0, EXTRA_WORDS[k])),\n ];\n // Every agent an install copies: the template's own and its extra agents (a card that said\n // \"1 agent\" made 3).\n const agents = (spec.agent ? 1 : 0) + (spec.extraAgents?.length ?? 0);\n if (agents) parts.push(counted(agents, [\"agent\", \"agents\"]));\n const workflows = spec.workflows?.length ?? 0;\n if (workflows) parts.push(counted(workflows, [\"workflow\", \"workflows\"]));\n return {\n tables,\n sharedBlocks: spec.sharedBlocks?.length ?? 0,\n views: spec.views?.length ?? 0,\n forms: spec.forms?.length ?? 0,\n dimensions,\n extras,\n agents,\n workflows,\n opensOutsideSignIn: (extras.portal ?? 0) > 0,\n line: parts.join(\" · \"),\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The catalogue row (templates/CATALOGUE.json) and the agent snapshot\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const CATALOGUE_STATUSES = [\"planned\", \"authoring\", \"checking\", \"waiting_on_lane_10\", \"ready\", \"published\", \"retired\"] as const;\nexport type CatalogueStatus = (typeof CATALOGUE_STATUSES)[number];\n\nexport interface CatalogueRow {\n /** Stable forever: a retired row keeps its id with status \"retired\"; ids are never reused. */\n catalogueId: string;\n industry: IndustryGroup;\n /** The vertical within the group: \"Dental practice\". */\n vertical: string;\n job: TemplateJob;\n teaches: TeachesFeature;\n strengths: Strength[];\n audience: TemplateAudience;\n /** One sentence the writer starts from: who, what business, what job. */\n personaSeed: string;\n ownerLane: string;\n status: CatalogueStatus;\n /** \"scope-template:<key>\" | \"use-case:<id>\" | \"new\". */\n source: string;\n /** Why a retired row was retired (\"duplicate of T0009\"). */\n retiredBecause?: string;\n /** The gallery card's picture, once the template has one. */\n previewImage?: string;\n /** Capabilities this row will need that may still be held (seed.attachments, automation), so batches can skip held rows. */\n requires?: CapabilityWord[];\n /**\n * The real install check of the CURRENT file (scripts/templates-publish.ts verify): installed through\n * the template family on the clone as a person, then uninstalled. `fileHash` pins which file passed.\n */\n installCheck?: {\n result: \"pass\" | \"fail\";\n /** Where the install ran: \"live\" since 2026-10-04 (Arman 2026-10-03: checks run on live; the clone is for destructive rehearsals only). */\n target: \"clone\" | \"live\";\n checkedAt: string;\n fileHash: string;\n wallMs: number;\n installMs?: number;\n steps?: number;\n calls?: number;\n orgId?: string;\n /** The refusal verbatim (store sentence, validator problem, or uninstall leftover). */\n refusal?: string;\n };\n /** Set by scripts/templates-publish.ts publish once declared for everyone on production. */\n published?: { templateId: string; version: number; steps: number; publishedAt: string; fileHash: string };\n}\n\n/** One platform agent a template may copy (templates/AGENTS.snapshot.json). */\nexport interface AgentSnapshotRow {\n id: string;\n name: string;\n variables: string[];\n}\n\n/** One entry of templates/RETIRED_IDS.json — append-only. */\nexport interface RetiredId {\n catalogueId: string;\n retiredOn: string;\n because: string;\n}\n","// src/templates/confidential.ts — @ai-matrx/records (templates)\n//\n// A TEMPLATE'S CONFIDENTIAL TABLES AND ITS \"MEMBERS ADD THEIR OWN ROWS\" TABLES.\n//\n// Lane 12 P7 (the HR employee review). Two table settings a template states and the install plan\n// alone cannot make:\n//\n// membersAddRows: [\"review_submission\", …]\n// The table's document says members_add_rows = true (custom.table_add_rung, CHAIR-DOORS-3A):\n// every member who may see the table adds rows, each edits only her own. A plan step sets it\n// through custom.record_change_many on the Table kernel — a door the family already allows,\n// run as the installing person, who owns the table she just made.\n//\n// confidential: [{ table, readers: [{field, level, when?}], makerIsReader, why }]\n// The store Table's Confidential level (custom.confidential_answer: the row's owner and the people\n// the row's own reader fields name — no organization, admin or library lane). It is set ONLY\n// through custom.set_table_confidential_arman_explicitly_approved, which records Arman's words\n// and which no client role may call (CHAIR-GUIDANCE: \"set only through the Arman-approved door\n// the chair runs\"). So a template never sets it: installing answers these REQUESTS, and the\n// chair runs each with Arman's standing word. Until the chair has run them the tables are\n// ordinary organization tables, so a host must not open the template's forms before then\n// (`confidentialPending`).\n//\n// `when` is a reader entry's condition on the row's own values (CHAIR-ACCESS c), written in the spec\n// as {column key: stored value} and sent as a Rule over field ids (`whenRule`), so derived columns\n// (lookups) are read too and a reader can wait on what another row says (\"both sides submitted\").\n\nimport type { TemplateSpec } from \"./types\";\n\nexport const TABLE_KERNEL_ID = \"11111111-0000-4000-8000-000000000001\";\n\nexport type ConfidentialLevel = \"viewer\" | \"commenter\" | \"editor\";\n\nexport interface TemplateConfidentialReader {\n /** A member / person field of the table whose value names the reader. */\n field: string;\n level: ConfidentialLevel;\n /** The row's own condition, flat saved-view filter: { \"cycle_manager_status\": \"Submitted\" }. */\n when?: Record<string, string | number | boolean>;\n}\n\nexport interface TemplateConfidential {\n table: string;\n readers: TemplateConfidentialReader[];\n /** true: the person who installs it is only a reader (the organization owns the table). */\n makerIsReader: boolean;\n /** One sentence for the chair and for Arman: why this table is Confidential. */\n why: string;\n}\n\nexport interface TemplateTableSettings {\n confidential?: TemplateConfidential[];\n membersAddRows?: string[];\n}\n\n/** One request the chair runs after install (the SQL is the exact call; words are the chair's). */\nexport interface ConfidentialRequest {\n table: string;\n tableId: string;\n readers: Array<{ field: string; level: ConfidentialLevel; when?: Record<string, unknown> }>;\n makerIsReader: boolean;\n why: string;\n /** `select custom.set_table_confidential_arman_explicitly_approved(…)` with `:'arman_words'` left for the chair. */\n sql: string;\n}\n\nconst sqlText = (s: string) => `'${s.replace(/'/g, \"''\")}'`;\n\n/** What a spec's confidential / membersAddRows say is wrong, in plain sentences ([] = fine). */\nexport function tableSettingsProblems(spec: TemplateSpec & TemplateTableSettings): string[] {\n const out: string[] = [];\n const tables = new Map(spec.tables.map((t) => [t.token, t]));\n for (const token of spec.membersAddRows ?? []) {\n if (!tables.has(token)) out.push(`membersAddRows names \"${token}\", which is not one of this template's tables.`);\n }\n const seen = new Set<string>();\n for (const c of spec.confidential ?? []) {\n const t = tables.get(c.table);\n if (!t) {\n out.push(`confidential names \"${c.table}\", which is not one of this template's tables.`);\n continue;\n }\n if (seen.has(c.table)) out.push(`confidential lists \"${c.table}\" twice.`);\n seen.add(c.table);\n if (!c.why?.trim()) out.push(`confidential \"${c.table}\" says why it is Confidential (one sentence for Arman).`);\n if (typeof c.makerIsReader !== \"boolean\") out.push(`confidential \"${c.table}\" says makerIsReader true or false.`);\n if (!c.readers?.length) out.push(`confidential \"${c.table}\" names at least one reader field; with none only each row's own writer reads it.`);\n for (const r of c.readers ?? []) {\n const f = t.fields.find((x) => x.key === r.field);\n if (!f) out.push(`confidential \"${c.table}\" reader \"${r.field}\" is not a field of the table.`);\n else if (![\"member\", \"person\", \"relation\"].includes(f.parityType as string)) out.push(`confidential \"${c.table}\" reader \"${r.field}\" is ${f.parityType}; a reader field names people (member).`);\n if (![\"viewer\", \"commenter\", \"editor\"].includes(r.level)) out.push(`confidential \"${c.table}\" reader \"${r.field}\" level is viewer, commenter or editor (never above editor).`);\n for (const k of Object.keys(r.when ?? {})) {\n if (!t.fields.some((x) => x.key === k)) out.push(`confidential \"${c.table}\" reader \"${r.field}\" waits on \"${k}\", which is not a field of the table.`);\n }\n }\n }\n return out;\n}\n\n/** The plan steps that set members_add_rows (custom.record_change_many on the Table kernel, as the person). */\nexport function membersAddRowsSteps(spec: TemplateTableSettings, tableRef: (token: string) => string) {\n return (spec.membersAddRows ?? []).map((token) => ({\n label: `members_add_rows.${token}`,\n door: \"record_change_many\" as const,\n args: {\n p_organization_id: \"${org}\",\n p_table_id: TABLE_KERNEL_ID,\n p_changes: [{ op: \"update\", record_id: tableRef(token), patch: { members_add_rows: true } }],\n },\n }));\n}\n\n/** The chair's requests for one install: table ids from the install answer's `made`. */\nexport function confidentialRequests(\n spec: TemplateTableSettings,\n made: Array<{ kind: string; ref: string; id: string | null }>,\n): ConfidentialRequest[] {\n const idOf = (token: string) => made.find((m) => m.kind === \"table\" && m.ref === `tables.${token}`)?.id ?? null;\n return (spec.confidential ?? []).map((c) => {\n const tableId = idOf(c.table);\n if (!tableId) throw new Error(`The install made no \"${c.table}\" table, so it cannot be made Confidential.`);\n const readers = c.readers.map((r) => ({ field: r.field, level: r.level, ...(r.when ? { when: whenRule(c.table, r.when, made) } : {}) }));\n return {\n table: c.table,\n tableId,\n readers,\n makerIsReader: c.makerIsReader,\n why: c.why,\n sql: `select custom.set_table_confidential_arman_explicitly_approved(${sqlText(tableId)}::uuid, ${sqlText(JSON.stringify(readers))}::jsonb, :'arman_words', current_date, ${c.makerIsReader});`,\n };\n });\n}\n\n/**\n * A reader's `when`, as the store asks it. The flat saved-view map compiles against the row's STORED\n * document only (custom.record_filter_sql reads r.data), so a lookup — \"both sides are submitted\",\n * read through the review cycle — would never be true there. A Rule expression is evaluated over\n * custom.record_values_of(r), which works lookups and roll-ups out on read; so every condition is\n * written as a Rule over the installed fields' ids (REC-17: a Rule points at a Field by id).\n */\nexport function whenRule(table: string, when: Record<string, unknown>, made: Array<{ kind: string; ref: string; id: string | null }>): Record<string, unknown> {\n const args = Object.entries(when).map(([key, value]) => {\n const id = made.find((m) => m.kind === \"field\" && m.ref === `fields.${table}.${key}`)?.id;\n if (!id) throw new Error(`The install answer names no field \"${key}\" on \"${table}\", so a reader cannot wait on it.`);\n return { op: \"eq\", args: [{ field: id }, { const: value }] };\n });\n return args.length === 1 ? args[0]! : { op: \"and\", args };\n}\n\n/** True while any of the template's Confidential tables is not Confidential yet (hold its forms). */\nexport function confidentialPending(spec: TemplateTableSettings, levels: Record<string, string | null | undefined>): boolean {\n return (spec.confidential ?? []).some((c) => levels[c.table] !== \"confidential\");\n}\n","// templates/extras.ts — Kits → Template merge (2026-10-04): the optional parts a kit carried.\n//\n// A template may carry, besides its one gated `agent`:\n// - `agent.variables[i].binding` the full merge-field binding (collection / one row / one field,\n// transform, limit, sort) instead of the whole-table default\n// - `extraAgents[]` more platform-agent copies, each variable bound the same way\n// - `workflows[]` workflows the host creates through aidream `POST /workflows`\n// - `guide[]` how-it-works steps, shown only (never the gated `walk`)\n// All are optional and ADDITIVE: a spec without them compiles, validates and installs exactly as\n// before. This file is their validator (`extrasProblems`, called once by validateTemplate) and\n// their compiler (`compileHostExtras`, called once by compileInstallPlan).\n//\n// The record pointer is template-local — a table token plus a seed-row index — and compiles to the\n// seed row's KEY; the install mints that row's id as `new:row.<token>.<key>` and the door's answer\n// hands the host those ids (custom._template_answer `host`), so the host never matches by name.\n\nimport type { UseCaseProblem } from \"../use-cases/validate\";\nimport type {\n AgentSnapshotRow,\n TemplateExtraAgent,\n TemplateMergeBinding,\n TemplateSpec,\n TemplateTable,\n TemplateTryIt,\n TemplateWorkflow,\n} from \"./types\";\n\n/** A binding as the install plan carries it: `rowIndex` replaced by the seed row's key. */\nexport interface TemplatePlanBinding extends Omit<TemplateMergeBinding, \"rowIndex\"> {\n rowKey?: string;\n}\n\nexport interface TemplatePlanExtraAgent {\n key: string;\n platformAgent: { id: string; name: string };\n name: string;\n bindings: Array<{ variable: string; describes: string; binding: TemplatePlanBinding }>;\n tryIt?: TemplateTryIt;\n}\n\nexport interface TemplateHostExtras {\n extraAgents?: TemplatePlanExtraAgent[];\n workflows?: TemplateWorkflow[];\n}\n\nconst KEY = /^[a-z][a-z0-9_]{0,63}$/;\nconst PLACEHOLDER = /\\{\\{(table|agent):([^}]+)\\}\\}/g;\n\nfunction tablesOf(spec: Pick<TemplateSpec, \"tables\">): Map<string, TemplateTable> {\n return new Map((spec.tables ?? []).map((t) => [t.token, t]));\n}\n\n/** The problems with one binding (`at` names where it sits). */\nfunction bindingProblems(at: string, b: TemplateMergeBinding | undefined, tables: Map<string, TemplateTable>, say: (at: string, says: string) => void): void {\n if (!b || typeof b !== \"object\") {\n say(at, \"Each variable carries its binding: what part of which table the agent reads.\");\n return;\n }\n if (![\"collection\", \"reference\", \"value\"].includes(b.semantic)) say(`${at}.semantic`, `\"${String(b.semantic)}\" is not a binding: it is a collection (the table's rows), a reference (one row) or a value (one field of one row).`);\n const t = tables.get(b.table);\n if (!t) {\n say(`${at}.table`, `It reads \"${b.table}\", which this template does not declare.`);\n return;\n }\n const keys = new Set(t.fields.map((f) => f.key));\n if (b.semantic === \"reference\" || b.semantic === \"value\") {\n const rows = t.rows ?? [];\n if (typeof b.rowIndex !== \"number\" || !Number.isInteger(b.rowIndex) || b.rowIndex < 0 || b.rowIndex >= rows.length) {\n say(`${at}.rowIndex`, `A ${b.semantic} points at one seed row of \"${b.table}\" by its index (0 to ${Math.max(rows.length - 1, 0)}); it has ${rows.length}.`);\n }\n } else if (b.rowIndex !== undefined) say(`${at}.rowIndex`, \"A collection reads the whole table; a row pointer belongs on a reference or a value.\");\n if (b.semantic === \"value\") {\n if (!b.field) say(`${at}.field`, \"A value names the one field it reads.\");\n else if (!keys.has(b.field)) say(`${at}.field`, `\"${b.table}\" has no field \"${b.field}\".`);\n }\n if (b.sort && !keys.has(b.sort.field)) say(`${at}.sort`, `It sorts on \"${b.sort.field}\", which \"${b.table}\" does not declare.`);\n if (b.sort && b.sort.dir !== \"asc\" && b.sort.dir !== \"desc\") say(`${at}.sort`, \"A sort is asc or desc.\");\n if (b.limit !== undefined && (!Number.isInteger(b.limit) || b.limit < 1)) say(`${at}.limit`, \"A limit is a whole number of rows, 1 or more.\");\n if (b.transform && b.transform.name !== \"list\") say(`${at}.transform`, `\"${String(b.transform.name)}\" is not a transform the resolver knows (list).`);\n}\n\n/** Every problem with the optional kit-merge parts of `spec`. Empty when it has none. */\nexport function extrasProblems(spec: TemplateSpec, agents: AgentSnapshotRow[] | undefined): UseCaseProblem[] {\n const problems: UseCaseProblem[] = [];\n const say = (at: string, says: string) => problems.push({ at, says });\n const tables = tablesOf(spec);\n\n // The primary agent's optional full bindings (every other rule on `agent` stays validateTemplate's).\n spec.agent?.variables?.forEach((v, vi) => {\n if (v.binding === undefined) return;\n const at = `agent.variables[${vi}].binding`;\n if (v.binding.table !== v.table) say(`${at}.table`, `The binding reads \"${v.binding.table}\" but the variable is bound to \"${v.table}\"; name one table.`);\n bindingProblems(at, v.binding, tables, say);\n });\n\n const extras: TemplateExtraAgent[] = spec.extraAgents ?? [];\n const agentKeys = new Set<string>([\"agent\"]);\n extras.forEach((a, ai) => {\n const at = `extraAgents[${ai}]`;\n if (!a.key || !KEY.test(a.key)) say(`${at}.key`, `\"${a.key}\" is not a key: lower-case letters, digits and _.`);\n else if (agentKeys.has(a.key)) say(`${at}.key`, `\"${a.key}\" is used twice (\"agent\" is the primary agent's).`);\n agentKeys.add(a.key);\n if (!a.name?.trim()) say(`${at}.name`, \"Name the copy the way the organization will see it.\");\n const row = agents?.find((x) => x.id === a.platformAgent?.id);\n if (!agents) say(`${at}.platformAgent`, \"No agent catalogue snapshot was given, so the agent could not be checked (pass templates/AGENTS.snapshot.json).\");\n else if (!row) say(`${at}.platformAgent`, `\"${a.platformAgent?.id}\" is not in the agent catalogue snapshot: a template copies a real platform agent, it never authors one.`);\n else if (row.name !== a.platformAgent.name) say(`${at}.platformAgent`, `The snapshot calls ${row.id} \"${row.name}\", not \"${a.platformAgent.name}\".`);\n if ((a.agentReason?.trim().split(/\\s+/).length ?? 0) < 8) say(`${at}.agentReason`, \"Say in agentReason, in a full sentence of at least eight words, why this template carries this agent.\");\n if (!a.variables?.length) say(`${at}.variables`, \"An agent without variables is not an agent: bind at least one to a table.\");\n const seen = new Set<string>();\n a.variables?.forEach((v, vi) => {\n const vat = `${at}.variables[${vi}]`;\n if (seen.has(v.name)) say(vat, `\"${v.name}\" is bound twice.`);\n seen.add(v.name);\n if (row && !row.variables.includes(v.name)) say(vat, `\"${row.name}\" has no variable \"${v.name}\"; its variables are: ${row.variables.join(\", \") || \"(none)\"}.`);\n if (!v.describes?.trim()) say(`${vat}.describes`, \"Say what the variable hands the agent.\");\n bindingProblems(`${vat}.binding`, v.binding, tables, say);\n });\n if (a.tryIt && row) {\n for (const k of Object.keys(a.tryIt.variables ?? {})) if (!row.variables.includes(k)) say(`${at}.tryIt.variables`, `\"${row.name}\" has no variable \"${k}\".`);\n }\n });\n\n const wfKeys = new Set<string>();\n (spec.workflows ?? []).forEach((w, wi) => {\n const at = `workflows[${wi}]`;\n if (!w.key || !KEY.test(w.key)) say(`${at}.key`, `\"${w.key}\" is not a key: lower-case letters, digits and _.`);\n else if (wfKeys.has(w.key)) say(`${at}.key`, `\"${w.key}\" is used twice.`);\n wfKeys.add(w.key);\n if (!w.name?.trim()) say(`${at}.name`, \"Name the workflow.\");\n if (!w.definition || typeof w.definition !== \"object\") say(`${at}.definition`, \"A workflow carries its definition (nodes and edges).\");\n for (const m of JSON.stringify(w.definition ?? null).matchAll(PLACEHOLDER)) {\n if (m[1] === \"table\" && !tables.has(m[2]!)) say(`${at}.definition`, `It names {{table:${m[2]}}}, which this template does not declare.`);\n if (m[1] === \"agent\" && !agentKeys.has(m[2]!)) say(`${at}.definition`, `It names {{agent:${m[2]}}}, which is not one of this template's agents.`);\n }\n });\n\n (spec.guide ?? []).forEach((g, gi) => {\n const at = `guide[${gi}]`;\n if (!g.title?.trim() || !g.body?.trim()) say(at, \"A guide step has a title and a body.\");\n const h = g.highlight;\n if (!h) return;\n const known =\n h.kind === \"table\" ? tables.has(h.key) : h.kind === \"agent\" ? agentKeys.has(h.key) : h.kind === \"workflow\" ? wfKeys.has(h.key) : h.kind === \"binding\";\n if (!known) say(`${at}.highlight`, `It highlights the ${h.kind} \"${h.key}\", which this template does not carry.`);\n });\n return problems;\n}\n\nfunction planBinding(b: TemplateMergeBinding, tables: Map<string, TemplateTable>): TemplatePlanBinding {\n const { rowIndex, ...rest } = b;\n if (rowIndex === undefined) return rest;\n const row = tables.get(b.table)?.rows?.[rowIndex];\n if (!row) throw new Error(`The binding points at seed row ${rowIndex} of \"${b.table}\", which has no such row.`);\n return { ...rest, rowKey: row.key };\n}\n\n/** The install plan's host parts: the primary agent's full bindings, extra agents and workflows. */\nexport function compileHostExtras(spec: TemplateSpec): {\n agentBindings: Map<string, TemplatePlanBinding>;\n extras: TemplateHostExtras;\n} {\n const tables = tablesOf(spec);\n const agentBindings = new Map<string, TemplatePlanBinding>();\n for (const v of spec.agent?.variables ?? []) if (v.binding) agentBindings.set(v.name, planBinding(v.binding, tables));\n const extras: TemplateHostExtras = {};\n if (spec.extraAgents?.length) {\n extras.extraAgents = spec.extraAgents.map((a) => ({\n key: a.key,\n platformAgent: a.platformAgent,\n name: a.name,\n bindings: a.variables.map((v) => ({ variable: v.name, describes: v.describes, binding: planBinding(v.binding, tables) })),\n ...(a.tryIt ? { tryIt: a.tryIt } : {}),\n }));\n }\n if (spec.workflows?.length) extras.workflows = spec.workflows;\n return { agentBindings, extras };\n}\n","// src/store.generated.ts — @ai-matrx/records\n//\n// GENERATED. Do not edit by hand: `pnpm records:generate` rewrites it from the\n// live record store, and `pnpm check:store-registry` fails the build when this\n// file and the store disagree. Every literal below was read from the database's\n// own catalogue — the vocabularies from the store's vocabulary functions, the\n// parity types from `custom.parity_field_types()`, the doors from `pg_proc`,\n// the kernel ids from the kernel rows themselves, the tokens from\n// `platform.entity_types`.\n//\n// Counts at generation: 3 actor words, 4 absence\n// reasons, 14 parity field types, 29 declarable field kinds,\n// 76 rule node kinds,\n// 9 kernel Tables, 884 doors, 72 knobs,\n// 1093 entity tokens.\n\nexport const ACTOR_VOCABULARY = [\"user\", \"agent\", \"system\"] as const;\n\n/** The three words the store still accepts and rewrites, and what each becomes. */\nexport const RETIRED_ACTOR_WORDS = {\"ai\": \"agent\", \"code\": \"system\", \"human\": \"user\"} as const;\n\nexport const ABSENCE_REASONS = [\"never asked\", \"none\", \"refused\", \"conflicting\"] as const;\n\nexport const VALUE_ENVELOPE_KEYS = [\"ver\", \"src\", \"actor\", \"on_behalf_of\", \"at\", \"absent\", \"alternates\", \"dated\", \"pinned\"] as const;\n\nexport const VALUE_ALTERNATE_KEYS = [\"value\", \"src\", \"rank\"] as const;\n\nexport const STORAGE_MODES = [\"light\", \"heavy\"] as const;\n\nexport const RULE_USES = [\"validate\", \"compute\", \"membership\", \"applicability\"] as const;\n\nexport const PER_VALUE_ACCESS_WORDS = [\"visibility\", \"access\", \"share\", \"acl\", \"permission\", \"permissions\", \"secret\"] as const;\n\n/** FLD-11's parity floor, each with the behaviour it is MADE OF (FLD-1). */\nexport const PARITY_FIELD_TYPES = [\n { parity_type: \"attachment\", behavior: \"relation\", made_of: \"REC-31: a File record reached through a relation, target the kernel `File` Table\" },\n { parity_type: \"checkbox\", behavior: \"boolean\", made_of: \"a ticked or unticked answer, stored as a REAL boolean — and a record that never answered holds neither, so filters and group-by see three states, not two\" },\n { parity_type: \"currency\", behavior: \"range\", made_of: \"FLD-N-1: a number whose UNIT is the currency and whose format is currency — on the Field, never in presentation\" },\n { parity_type: \"datetime\", behavior: \"range\", made_of: \"a range of kind date or datetime — the dated modifier says the VALUES are dated, which is a different question\" },\n { parity_type: \"email\", behavior: \"text\", made_of: \"text whose format is email\" },\n { parity_type: \"formula\", behavior: \"formula\", made_of: \"FLD-9: a declared computation, on read or on write, evaluated by custom.rule_eval\" },\n { parity_type: \"lookup\", behavior: \"formula\", made_of: \"a Value read THROUGH a relation — config.via names the relation field, config.pick the Value on the far side\" },\n { parity_type: \"member\", behavior: \"relation\", made_of: \"a person: a relation whose target is the kernel `Person` Table\" },\n { parity_type: \"multi_select\", behavior: \"list\", made_of: \"many choices from the same Table — the multi modifier, never a second behaviour\" },\n { parity_type: \"percent\", behavior: \"range\", made_of: \"a number whose unit is % and whose format is percent\" },\n { parity_type: \"phone\", behavior: \"text\", made_of: \"text whose format is phone\" },\n { parity_type: \"rollup\", behavior: \"formula\", made_of: \"an aggregate ALONG a relation — config.via, config.of, config.agg; far-side ids are taken DISTINCT, so nothing is counted twice\" },\n { parity_type: \"select\", behavior: \"list\", made_of: \"one choice from a Table shown as a list (FLD-5/FLD-6)\" },\n { parity_type: \"url\", behavior: \"text\", made_of: \"text whose format is url, with the pattern Rule that makes the format enforceable\" },\n] as const;\n\n/**\n * THE ONE REGISTRY: every kind a column can be DECLARED as, from\n * `custom.field_kinds()`. `parity` says whether the kind is one of FLD-11's parity\n * floor; the rest are the behaviours and formats the declaration door answers to and\n * nothing else enumerated — which is how `signature` came to be a shape\n * `custom.doc_sign` accepted and no screen could offer.\n */\nexport const DECLARABLE_FIELD_KINDS = [\n { kind: \"address\", behavior: \"text\", parity: false, made_of: \"P4: behaviour text, format address; the value is {street, city, region, postal_code, country}, every part optional, at least one filled\" },\n { kind: \"attachment\", behavior: \"relation\", parity: true, made_of: \"REC-31: a File record reached through a relation, target the kernel `File` Table\" },\n { kind: \"barcode\", behavior: \"text\", parity: false, made_of: \"P4: behaviour text, format barcode; one printable line a scanner reads, config.symbology optional (custom.barcode_symbologies()), EAN/UPC digits and check digit enforced\" },\n { kind: \"checkbox\", behavior: \"boolean\", parity: true, made_of: \"a ticked or unticked answer, stored as a REAL boolean — and a record that never answered holds neither, so filters and group-by see three states, not two\" },\n { kind: \"count\", behavior: \"formula\", parity: false, made_of: \"P4: a roll-up whose config.agg is count, with format count: how many records a many-relation points at, as a number of its own\" },\n { kind: \"created_by\", behavior: \"formula\", parity: false, made_of: \"P4: a formula Field whose config.system is created_by: who made the record, {id, name}, filled by the store from the record's writer on read and never typed\" },\n { kind: \"currency\", behavior: \"range\", parity: true, made_of: \"FLD-N-1: a number whose UNIT is the currency and whose format is currency — on the Field, never in presentation\" },\n { kind: \"datetime\", behavior: \"range\", parity: true, made_of: \"a range of kind date or datetime — the dated modifier says the VALUES are dated, which is a different question\" },\n { kind: \"duration\", behavior: \"range\", parity: false, made_of: \"P4: behaviour range, format duration, unit seconds; a length of time kept as seconds, never below zero\" },\n { kind: \"email\", behavior: \"text\", parity: true, made_of: \"text whose format is email\" },\n { kind: \"entity_reference\", behavior: \"relation\", parity: false, made_of: \"SC-R / P12: a relation whose target mode is any (REL-8), restricted by config.allowed_types to the platform kinds it may name (custom.entity_reference_kinds() — agents, notes, web sites, workbooks, datasets, conversations …); each value is {token, id}, the edge a platform.associations row record → <token>. File and Person stay relations to their kernel Tables\" },\n { kind: \"formula\", behavior: \"formula\", parity: true, made_of: \"FLD-9: a declared computation, on read or on write, evaluated by custom.rule_eval\" },\n { kind: \"long_text\", behavior: \"text\", parity: false, made_of: \"behaviour text with format long and config.multiline, for several lines rather than one\" },\n { kind: \"lookup\", behavior: \"formula\", parity: true, made_of: \"a Value read THROUGH a relation — config.via names the relation field, config.pick the Value on the far side\" },\n { kind: \"member\", behavior: \"relation\", parity: true, made_of: \"a person: a relation whose target is the kernel `Person` Table\" },\n { kind: \"modified_by\", behavior: \"formula\", parity: false, made_of: \"P4: a formula Field whose config.system is modified_by: who last changed the record, {id, name}, filled by the store on read and never typed\" },\n { kind: \"multi_select\", behavior: \"list\", parity: true, made_of: \"many choices from the same Table — the multi modifier, never a second behaviour\" },\n { kind: \"number\", behavior: \"range\", parity: false, made_of: \"a plain number: behaviour range with no date kind and neither the currency nor the percent format\" },\n { kind: \"percent\", behavior: \"range\", parity: true, made_of: \"a number whose unit is % and whose format is percent\" },\n { kind: \"phone\", behavior: \"text\", parity: true, made_of: \"text whose format is phone\" },\n { kind: \"rating\", behavior: \"range\", parity: false, made_of: \"P4: behaviour range, format rating; a whole number of stars from 0 to its max Rule (1 to 10, default 5), shown as stars\" },\n { kind: \"relation\", behavior: \"relation\", parity: false, made_of: \"REL / FLD-11: a relation a person aims themselves — relation_target names a Table of this organization, and it is a BEHAVIOUR, never a parity type of its own\" },\n { kind: \"rich_text\", behavior: \"text\", parity: false, made_of: \"P4: behaviour text, format rich_text; Markdown with no raw HTML and no script links, shown formatted\" },\n { kind: \"rollup\", behavior: \"formula\", parity: true, made_of: \"an aggregate ALONG a relation — config.via, config.of, config.agg; far-side ids are taken DISTINCT, so nothing is counted twice\" },\n { kind: \"select\", behavior: \"list\", parity: true, made_of: \"one choice from a Table shown as a list (FLD-5/FLD-6)\" },\n { kind: \"signature\", behavior: \"text\", parity: false, made_of: \"VAL-10: behaviour text whose format is signature — the one shape custom.doc_sign accepts, sealed by custom.doc_signature_write and checked by custom.doc_signature_intact\" },\n { kind: \"status\", behavior: \"list\", parity: false, made_of: \"P4: a single-choice list with format status; config.status_groups puts each choice key in todo, in_progress or done (Notion's Status)\" },\n { kind: \"text\", behavior: \"text\", parity: false, made_of: \"plain text: behaviour text with no format — it carries no parity type, which is exactly what custom.parity_type answers for it\" },\n { kind: \"url\", behavior: \"text\", parity: true, made_of: \"text whose format is url, with the pattern Rule that makes the format enforceable\" },\n] as const;\n\n/** The node kinds `custom.rule_eval` evaluates, and the lane that owns each. */\nexport const RULE_NODE_KINDS = [\n { node: \"actor_at_least\", evaluated_by: \"PIPELINES\" },\n { node: \"add\", evaluated_by: \"W1-RULE\" },\n { node: \"and\", evaluated_by: \"W1-RULE\" },\n { node: \"concat\", evaluated_by: \"W1-RULE\" },\n { node: \"const\", evaluated_by: \"W1-RULE\" },\n { node: \"div\", evaluated_by: \"W1-RULE\" },\n { node: \"eq\", evaluated_by: \"W1-RULE\" },\n { node: \"field\", evaluated_by: \"W1-RULE\" },\n { node: \"fx.abs\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.add\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.and\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.arraycompact\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.arrayjoin\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.autonumber\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.average\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.blank\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.concatenate\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.contains\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.created_time\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.dateadd\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.datediff\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.datetime_format\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.day\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.div\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.eq\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.find\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.gt\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.gte\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.if\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.isblank\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.left\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.len\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.lower\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.lt\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.lte\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.max\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.min\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.mod\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.modified_time\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.month\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.mul\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.ne\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.neg\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.not\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.now\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.or\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.regex_match\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.right\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.round\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.sub\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.substitute\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.sum\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.switch\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.today\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.trim\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.upper\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.workday\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.year\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"gt\", evaluated_by: \"W1-RULE\" },\n { node: \"gte\", evaluated_by: \"W1-RULE\" },\n { node: \"length\", evaluated_by: \"W1-RULE\" },\n { node: \"lt\", evaluated_by: \"W1-RULE\" },\n { node: \"lte\", evaluated_by: \"W1-RULE\" },\n { node: \"matches\", evaluated_by: \"W1-RULE\" },\n { node: \"merge_field\", evaluated_by: \"W5-MERGE-B\" },\n { node: \"mul\", evaluated_by: \"W1-RULE\" },\n { node: \"ne\", evaluated_by: \"W1-RULE\" },\n { node: \"not\", evaluated_by: \"W1-RULE\" },\n { node: \"or\", evaluated_by: \"W1-RULE\" },\n { node: \"parent_field\", evaluated_by: \"W1-RULE-APPLY\" },\n { node: \"present\", evaluated_by: \"W1-RULE\" },\n { node: \"previous\", evaluated_by: \"PIPELINES\" },\n { node: \"sibling_count\", evaluated_by: \"STAGE-RULES\" },\n { node: \"stage_count\", evaluated_by: \"PIPELINES\" },\n { node: \"sub\", evaluated_by: \"W1-RULE\" },\n { node: \"within\", evaluated_by: \"CHAIR-FILTER\" },\n] as const;\n\n/** REC-27. The kernel, by name and by id, as the store holds it. */\nexport const KERNEL_TABLES = [\n { id: \"11111111-0000-4000-8000-000000000002\", name: \"Field\" },\n { id: \"11111111-0000-4000-8000-000000000006\", name: \"File\" },\n { id: \"11111111-0000-4000-8000-000000000009\", name: \"Merge Field\" },\n { id: \"11111111-0000-4000-8000-000000000004\", name: \"Organization\" },\n { id: \"11111111-0000-4000-8000-000000000005\", name: \"Person\" },\n { id: \"11111111-0000-4000-8000-000000000007\", name: \"Presentation\" },\n { id: \"11111111-0000-4000-8000-000000000003\", name: \"Rule\" },\n { id: \"11111111-0000-4000-8000-000000000001\", name: \"Table\" },\n { id: \"11111111-0000-4000-8000-000000000008\", name: \"Widget\" },\n] as const;\n\n/**\n * Every door the store actually has, with the argument list and the result the\n * catalogue reports. A client call whose door is not in this list is answered\n * `door_absent` by name — never a guess, never a silent no-op.\n */\nexport const STORE_DOORS = [\n { name: \"absence_reasons\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"action_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_actions jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"action_run\", args: \"p_organization_id uuid, p_action_id uuid, p_record_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"actor_vocabulary\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"actor_word\", args: \"p_declared text\", returns: \"text\", security: \"invoker\" },\n { name: \"addressed_cap\", args: \"p_user_id uuid, p_type text, p_id uuid, p_organization_id uuid DEFAULT NULL::uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"permission_level\", security: \"definer\" },\n { name: \"addressed_cap_specific\", args: \"p_user_id uuid, p_type text, p_id uuid, p_organization_id uuid DEFAULT NULL::uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"permission_level\", security: \"definer\" },\n { name: \"agent_change_approval\", args: \"p_organization uuid, p_conversation uuid DEFAULT NULL::uuid, p_table uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"agent_change_trust\", args: \"p_organization_id uuid, p_approval_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"agent_context\", args: \"p_organization_id uuid, p_table_id uuid, p_limit integer DEFAULT 50\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"agent_context_value\", args: \"p_doc jsonb, p_key text, p_type text, p_organization_id uuid, p_record_id uuid, p_cap bigint\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"agent_context_value_cap\", args: \"p_organization_id uuid\", returns: \"bigint\", security: \"invoker\" },\n { name: \"agent_table_claim\", args: \"p_organization uuid, p_table uuid, p_conversation uuid DEFAULT NULL::uuid\", returns: \"void\", security: \"definer\" },\n { name: \"agg_assert_key\", args: \"p_key text\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_bucket_ordinal\", args: \"p_by text, p_window_from timestamp without time zone, p_at timestamp without time zone, p_week_start text\", returns: \"integer\", security: \"invoker\" },\n { name: \"agg_buckets\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"agg_cadence_normalize\", args: \"p_cadence text\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_calendar\", args: \"p_organization_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"agg_compare_kinds\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"agg_compare_windows\", args: \"p_organization_id uuid, p_compare jsonb, p_bucket jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"agg_deliver\", args: \"p_organization_id uuid, p_rule_id uuid, p_record_id uuid, p_channel text, p_recipient_user_id uuid, p_event_key text, p_subject text, p_body text, p_payload jsonb DEFAULT '{}'::jsonb, p_dedupe_suffix text DEFAULT NULL::text\", returns: \"uuid\", security: \"invoker\" },\n { name: \"agg_deliver_quietly\", args: \"p_organization_id uuid, p_rule_id uuid, p_subject_id uuid, p_channel text, p_recipient_user_id uuid, p_event_key text, p_subject text, p_body text, p_payload jsonb, p_quiet_hours jsonb, p_link text, p_dedupe_suffix text DEFAULT NULL::text\", returns: \"uuid\", security: \"invoker\" },\n { name: \"agg_delta\", args: \"p_current jsonb, p_prior jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"agg_digest_assemble\", args: \"p_organization_id uuid, p_rule_id uuid, p_since timestamp with time zone DEFAULT NULL::timestamp with time zone, p_until timestamp with time zone DEFAULT NULL::timestamp with time zone\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"agg_digest_due_at\", args: \"p_cadence text, p_schedule text, p_quiet jsonb, p_after timestamp with time zone\", returns: \"timestamp with time zone\", security: \"invoker\" },\n { name: \"agg_digest_judged_at\", args: \"p_organization_id uuid, p_rule_id uuid\", returns: \"timestamp with time zone\", security: \"invoker\" },\n { name: \"agg_digest_run\", args: \"p_organization_id uuid, p_rule_id uuid DEFAULT NULL::uuid, p_since timestamp with time zone DEFAULT NULL::timestamp with time zone\", returns: \"integer\", security: \"invoker\" },\n { name: \"agg_digest_run_at\", args: \"p_organization_id uuid, p_rule_id uuid, p_since timestamp with time zone, p_now timestamp with time zone\", returns: \"integer\", security: \"invoker\" },\n { name: \"agg_digest_tick\", args: \"\", returns: \"integer\", security: \"invoker\" },\n { name: \"agg_digest_tick_at\", args: \"p_now timestamp with time zone, p_organization_id uuid DEFAULT NULL::uuid\", returns: \"integer\", security: \"invoker\" },\n { name: \"agg_explain\", args: \"p_organization_id uuid, p_table_id uuid, p_group_by jsonb DEFAULT '[]'::jsonb, p_measures jsonb DEFAULT '[]'::jsonb, p_bucket jsonb DEFAULT NULL::jsonb, p_filter jsonb DEFAULT '{}'::jsonb, p_required text DEFAULT 'viewer'::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"agg_field_kind\", args: \"p_organization_id uuid, p_table_id uuid, p_key text\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_field_value_sql\", args: \"p_organization_id uuid, p_table_id uuid, p_key text\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_fields_readable_assert\", args: \"p_organization_id uuid, p_table_id uuid, p_keys text[], p_required text DEFAULT 'viewer'::text\", returns: \"void\", security: \"invoker\" },\n { name: \"agg_last_digest_at\", args: \"p_organization_id uuid, p_rule_id uuid\", returns: \"timestamp with time zone\", security: \"invoker\" },\n { name: \"agg_local_label\", args: \"p_local timestamp without time zone, p_tz text\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_moment_sql\", args: \"p_key text, p_tz text\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_operations\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"agg_parse_moment\", args: \"p_raw text, p_tz text, p_what text\", returns: \"timestamp with time zone\", security: \"invoker\" },\n { name: \"agg_period_start\", args: \"p_local timestamp without time zone, p_by text, p_week_start text DEFAULT 'monday'::text\", returns: \"timestamp without time zone\", security: \"invoker\" },\n { name: \"agg_period_step\", args: \"p_by text\", returns: \"interval\", security: \"invoker\" },\n { name: \"agg_quiet_until\", args: \"p_quiet jsonb, p_at timestamp with time zone\", returns: \"timestamp with time zone\", security: \"invoker\" },\n { name: \"agg_record_name\", args: \"p_organization_id uuid, p_record_id uuid, p_state jsonb DEFAULT NULL::jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_sql\", args: \"p_organization_id uuid, p_table_id uuid, p_group_by jsonb DEFAULT '[]'::jsonb, p_measures jsonb DEFAULT '[]'::jsonb, p_bucket jsonb DEFAULT NULL::jsonb, p_filter jsonb DEFAULT '{}'::jsonb, p_limit integer DEFAULT 200, p_required text DEFAULT 'viewer'::text, p_window jsonb DEFAULT NULL::jsonb, p_search text DEFAULT NULL::text, p_time_zone text DEFAULT NULL::text\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_subscription_cadences\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"agg_subscription_fire\", args: \"p_organization_id uuid, p_record_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_changed_field_ids jsonb DEFAULT '[]'::jsonb\", returns: \"integer\", security: \"invoker\" },\n { name: \"agg_subscription_fire_entered\", args: \"p_organization_id uuid, p_record_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_since timestamp with time zone DEFAULT NULL::timestamp with time zone\", returns: \"integer\", security: \"invoker\" },\n { name: \"agg_subscription_tick\", args: \"p_window interval DEFAULT '00:15:00'::interval\", returns: \"integer\", security: \"invoker\" },\n { name: \"agg_subscriptions\", args: \"p_organization_id uuid, p_saved_view_id uuid DEFAULT NULL::uuid, p_cadence text DEFAULT NULL::text\", returns: \"TABLE(rule_id uuid, saved_view_id uuid, table_id uuid, cadence text, schedule text, quiet_hours jsonb, channel text, recipient_user_id uuid, event_key text, name text)\", security: \"invoker\" },\n { name: \"agg_value_sql\", args: \"p_key text\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_value_text\", args: \"p_value jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_view_admits\", args: \"p_organization_id uuid, p_saved_view_id uuid, p_record_id uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"agg_view_admits_state\", args: \"p_definition jsonb, p_state jsonb\", returns: \"boolean\", security: \"invoker\" },\n { name: \"agg_withheld_marker\", args: \"p_organization_id uuid, p_table_id uuid, p_key text, p_required text DEFAULT 'viewer'::text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"agg_zero\", args: \"p_measures jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"anon_capture\", args: \"p_organization_id uuid, p_client_key text, p_table_id uuid, p_payload jsonb, p_device text DEFAULT NULL::text, p_captured_at timestamp with time zone DEFAULT NULL::timestamp with time zone\", returns: \"uuid\", security: \"definer\" },\n { name: \"anon_clear\", args: \"p_organization_id uuid, p_submission_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"anon_inbound_land\", args: \"p_address text, p_secret text, p_payload jsonb, p_raw_payload jsonb DEFAULT '{}'::jsonb, p_client_key text DEFAULT NULL::text\", returns: \"uuid\", security: \"definer\" },\n { name: \"anon_publish\", args: \"p_organization_id uuid, p_form_id uuid, p_published boolean DEFAULT true\", returns: \"timestamp with time zone\", security: \"definer\" },\n { name: \"anon_rate_take\", args: \"p_organization_id uuid, p_form_id uuid, p_bucket text, p_token_id uuid DEFAULT NULL::uuid\", returns: \"integer\", security: \"definer\" },\n { name: \"anon_submissions\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_state text DEFAULT NULL::text, p_limit integer DEFAULT 100, p_offset integer DEFAULT 0\", returns: \"TABLE(id uuid, form_id uuid, inbound_id uuid, table_id uuid, source text, state text, payload jsonb, raw_payload jsonb, client_key text, record_id uuid, remote_origin text, rejection_reason text, created_at timestamp with time zone, cleared_at timestamp with time zone)\", security: \"definer\" },\n { name: \"anon_token_issue\", args: \"p_organization_id uuid, p_mode text, p_allowed_origins jsonb, p_form_id uuid DEFAULT NULL::uuid, p_saved_view_id uuid DEFAULT NULL::uuid, p_record_id uuid DEFAULT NULL::uuid, p_expires_at timestamp with time zone DEFAULT NULL::timestamp with time zone\", returns: \"TABLE(token_id uuid, secret text)\", security: \"definer\" },\n { name: \"anon_token_revoke\", args: \"p_organization_id uuid, p_token_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"anon_token_verify\", args: \"p_secret text, p_origin text, p_required_mode text\", returns: \"TABLE(token_id uuid, organization_id uuid, form_id uuid, saved_view_id uuid, record_id uuid, mode text)\", security: \"definer\" },\n { name: \"anon_write\", args: \"p_secret text, p_origin text, p_payload jsonb, p_client_key text DEFAULT NULL::text, p_raw_payload jsonb DEFAULT '{}'::jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"applicable_fields\", args: \"p_organization_id uuid, p_table_id uuid, p_record_type text DEFAULT NULL::text\", returns: \"SETOF custom.record\", security: \"definer\" },\n { name: \"archive_event_of\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"history.migration_log\", security: \"definer\" },\n { name: \"archived_tables_everywhere\", args: \"p_lane text DEFAULT 'org'::text, p_limit integer DEFAULT 100, p_offset integer DEFAULT 0, p_sort text DEFAULT 'archived_at'::text, p_desc boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"assert_client_may_change\", args: \"p_organization_id uuid, p_subject_id uuid, p_door text, p_required permission_level DEFAULT 'editor'::permission_level, p_subject_word text DEFAULT 'record'::text\", returns: \"void\", security: \"invoker\" },\n { name: \"assert_client_may_open\", args: \"p_organization_id uuid, p_subject_id uuid, p_door text, p_required permission_level DEFAULT 'viewer'::permission_level, p_subject_word text DEFAULT 'record'::text\", returns: \"void\", security: \"invoker\" },\n { name: \"assert_client_may_reach\", args: \"p_organization_id uuid, p_door text\", returns: \"void\", security: \"invoker\" },\n { name: \"assert_columns_are_defined\", args: \"p_organization_id uuid, p_record_id uuid, p_patch jsonb\", returns: \"void\", security: \"definer\" },\n { name: \"assert_entity_door\", args: \"p_organization_id uuid, p_door text\", returns: \"void\", security: \"definer\" },\n { name: \"assert_entity_is_organization_scoped\", args: \"p_token text, p_label text, p_scoped boolean\", returns: \"void\", security: \"invoker\" },\n { name: \"assert_may_know_table\", args: \"p_organization_id uuid, p_table_id uuid, p_door text\", returns: \"void\", security: \"invoker\" },\n { name: \"assert_organization_admin\", args: \"p_organization_id uuid, p_door text, p_what text\", returns: \"void\", security: \"invoker\" },\n { name: \"assert_organization_wall\", args: \"p_kind text, p_organization_id uuid, p_row jsonb\", returns: \"void\", security: \"invoker\" },\n { name: \"assert_scope_door\", args: \"p_organization_id uuid, p_door text\", returns: \"void\", security: \"definer\" },\n { name: \"assert_store_door\", args: \"p_organization_id uuid, p_door text\", returns: \"void\", security: \"invoker\" },\n { name: \"autonumber_backfill\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"barcode_symbologies\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"booking_cancel\", args: \"p_booking_ref text, p_origin text DEFAULT NULL::text\", returns: \"TABLE(booking_ref text, record_id uuid, slot_key text, state text, message text)\", security: \"definer\" },\n { name: \"booking_confirm\", args: \"p_form_id uuid, p_hold_id uuid, p_origin text, p_payload jsonb, p_bucket text, p_honeypot text DEFAULT NULL::text, p_client_key text DEFAULT NULL::text\", returns: \"TABLE(booking_ref text, record_id uuid, submission_id uuid, slot_key text, slot_at timestamp with time zone, state text, message text)\", security: \"definer\" },\n { name: \"booking_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_title text, p_questions jsonb, p_availability jsonb DEFAULT '{}'::jsonb, p_presentation jsonb DEFAULT '{}'::jsonb, p_submission_cap integer DEFAULT NULL::integer, p_quarantine_rule_id uuid DEFAULT NULL::uuid, p_notify_rule_id uuid DEFAULT NULL::uuid, p_form_id uuid DEFAULT NULL::uuid, p_slug text DEFAULT NULL::text, p_home_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"booking_hold\", args: \"p_form_id uuid, p_slot_key text, p_origin text, p_bucket text, p_client_key text DEFAULT NULL::text\", returns: \"TABLE(hold_id uuid, slot_key text, expires_at timestamp with time zone, member_user_id uuid, state text, message text)\", security: \"definer\" },\n { name: \"booking_manage\", args: \"p_booking_ref text, p_days integer DEFAULT NULL::integer\", returns: \"TABLE(booking_ref text, form_id uuid, title text, slot_key text, slot_at timestamp with time zone, status text, slots jsonb, availability jsonb, state text, message text)\", security: \"definer\" },\n { name: \"booking_notify\", args: \"p_organization_id uuid, p_form_id uuid, p_record_id uuid, p_submission_id uuid, p_event text, p_when text\", returns: \"uuid\", security: \"invoker\" },\n { name: \"booking_public\", args: \"p_form_id uuid, p_days integer DEFAULT NULL::integer\", returns: \"TABLE(form_id uuid, organization_id uuid, table_id uuid, title text, presentation jsonb, fields jsonb, honeypot_key text, availability jsonb, slots jsonb, state text, message text)\", security: \"definer\" },\n { name: \"booking_reschedule\", args: \"p_booking_ref text, p_slot_key text, p_origin text, p_bucket text DEFAULT NULL::text\", returns: \"TABLE(booking_ref text, record_id uuid, slot_key text, slot_at timestamp with time zone, state text, message text)\", security: \"definer\" },\n { name: \"bookings\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(form_id uuid, table_id uuid, title text, slug text, published_at timestamp with time zone, closed_at timestamp with time zone, slot_minutes integer, timezone text, slot_table_id uuid, booked bigint, cancelled bigint, upcoming bigint, held bigint, next_at timestamp with time zone, state text)\", security: \"definer\" },\n { name: \"bump_epoch\", args: \"p_entity_type text, p_entity_id uuid, p_organization_id uuid DEFAULT NULL::uuid\", returns: \"bigint\", security: \"definer\" },\n { name: \"cache_lookup\", args: \"p_container_type text, p_container_id uuid, p_item_type text, p_item_id uuid\", returns: \"permission_level\", security: \"definer\" },\n { name: \"caller_role\", args: \"\", returns: \"name\", security: \"invoker\" },\n { name: \"capture_open\", args: \"p_organization_id uuid, p_sheet_id uuid\", returns: \"TABLE(sheet_id uuid, organization_id uuid, table_id uuid, title text, presentation jsonb, fields jsonb, state text, may_capture boolean, message text)\", security: \"definer\" },\n { name: \"capture_publish\", args: \"p_organization_id uuid, p_sheet_id uuid, p_open boolean DEFAULT true\", returns: \"timestamp with time zone\", security: \"definer\" },\n { name: \"capture_sheet_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_title text, p_questions jsonb, p_presentation jsonb DEFAULT '{}'::jsonb, p_sheet_id uuid DEFAULT NULL::uuid, p_notify_rule_id uuid DEFAULT NULL::uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"capture_sheets\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(sheet_id uuid, table_id uuid, title text, slug text, state text, opened_at timestamp with time zone, captures bigint, replays bigint, last_capture_at timestamp with time zone, presentation jsonb)\", security: \"definer\" },\n { name: \"capture_submit\", args: \"p_organization_id uuid, p_sheet_id uuid, p_client_key text, p_payload jsonb, p_files jsonb DEFAULT '[]'::jsonb, p_device text DEFAULT NULL::text, p_captured_at timestamp with time zone DEFAULT NULL::timestamp with time zone, p_location jsonb DEFAULT NULL::jsonb\", returns: \"TABLE(record_id uuid, state text, message text, replay boolean, file_ids uuid[])\", security: \"definer\" },\n { name: \"carry_unchanged_value_stamps\", args: \"p_old jsonb, p_new jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"carrying_edges_in\", args: \"p_organization_id uuid\", returns: \"TABLE(container_type text, container_id uuid, item_type text, item_id uuid, conveys_max permission_level)\", security: \"definer\" },\n { name: \"carrying_edges_of\", args: \"p_item_type text, p_item_id uuid\", returns: \"TABLE(container_type text, container_id uuid, conveys_max permission_level)\", security: \"definer\" },\n { name: \"checklist_declare\", args: \"p_organization_id uuid, p_spec jsonb, p_template_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"checklist_refusal\", args: \"p_spec jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"checklist_run\", args: \"p_organization_id uuid, p_run_id uuid\", returns: \"TABLE(step_id uuid, step_order integer, ref text, title text, role text, assignee_name text, assignee_user_id uuid, due_on timestamp with time zone, due_state text, status text, finished boolean, requires text, requires_key text, requires_label text, requires_id uuid, evidence jsonb, blocked_by text[], may_complete boolean, refusal text)\", security: \"definer\" },\n { name: \"checklist_runs\", args: \"p_organization_id uuid, p_about_table_id uuid DEFAULT NULL::uuid, p_about_record_id uuid DEFAULT NULL::uuid, p_include_closed boolean DEFAULT true, p_limit integer DEFAULT 100\", returns: \"TABLE(run_id uuid, name text, template_id uuid, template text, about_record_id uuid, about text, about_table_id uuid, started_at timestamp with time zone, started_by uuid, origin text, step_count integer, done integer, overdue integer, next_step text, next_due timestamp with time zone, closed_at timestamp with time zone)\", security: \"definer\" },\n { name: \"checklist_start\", args: \"p_organization_id uuid, p_template_id uuid, p_about_record_id uuid DEFAULT NULL::uuid, p_roles jsonb DEFAULT '{}'::jsonb, p_starting_at timestamp with time zone DEFAULT NULL::timestamp with time zone\", returns: \"jsonb\", security: \"definer\" },\n { name: \"checklist_step_complete\", args: \"p_organization_id uuid, p_step_id uuid, p_evidence jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"checklist_step_refusal\", args: \"p_organization_id uuid, p_step_id uuid\", returns: \"text\", security: \"definer\" },\n { name: \"checklist_steps_table\", args: \"p_organization_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"checklist_template_shape\", args: \"p_organization_id uuid, p_template_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"checklist_templates\", args: \"p_organization_id uuid, p_about_table_id uuid DEFAULT NULL::uuid, p_limit integer DEFAULT 100\", returns: \"TABLE(template_id uuid, name text, about_table_id uuid, about_table text, steps integer, roles integer, trigger_kind text, trigger_status text, open_runs integer, total_runs integer, updated_at timestamp with time zone)\", security: \"definer\" },\n { name: \"checklist_templates_archived\", args: \"p_organization_id uuid, p_about_table_id uuid DEFAULT NULL::uuid, p_limit integer DEFAULT 100\", returns: \"TABLE(template_id uuid, name text, about_table_id uuid, about_table text, steps integer, archived_at timestamp with time zone, archived_by uuid, table_archived boolean)\", security: \"definer\" },\n { name: \"choice_census\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"choice_field_map\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_filter_normalize\", args: \"p_map jsonb, p_filter jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_key_for\", args: \"p_organization_id uuid, p_options_table_id uuid, p_title text, p_exclude uuid DEFAULT NULL::uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"choice_key_of\", args: \"p_field jsonb, p_token text\", returns: \"text\", security: \"invoker\" },\n { name: \"choice_nudge\", args: \"p_organization_id uuid\", returns: \"text\", security: \"definer\" },\n { name: \"choice_options\", args: \"p_organization_id uuid, p_options_table_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_render\", args: \"p_organization_id uuid, p_table_id uuid, p_doc jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_render_groups\", args: \"p_map jsonb, p_groups jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_render_note\", args: \"p_field jsonb, p_value jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_render_plan\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_render_value\", args: \"p_field jsonb, p_value jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_render_with\", args: \"p_organization_id uuid, p_table_id uuid, p_doc jsonb, p_plan jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_slug\", args: \"p_word text\", returns: \"text\", security: \"invoker\" },\n { name: \"choice_synonyms\", args: \"p_organization_id uuid, p_table_id uuid, p_token text\", returns: \"text[]\", security: \"invoker\" },\n { name: \"choice_synonyms_in\", args: \"p_map jsonb, p_token text\", returns: \"text[]\", security: \"invoker\" },\n { name: \"choice_words\", args: \"p_field jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"client_write_grants\", args: \"\", returns: \"TABLE(role_name text, object_name text, privilege text)\", security: \"invoker\" },\n { name: \"comment_mention_deliver\", args: \"p_organization_id uuid, p_record_id uuid, p_table_id uuid, p_comment_id uuid, p_recipient uuid, p_author_name text, p_record_title text, p_body text\", returns: \"uuid\", security: \"definer\" },\n { name: \"comment_thread\", args: \"p_organization_id uuid, p_record_id uuid, p_include_resolved boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\n { name: \"comment_write\", args: \"p_organization_id uuid, p_record_id uuid, p_body text, p_anchor jsonb DEFAULT '{}'::jsonb, p_parent_comment_id uuid DEFAULT NULL::uuid, p_mentions uuid[] DEFAULT NULL::uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"computed_block\", args: \"p_block jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"computed_provenance\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(field_key text, field_id uuid, value jsonb, rule_id uuid, rule_version integer, computed_at timestamp with time zone)\", security: \"definer\" },\n { name: \"confidential_anchor\", args: \"p_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"confidential_answer\", args: \"p_user uuid, p_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level\", returns: \"boolean\", security: \"definer\" },\n { name: \"confidential_header\", args: \"p_user uuid, p_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"confidential_names\", args: \"p_organization_id uuid, p_value jsonb, p_user uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"containment_chain\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(ancestor_id uuid, depth integer)\", security: \"invoker\" },\n { name: \"containment_depth_ceiling\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"integer\", security: \"invoker\" },\n { name: \"containment_edges\", args: \"p_organization_id uuid\", returns: \"TABLE(parent_id uuid, child_id uuid, via text)\", security: \"invoker\" },\n { name: \"containment_parent\", args: \"p_data jsonb\", returns: \"uuid\", security: \"invoker\" },\n { name: \"context_archived_types\", args: \"p_organization_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_class_for_checkout\", args: \"p_scope_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_compare_facts\", args: \"p_user_id uuid, p_record_ids uuid[], p_item_ids uuid[] DEFAULT NULL::uuid[], p_cells jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_item_archive\", args: \"p_item_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_item_restore\", args: \"p_item_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_item_row_of\", args: \"p_field custom.record\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"context_item_write\", args: \"p_item_id uuid, p_scope_type_id uuid, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_items\", args: \"p_scope_type_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_policy_rank\", args: \"p_policy text\", returns: \"integer\", security: \"invoker\" },\n { name: \"context_resolve\", args: \"p_bindings jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_scope_archive\", args: \"p_scope_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_scope_restore\", args: \"p_scope_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_scope_write\", args: \"p_organization_id uuid, p_scope_id uuid, p_type_id uuid, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_scopes\", args: \"p_scope_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_system_items\", args: \"\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_tags_set\", args: \"p_entity_type text, p_entity_id uuid, p_scope_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_template_define\", args: \"p_organization_id uuid, p_definition jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"context_templates\", args: \"\", returns: \"SETOF jsonb\", security: \"invoker\" },\n { name: \"context_tree\", args: \"p_organization_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_tree_search\", args: \"p_organization_ids uuid[], p_query text, p_limit integer DEFAULT 100\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_tree_type_scopes\", args: \"p_scope_type_id uuid, p_offset integer DEFAULT 0, p_limit integer DEFAULT 200\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_tree_types\", args: \"p_organization_ids uuid[], p_with_counts boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_type_archive\", args: \"p_type_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_type_restore\", args: \"p_type_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_type_write\", args: \"p_organization_id uuid, p_type_id uuid, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_value_write\", args: \"p_payload jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"context_values\", args: \"p_scope_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_writer\", args: \"p_organization_id uuid\", returns: \"text\", security: \"definer\" },\n { name: \"conversation_scope\", args: \"p_organization_id uuid, p_conversation_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"conversation_scope_bind\", args: \"p_organization_id uuid, p_conversation_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"conversation_scope_context\", args: \"p_organization_id uuid, p_conversation_id uuid, p_relations integer DEFAULT 12, p_history integer DEFAULT 15, p_siblings integer DEFAULT 8\", returns: \"jsonb\", security: \"definer\" },\n { name: \"conversation_scope_unbind\", args: \"p_organization_id uuid, p_conversation_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"count_records_archived\", args: \"p_organization_id uuid, p_table_ids uuid[], p_lane text DEFAULT 'org'::text\", returns: \"TABLE(table_id uuid, n integer)\", security: \"definer\" },\n { name: \"cross_organization_links_open\", args: \"p_source_organization_id uuid, p_target_organization_id uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"custom_fields_tables\", args: \"\", returns: \"TABLE(token text, schema_name text, table_name text)\", security: \"invoker\" },\n { name: \"dashboard_block_normalize\", args: \"p_organization_id uuid, p_subject_table_id uuid, p_block jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"dashboard_class\", args: \"\", returns: \"text\", security: \"invoker\" },\n { name: \"dashboard_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_name text, p_blocks jsonb DEFAULT '[]'::jsonb, p_presentation jsonb DEFAULT '{}'::jsonb, p_dashboard_id uuid DEFAULT NULL::uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"dashboard_delete\", args: \"p_organization_id uuid, p_dashboard_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"dashboard_field_keys\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"text[]\", security: \"definer\" },\n { name: \"dashboard_kinds\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"dashboard_moment_sql\", args: \"p_key text\", returns: \"text\", security: \"invoker\" },\n { name: \"dashboard_restore\", args: \"p_organization_id uuid, p_dashboard_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"dashboard_run\", args: \"p_organization_id uuid, p_dashboard_id uuid, p_filter jsonb DEFAULT '{}'::jsonb, p_compare jsonb DEFAULT NULL::jsonb, p_grain text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"dashboard_stuck\", args: \"p_organization_id uuid, p_table_id uuid, p_state_key text, p_days integer DEFAULT 14, p_filter jsonb DEFAULT '{}'::jsonb, p_limit integer DEFAULT 50, p_required text DEFAULT 'viewer'::text\", returns: \"TABLE(record_id uuid, title text, state text, last_changed_at timestamp with time zone, days_unchanged numeric, measured_from text)\", security: \"definer\" },\n { name: \"dashboard_target_field_assert\", args: \"p_organization_id uuid, p_table_id uuid, p_field_key text\", returns: \"void\", security: \"invoker\" },\n { name: \"dashboard_window_sql\", args: \"p_key text, p_window jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"dashboards\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(dashboard_id uuid, table_id uuid, name text, blocks jsonb, presentation jsonb, block_count integer, version integer, created_at timestamp with time zone, updated_at timestamp with time zone)\", security: \"definer\" },\n { name: \"data_home\", args: \"p_organization_id uuid DEFAULT NULL::uuid, p_search text DEFAULT NULL::text, p_include_app_tables boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\n { name: \"data_home_changed_by\", args: \"p_asks jsonb\", returns: \"TABLE(organization_id uuid, id uuid, at timestamp with time zone, who text)\", security: \"definer\" },\n { name: \"data_home_items\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(kind text, organization_id uuid, organization_name text, item_id uuid, table_id uuid, table_name text, item_row jsonb)\", security: \"definer\" },\n { name: \"data_home_tables\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(table_id uuid, table_name text, organization_id uuid, organization_name text, member boolean, visibility text, updated_at timestamp with time zone, mine boolean, shared_with_me boolean, kept_by_the_app boolean, kind text, team boolean, system boolean, created_by uuid)\", security: \"definer\" },\n { name: \"data_home_tables\", args: \"p_organization_id uuid, p_include_app_tables boolean\", returns: \"TABLE(table_id uuid, table_name text, organization_id uuid, organization_name text, member boolean, visibility text, updated_at timestamp with time zone, mine boolean, shared_with_me boolean, kept_by_the_app boolean, kind text, team boolean, system boolean, created_by uuid)\", security: \"invoker\" },\n { name: \"declared_conversation\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"decoration_colors\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"decoration_rule_ops\", args: \"\", returns: \"TABLE(op text, takes_value boolean, label text)\", security: \"invoker\" },\n { name: \"delete_cascade_closure\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"uuid[]\", security: \"invoker\" },\n { name: \"delete_preview\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"delete_rule\", args: \"p_organization_id uuid, p_record_id uuid, p_apply boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"dependency_cycle\", args: \"p_organization_id uuid, p_row custom.record\", returns: \"text[]\", security: \"invoker\" },\n { name: \"dependency_label\", args: \"p_organization_id uuid, p_node text\", returns: \"text\", security: \"invoker\" },\n { name: \"derive_visibility\", args: \"p_container_type text, p_container_id uuid\", returns: \"TABLE(item_type text, item_id uuid, depth integer, max_level permission_level)\", security: \"definer\" },\n { name: \"derived_value\", args: \"p_organization_id uuid, p_record_id uuid, p_field_data jsonb, p_values jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"derived_values\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"derived_values_of\", args: \"v_rec custom.record\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"display_format_ids\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"doc_content_hash\", args: \"p_body text\", returns: \"text\", security: \"invoker\" },\n { name: \"doc_format_value\", args: \"p_field_data jsonb, p_value jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"doc_letterhead\", args: \"p_organization_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"doc_name_token_pattern\", args: \"\", returns: \"text\", security: \"invoker\" },\n { name: \"doc_name_tokens\", args: \"p_body text\", returns: \"TABLE(ordinal integer, raw text)\", security: \"invoker\" },\n { name: \"doc_render_body\", args: \"p_organization_id uuid, p_template_id uuid, p_record_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"doc_render_document\", args: \"p_organization_id uuid, p_template_id uuid, p_record_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"doc_render_read\", args: \"p_organization_id uuid, p_render_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"doc_render_write\", args: \"p_organization_id uuid, p_template_id uuid, p_record_id uuid, p_table_id uuid, p_template_version integer, p_body text, p_content_hash text\", returns: \"uuid\", security: \"definer\" },\n { name: \"doc_renders\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(render_id uuid, template_id uuid, record_id uuid, table_id uuid, template_version integer, body text, content_hash text, rendered_at timestamp with time zone)\", security: \"definer\" },\n { name: \"doc_sign\", args: \"p_organization_id uuid, p_render_id uuid, p_field_key text, p_signer_name text, p_signer_user_id uuid DEFAULT NULL::uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"doc_signature_field_ok\", args: \"p_field_data jsonb\", returns: \"boolean\", security: \"invoker\" },\n { name: \"doc_signature_intact\", args: \"p_organization_id uuid, p_signature_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"doc_signature_read\", args: \"p_organization_id uuid, p_signature_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"doc_signature_write\", args: \"p_organization_id uuid, p_render_id uuid, p_record_id uuid, p_field_key text, p_signer_name text, p_signer_user_id uuid, p_document_hash text, p_document_version integer\", returns: \"uuid\", security: \"definer\" },\n { name: \"doc_signatures\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(signature_id uuid, render_id uuid, record_id uuid, field_key text, signer_name text, signer_user_id uuid, signed_at timestamp with time zone, document_hash text, document_version integer)\", security: \"definer\" },\n { name: \"doc_template_delete\", args: \"p_organization_id uuid, p_template_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"doc_template_read\", args: \"p_organization_id uuid, p_template_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"doc_template_restore\", args: \"p_organization_id uuid, p_template_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"doc_template_save\", args: \"p_organization_id uuid, p_table_id uuid, p_name text, p_body text, p_template_id uuid DEFAULT NULL::uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"doc_templates\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(template_id uuid, renders_table_id uuid, name text, body text, template_version integer, token_count bigint, updated_at timestamp with time zone)\", security: \"definer\" },\n { name: \"doc_token_pattern\", args: \"\", returns: \"text\", security: \"invoker\" },\n { name: \"doc_tokens\", args: \"p_body text\", returns: \"TABLE(ordinal integer, raw text, field_id uuid)\", security: \"invoker\" },\n { name: \"doc_unresolved_tokens\", args: \"p_organization_id uuid, p_table_id uuid, p_body text\", returns: \"TABLE(raw text, field_id uuid, why text)\", security: \"invoker\" },\n { name: \"doors_not_deciding_the_caller\", args: \"\", returns: \"TABLE(function_name text, identity_args text)\", security: \"invoker\" },\n { name: \"doors_not_deciding_the_record\", args: \"\", returns: \"TABLE(function_name text, identity_args text, why text)\", security: \"invoker\" },\n { name: \"doors_not_masking_fields\", args: \"\", returns: \"TABLE(function_name text, identity_args text, why text)\", security: \"invoker\" },\n { name: \"doors_not_on_one_ladder\", args: \"\", returns: \"TABLE(function_name text, identity_args text, why text)\", security: \"invoker\" },\n { name: \"doors_refusing_in_another_doors_name\", args: \"\", returns: \"TABLE(function_name text, identity_args text, why text)\", security: \"invoker\" },\n { name: \"drill_resolve\", args: \"p_organization_id uuid, p_table_id uuid, p_group_by jsonb, p_measures jsonb, p_bucket jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"effective_level\", args: \"p_user_id uuid, p_organization_id uuid, p_id uuid, p_type text DEFAULT 'record'::text\", returns: \"permission_level\", security: \"definer\" },\n { name: \"enrich_cells\", args: \"p_organization_id uuid, p_table_id uuid, p_field_keys text[] DEFAULT NULL::text[], p_record_ids uuid[] DEFAULT NULL::uuid[]\", returns: \"TABLE(record_id uuid, field_key text, agent_owned boolean, value jsonb, value_version integer, actor text, on_behalf_of text, written_at timestamp with time zone, source jsonb, absent_reason text, alternates jsonb, pinned boolean, stale boolean, due_at timestamp with time zone)\", security: \"definer\" },\n { name: \"enrich_declare\", args: \"p_organization_id uuid, p_field_id uuid, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"enrich_due\", args: \"p_organization_id uuid, p_field_id uuid, p_limit integer DEFAULT 50, p_include_fresh boolean DEFAULT false, p_record_ids uuid[] DEFAULT NULL::uuid[]\", returns: \"TABLE(record_id uuid, title text, inputs jsonb, current_value jsonb, written_at timestamp with time zone, reason text, trimmed_to integer)\", security: \"definer\" },\n { name: \"enrich_land\", args: \"p_organization_id uuid, p_field_id uuid, p_results jsonb, p_run jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"enrich_normalize\", args: \"p_organization_id uuid, p_table_id uuid, p_field_key text, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"enrich_pin\", args: \"p_organization_id uuid, p_record_id uuid, p_field_key text, p_pinned boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"enrich_run_class\", args: \"\", returns: \"text\", security: \"invoker\" },\n { name: \"enrich_runs\", args: \"p_organization_id uuid, p_field_id uuid DEFAULT NULL::uuid, p_limit integer DEFAULT 50\", returns: \"TABLE(run_id uuid, field_id uuid, field_key text, model text, trigger_word text, rows_seen integer, rows_written integer, rows_absent integer, rows_below_floor integer, rows_pinned integer, rows_refused integer, cost_cents numeric, cost_per_row_cents numeric, ran_at timestamp with time zone)\", security: \"definer\" },\n { name: \"enrich_sensitivity_rank\", args: \"p_word text\", returns: \"integer\", security: \"invoker\" },\n { name: \"enrich_triggers\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"enrichments\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(field_id uuid, table_id uuid, field_key text, label text, enrichment jsonb, enabled boolean, review_interval_days integer, rows_total integer, rows_filled integer, rows_stale integer, rows_pinned integer, rows_absent integer, runs integer, cost_cents numeric, cost_per_row_cents numeric, last_run_at timestamp with time zone, last_run jsonb)\", security: \"definer\" },\n { name: \"entity_field_declare\", args: \"p_organization_id uuid, p_token text, p_spec jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"entity_field_protect_arman_explicitly_approved\", args: \"p_field_id uuid, p_readers jsonb, p_arman_words text, p_approved_on date\", returns: \"jsonb\", security: \"definer\" },\n { name: \"entity_field_retire\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"entity_field_rights\", args: \"p_organization_id uuid, p_token text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"entity_field_update\", args: \"p_organization_id uuid, p_field_id uuid, p_patch jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"entity_fields\", args: \"p_organization_id uuid, p_token text\", returns: \"SETOF custom.record\", security: \"definer\" },\n { name: \"entity_fields_across\", args: \"p_token text, p_organization_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"entity_read_mask\", args: \"p_organization_id uuid, p_token text, p_level permission_level, p_action text DEFAULT 'read'::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"entity_record_home\", args: \"p_token text, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_record_read\", args: \"p_organization_id uuid, p_token text, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_records_find\", args: \"p_organization_id uuid, p_token text, p_key text, p_value jsonb DEFAULT NULL::jsonb, p_limit integer DEFAULT 50, p_offset integer DEFAULT 0\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_reference_fields\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_reference_kinds\", args: \"\", returns: \"TABLE(token text, label text, category text)\", security: \"definer\" },\n { name: \"entity_reference_render\", args: \"p_organization_id uuid, p_table_id uuid, p_doc jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_reference_render_with\", args: \"p_organization_id uuid, p_table_id uuid, p_doc jsonb, p_fields jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_reference_rows\", args: \"p_organization_id uuid, p_token text, p_ids uuid[]\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_reference_search\", args: \"p_organization_id uuid, p_tokens text[], p_search text DEFAULT NULL::text, p_limit integer DEFAULT 20\", returns: \"jsonb\", security: \"definer\" },\n { name: \"entity_reference_target\", args: \"p_token text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"entity_reference_words\", args: \"p_organization_id uuid, p_refs jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"entity_row_propose\", args: \"p_organization_id uuid, p_token text, p_record_id uuid, p_columns jsonb DEFAULT '{}'::jsonb, p_custom jsonb DEFAULT '{}'::jsonb, p_expected_version integer DEFAULT NULL::integer, p_archive boolean DEFAULT NULL::boolean, p_note text DEFAULT NULL::text, p_conversation_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_row_write\", args: \"p_organization_id uuid, p_token text, p_record_id uuid, p_columns jsonb DEFAULT '{}'::jsonb, p_custom jsonb DEFAULT '{}'::jsonb, p_expected_version integer DEFAULT NULL::integer, p_archive boolean DEFAULT NULL::boolean\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_seat_level\", args: \"p_organization_id uuid, p_token text, p_record_id uuid\", returns: \"permission_level\", security: \"invoker\" },\n { name: \"entity_table\", args: \"p_token text\", returns: \"TABLE(token text, schema_name text, table_name text, type text, title_column text, label text, has_organization boolean, has_deleted_at boolean)\", security: \"definer\" },\n { name: \"entity_value_write\", args: \"p_organization_id uuid, p_token text, p_record_id uuid, p_patch jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"export_ceiling\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"integer\", security: \"invoker\" },\n { name: \"export_records\", args: \"p_organization_id uuid, p_table_id uuid, p_limit integer DEFAULT 1000\", returns: \"TABLE(id uuid, document jsonb)\", security: \"invoker\" },\n { name: \"external_foreign_table_findings\", args: \"\", returns: \"SETOF text\", security: \"definer\" },\n { name: \"external_history_event\", args: \"p_organization_id uuid, p_link_id uuid, p_operation text\", returns: \"bigint\", security: \"definer\" },\n { name: \"external_rows\", args: \"p_organization_id uuid, p_source_id uuid\", returns: \"SETOF jsonb\", security: \"definer\" },\n { name: \"external_source_declare\", args: \"p_organization_id uuid, p_tier text, p_connection_token text, p_external_schema text, p_external_table text, p_link_template text\", returns: \"uuid\", security: \"definer\" },\n { name: \"external_stub_upsert\", args: \"p_organization_id uuid, p_source_id uuid, p_table_id uuid, p_external_key text, p_link_url text, p_cached_title text\", returns: \"uuid\", security: \"definer\" },\n { name: \"external_tier_contract\", args: \"\", returns: \"jsonb\", security: \"definer\" },\n { name: \"external_write_through\", args: \"p_organization_id uuid, p_record_id uuid, p_patch jsonb\", returns: \"void\", security: \"definer\" },\n { name: \"external_writes_set\", args: \"p_organization_id uuid, p_source_id uuid, p_enabled boolean\", returns: \"boolean\", security: \"definer\" },\n { name: \"far_value\", args: \"p_organization_id uuid, p_record_id uuid, p_key text, p_reader jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"field_access\", args: \"p_user uuid, p_field_id uuid, p_token text, p_row_id uuid, p_action text, p_audit boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"field_add_rung\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"permission_level\", security: \"invoker\" },\n { name: \"field_behaviour\", args: \"p_field_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"field_choice_usage\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"field_context_policy_floor\", args: \"p_organization_id uuid, p_field_data jsonb, p_self uuid DEFAULT NULL::uuid\", returns: \"TABLE(context_policy text, reads jsonb)\", security: \"definer\" },\n { name: \"field_cycle\", args: \"p_organization_id uuid, p_field_data jsonb, p_self uuid\", returns: \"text[]\", security: \"definer\" },\n { name: \"field_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_spec jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"field_dependants\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"TABLE(kind text, dependant_id uuid, label text, how text)\", security: \"definer\" },\n { name: \"field_history\", args: \"p_organization_id uuid, p_table_id uuid, p_field_key text, p_limit integer DEFAULT 100, p_offset integer DEFAULT 0, p_record_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(record_id uuid, record_title text, version integer, occurred_at timestamp with time zone, operation_label text, actor jsonb, before jsonb, after jsonb)\", security: \"definer\" },\n { name: \"field_input_closure\", args: \"p_organization_id uuid, p_field_data jsonb, p_self uuid DEFAULT NULL::uuid\", returns: \"TABLE(input_id uuid, input_key text, input_label text, input_table uuid, sensitivity text, retired boolean, depth integer)\", security: \"definer\" },\n { name: \"field_inputs_of\", args: \"p_organization_id uuid, p_field_data jsonb\", returns: \"TABLE(input_id uuid, input_key text, input_label text, input_table uuid, sensitivity text, retired boolean, how text)\", security: \"definer\" },\n { name: \"field_is_protected\", args: \"p_data jsonb\", returns: \"boolean\", security: \"invoker\" },\n { name: \"field_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"field_kind_of\", args: \"p_field_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"field_kinds\", args: \"\", returns: \"TABLE(kind text, behavior text, parity boolean, made_of text)\", security: \"invoker\" },\n { name: \"field_options\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"SETOF custom.record\", security: \"definer\" },\n { name: \"field_protection_refusal\", args: \"p_op text, p_old jsonb, p_new jsonb, p_field_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"field_restore\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"field_retire\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"field_rules\", args: \"p_field_data jsonb\", returns: \"TABLE(kind text, spec jsonb)\", security: \"invoker\" },\n { name: \"field_sensitivity_floor\", args: \"p_organization_id uuid, p_field_data jsonb, p_self uuid DEFAULT NULL::uuid\", returns: \"TABLE(sensitivity text, reads jsonb)\", security: \"definer\" },\n { name: \"field_source_archived\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"field_update\", args: \"p_organization_id uuid, p_field_id uuid, p_patch jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"field_update_rehoming_choices\", args: \"p_organization_id uuid, p_field_id uuid, p_patch jsonb, p_rehome jsonb DEFAULT NULL::jsonb, p_cells_back jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"field_value_convert\", args: \"p_to jsonb, p_value jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"field_value_kind\", args: \"p_organization_id uuid, p_field_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"field_words\", args: \"p_organization_id uuid, p_field_id uuid, p_value jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"file_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"filter_is_rule\", args: \"p_filter jsonb\", returns: \"boolean\", security: \"invoker\" },\n { name: \"form_archive\", args: \"p_organization_id uuid, p_form_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"form_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_title text, p_questions jsonb, p_presentation jsonb DEFAULT '{}'::jsonb, p_submission_cap integer DEFAULT NULL::integer, p_quarantine_rule_id uuid DEFAULT NULL::uuid, p_notify_rule_id uuid DEFAULT NULL::uuid, p_form_id uuid DEFAULT NULL::uuid, p_slug text DEFAULT NULL::text\", returns: \"uuid\", security: \"definer\" },\n { name: \"form_draft_read\", args: \"p_form_id uuid, p_secret text\", returns: \"TABLE(answers jsonb, saved_at timestamp with time zone, expires_at timestamp with time zone, state text, message text)\", security: \"definer\" },\n { name: \"form_draft_save\", args: \"p_form_id uuid, p_answers jsonb, p_secret text DEFAULT NULL::text, p_bucket text DEFAULT NULL::text, p_origin text DEFAULT NULL::text\", returns: \"TABLE(draft_secret text, saved_at timestamp with time zone, expires_at timestamp with time zone, state text, message text)\", security: \"definer\" },\n { name: \"form_look_options\", args: \"p_organization_id uuid, p_presentation jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"form_notify\", args: \"p_organization_id uuid, p_form_id uuid, p_record_id uuid, p_submission_id uuid\", returns: \"uuid\", security: \"invoker\" },\n { name: \"form_preview_asks\", args: \"p_organization_id uuid, p_table_id uuid, p_questions jsonb, p_values jsonb\", returns: \"TABLE(field_key text, asked boolean, decided boolean, said text)\", security: \"definer\" },\n { name: \"form_public\", args: \"p_form_id uuid\", returns: \"TABLE(form_id uuid, organization_id uuid, table_id uuid, title text, presentation jsonb, fields jsonb, honeypot_key text, state text, message text)\", security: \"definer\" },\n { name: \"form_public_asks\", args: \"p_form_id uuid, p_values jsonb, p_secret text DEFAULT NULL::text, p_origin text DEFAULT NULL::text\", returns: \"TABLE(field_key text, asked boolean, decided boolean, said text)\", security: \"definer\" },\n { name: \"form_redirect_domains\", args: \"p_organization_id uuid\", returns: \"text[]\", security: \"invoker\" },\n { name: \"form_redirect_refusal\", args: \"p_organization_id uuid, p_url text\", returns: \"text\", security: \"invoker\" },\n { name: \"form_restore\", args: \"p_organization_id uuid, p_form_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"form_slug\", args: \"p_organization_id uuid, p_title text, p_form_id uuid DEFAULT NULL::uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"form_submit\", args: \"p_form_id uuid, p_origin text, p_payload jsonb, p_bucket text, p_honeypot text DEFAULT NULL::text, p_client_key text DEFAULT NULL::text\", returns: \"TABLE(submission_id uuid, record_id uuid, state text, message text)\", security: \"definer\" },\n { name: \"forms\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(form_id uuid, table_id uuid, title text, slug text, published_at timestamp with time zone, closed_at timestamp with time zone, submission_cap integer, responses bigint, in_table bigint, held bigint, rejected bigint, state text, quarantine_rule_id uuid, notify_rule_id uuid, presentation jsonb)\", security: \"definer\" },\n { name: \"forms_archived\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_limit integer DEFAULT 100\", returns: \"TABLE(form_id uuid, table_id uuid, table_name text, kind text, title text, slug text, archived_at timestamp with time zone, archived_by uuid, table_archived boolean, can_restore boolean)\", security: \"definer\" },\n { name: \"formula_compile_sql\", args: \"p_organization_id uuid, p_expr jsonb, p_values_sql text\", returns: \"text\", security: \"invoker\" },\n { name: \"formula_eval\", args: \"p_organization_id uuid, p_expr jsonb, p_values jsonb, p_context jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"formula_field_keys\", args: \"p_organization_id uuid, p_expr jsonb\", returns: \"text[]\", security: \"invoker\" },\n { name: \"formula_node_kinds\", args: \"\", returns: \"TABLE(node text, min_args integer, max_args integer, result text, signature text, says text)\", security: \"invoker\" },\n { name: \"formula_parse\", args: \"p_organization_id uuid, p_table_id uuid, p_text text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"formula_result_kind\", args: \"p_organization_id uuid, p_expr jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"formula_value\", args: \"p_organization_id uuid, p_record_id uuid, p_field_data jsonb, p_values jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"freshness_verdict\", args: \"p_written_at timestamp with time zone, p_ceiling_seconds numeric\", returns: \"jsonb\", security: \"definer\" },\n { name: \"grid_layout\", args: \"p_organization_id uuid, p_table_id uuid, p_view_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"grid_layout_check\", args: \"p_layout jsonb, p_scope text DEFAULT 'view'::text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"guard_refusals_are_complete\", args: \"\", returns: \"TABLE(guard text, said text)\", security: \"invoker\" },\n { name: \"has_visibility\", args: \"p_user_id uuid, p_type text, p_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level\", returns: \"boolean\", security: \"definer\" },\n { name: \"has_visibility_at\", args: \"p_user_id uuid, p_type text, p_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level, p_organization_id uuid DEFAULT NULL::uuid, p_min_version bigint DEFAULT NULL::bigint\", returns: \"boolean\", security: \"definer\" },\n { name: \"hidden_field_notice\", args: \"p_field custom.record, p_action text DEFAULT 'read'::text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"history_actor\", args: \"p_tier text, p_document jsonb, p_actor_id uuid, p_people jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"history_changes\", args: \"p_organization_id uuid, p_table_id uuid, p_old jsonb, p_new jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"history_people\", args: \"p_organization_id uuid, p_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"history_prune\", args: \"p_organization_id uuid, p_scope text DEFAULT 'values'::text, p_table_id uuid DEFAULT NULL::uuid, p_dry_run boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"history_restore_body\", args: \"p_current jsonb, p_target jsonb, p_field_key text DEFAULT NULL::text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"history_restore_body\", args: \"p_current jsonb, p_target jsonb, p_field_key text, p_author jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"history_retention\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"history_retention_floor_raise\", args: \"p_organization_id uuid, p_days integer\", returns: \"integer\", security: \"definer\" },\n { name: \"history_retention_set\", args: \"p_organization_id uuid, p_table_id uuid, p_days integer\", returns: \"integer\", security: \"definer\" },\n { name: \"home_add\", args: \"p_organization_id uuid, p_table_id uuid, p_home_record_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"home_relations\", args: \"\", returns: \"TABLE(table_id uuid, home_record_id uuid, organization_id uuid, relation_id uuid)\", security: \"invoker\" },\n { name: \"hub_changed_by\", args: \"p_organization_id uuid, p_kind text, p_ids uuid[]\", returns: \"TABLE(id uuid, at timestamp with time zone, who text)\", security: \"definer\" },\n { name: \"inbound_addresses\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"inbound_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_label text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"inbound_domain\", args: \"p_organization_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"inbound_mail_land\", args: \"p_address text, p_mail jsonb, p_secret text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"inbound_mail_map\", args: \"p_organization_id uuid, p_table_id uuid, p_mail jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"inbound_set\", args: \"p_organization_id uuid, p_inbound_id uuid, p_enabled boolean\", returns: \"jsonb\", security: \"definer\" },\n { name: \"inbox_clear\", args: \"p_organization_id uuid, p_item_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"inbox_counts\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(organization_id uuid, organization_name text, waiting integer, snoozed integer, cleared integer, overdue integer, oldest_waiting_at timestamp with time zone)\", security: \"definer\" },\n { name: \"inbox_remind_tick\", args: \"\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"inbox_snooze\", args: \"p_organization_id uuid, p_item_id uuid, p_until timestamp with time zone\", returns: \"jsonb\", security: \"definer\" },\n { name: \"inbox_unclear\", args: \"p_organization_id uuid, p_item_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"inbox_unsnooze\", args: \"p_organization_id uuid, p_item_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"index_payload\", args: \"p_organization_id uuid, p_table_id uuid, p_limit integer DEFAULT 1000\", returns: \"TABLE(id uuid, searchable text)\", security: \"invoker\" },\n { name: \"intern_provenance\", args: \"p_data jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"io_cell\", args: \"p_organization_id uuid, p_field jsonb, p_word text, p_date_order text DEFAULT 'mdy'::text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"io_change_actor\", args: \"\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"io_change_fields\", args: \"p_keys text[], p_old jsonb, p_new jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"io_change_via\", args: \"\", returns: \"text\", security: \"invoker\" },\n { name: \"io_changed_field_ids\", args: \"p_organization_id uuid, p_table_id uuid, p_old jsonb, p_new jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"io_changed_keys\", args: \"p_old jsonb, p_new jsonb\", returns: \"text[]\", security: \"invoker\" },\n { name: \"io_comment_resolve\", args: \"p_organization_id uuid, p_comment_id uuid, p_resolved boolean DEFAULT true\", returns: \"boolean\", security: \"definer\" },\n { name: \"io_comment_write\", args: \"p_organization_id uuid, p_record_id uuid, p_body text, p_anchor jsonb DEFAULT '{}'::jsonb, p_parent_comment_id uuid DEFAULT NULL::uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"io_comments\", args: \"p_organization_id uuid, p_record_id uuid, p_include_resolved boolean DEFAULT false\", returns: \"TABLE(id uuid, body text, anchor jsonb, parent_comment_id uuid, created_by uuid, created_at timestamp with time zone, resolved_at timestamp with time zone, resolved_by uuid)\", security: \"definer\" },\n { name: \"io_csv_escape\", args: \"p_value text, p_delimiter text DEFAULT ','::text\", returns: \"text\", security: \"invoker\" },\n { name: \"io_csv_parse\", args: \"p_text text, p_delimiter text DEFAULT NULL::text\", returns: \"TABLE(row_number integer, cells text[])\", security: \"invoker\" },\n { name: \"io_export\", args: \"p_organization_id uuid, p_table_id uuid, p_columns text[] DEFAULT NULL::text[], p_limit integer DEFAULT 10000, p_required text DEFAULT 'viewer'::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_export_csv\", args: \"p_organization_id uuid, p_table_id uuid, p_columns text[] DEFAULT NULL::text[], p_limit integer DEFAULT 10000, p_delimiter text DEFAULT chr(44), p_required text DEFAULT 'viewer'::text\", returns: \"text\", security: \"definer\" },\n { name: \"io_import_begin\", args: \"p_organization_id uuid, p_table_id uuid, p_format text DEFAULT 'csv'::text, p_source_name text DEFAULT NULL::text, p_source_columns jsonb DEFAULT '[]'::jsonb, p_file_hash text DEFAULT NULL::text, p_policy jsonb DEFAULT '{}'::jsonb, p_dedupe_key text DEFAULT NULL::text, p_file_bytes bigint DEFAULT NULL::bigint, p_force boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_import_declare_columns\", args: \"p_organization_id uuid, p_table_id uuid, p_rows jsonb, p_mapping jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_import_finish\", args: \"p_organization_id uuid, p_import_id uuid, p_unmapped text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_import_forget\", args: \"p_organization_id uuid, p_import_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"io_import_open\", args: \"p_organization_id uuid, p_table_id uuid, p_format text DEFAULT 'csv'::text, p_source_name text DEFAULT NULL::text, p_source_columns jsonb DEFAULT '[]'::jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"io_import_plan\", args: \"p_organization_id uuid, p_table_id uuid, p_columns jsonb DEFAULT '[]'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_import_report\", args: \"p_organization_id uuid, p_import_id uuid, p_state text DEFAULT NULL::text, p_limit integer DEFAULT 100, p_offset integer DEFAULT 0\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_import_rows\", args: \"p_organization_id uuid, p_import_id uuid, p_rows jsonb, p_mapping jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_imports\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_limit integer DEFAULT 25\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_infer_column\", args: \"p_organization_id uuid, p_table_id uuid, p_header text, p_samples jsonb DEFAULT '[]'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_infer_type\", args: \"p_samples jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"io_money_unit\", args: \"p_word text\", returns: \"text\", security: \"invoker\" },\n { name: \"io_outbox_announce\", args: \"\", returns: \"trigger\", security: \"definer\" },\n { name: \"io_outbox_backlog\", args: \"p_consumer text, p_event_key text, p_older_than interval DEFAULT '00:00:00'::interval\", returns: \"TABLE(organization_id uuid, waiting bigint, oldest timestamp with time zone, last_carried timestamp with time zone)\", security: \"definer\" },\n { name: \"io_outbox_broadcast_stmt\", args: \"\", returns: \"trigger\", security: \"definer\" },\n { name: \"io_outbox_consumed_by\", args: \"p_event_id uuid, p_consumer text, p_consumed_at timestamp with time zone\", returns: \"boolean\", security: \"invoker\" },\n { name: \"io_outbox_drain\", args: \"p_organization_id uuid, p_consumer text, p_limit integer DEFAULT 100, p_event_key text DEFAULT 'records.changed'::text\", returns: \"TABLE(outbox_id uuid, record_id uuid, table_id uuid, operation text, changed_field_ids jsonb, actor jsonb, occurred_at timestamp with time zone)\", security: \"definer\" },\n { name: \"io_outbox_last_consumed\", args: \"p_consumer text, p_event_key text, p_organization_id uuid\", returns: \"timestamp with time zone\", security: \"invoker\" },\n { name: \"io_outbox_pending_organizations\", args: \"p_consumer text, p_event_key text\", returns: \"SETOF uuid\", security: \"definer\" },\n { name: \"io_outbox_per_consumer\", args: \"\", returns: \"boolean\", security: \"invoker\" },\n { name: \"io_outbox_rearm\", args: \"p_organization_id uuid, p_dedupe_key text\", returns: \"void\", security: \"definer\" },\n { name: \"io_outbox_release\", args: \"p_organization_id uuid, p_consumer text, p_older_than interval DEFAULT '00:15:00'::interval\", returns: \"integer\", security: \"definer\" },\n { name: \"io_outbox_release_claimed\", args: \"p_organization_id uuid, p_consumer text, p_ids uuid[]\", returns: \"integer\", security: \"definer\" },\n { name: \"io_outbox_subscribe\", args: \"p_consumer text, p_event_key text\", returns: \"timestamp with time zone\", security: \"definer\" },\n { name: \"io_proposal_accept\", args: \"p_organization_id uuid, p_import_id uuid, p_column text, p_type text DEFAULT NULL::text, p_label text DEFAULT NULL::text\", returns: \"uuid\", security: \"definer\" },\n { name: \"io_proposal_reject\", args: \"p_organization_id uuid, p_import_id uuid, p_column text\", returns: \"boolean\", security: \"definer\" },\n { name: \"io_proposal_spec\", args: \"p_proposal jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"io_record_changed\", args: \"\", returns: \"trigger\", security: \"definer\" },\n { name: \"io_record_changed_stmt_delete\", args: \"\", returns: \"trigger\", security: \"definer\" },\n { name: \"io_record_changed_stmt_insert\", args: \"\", returns: \"trigger\", security: \"definer\" },\n { name: \"io_record_changed_stmt_update\", args: \"\", returns: \"trigger\", security: \"definer\" },\n { name: \"io_relation_candidate\", args: \"p_organization_id uuid, p_table_id uuid, p_words text[]\", returns: \"uuid\", security: \"invoker\" },\n { name: \"io_restore\", args: \"p_organization_id uuid, p_record_id uuid, p_version integer\", returns: \"integer\", security: \"definer\" },\n { name: \"io_restore\", args: \"p_organization_id uuid, p_record_id uuid, p_version integer, p_author jsonb\", returns: \"integer\", security: \"definer\" },\n { name: \"io_revisions\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(version integer, changed_at timestamp with time zone, changed_by uuid, summary text, operation text, changed_fields jsonb)\", security: \"definer\" },\n { name: \"io_sample_words\", args: \"p_samples jsonb\", returns: \"TABLE(word text)\", security: \"invoker\" },\n { name: \"io_value_shape\", args: \"p_envelope jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"io_workflow_chain\", args: \"\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"is_a_retirement\", args: \"p_old_deleted timestamp with time zone, p_new_deleted timestamp with time zone, p_old_data jsonb, p_new_data jsonb, p_old_table uuid, p_new_table uuid, p_old_org uuid, p_new_org uuid, p_old_class text, p_new_class text\", returns: \"boolean\", security: \"invoker\" },\n { name: \"ladder_replanners\", args: \"p_roots text[] DEFAULT ARRAY['custom.has_visibility'::text, 'custom.effective_level'::text, 'custom.reaches_directly'::text, 'custom.visible_set'::text]\", returns: \"TABLE(fn text, lang text, why text, remedy text)\", security: \"definer\" },\n { name: \"level_floor\", args: \"\", returns: \"permission_level\", security: \"definer\" },\n { name: \"levels_of\", args: \"p_user_id uuid, p_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"levels_raised_by_a_less_specific_rung\", args: \"\", returns: \"TABLE(organization_id uuid, organization_name text, member_id uuid, member_email text, record_id uuid, addressed_level permission_level, answered_level permission_level)\", security: \"definer\" },\n { name: \"list_door_disagreements\", args: \"p_pretend text DEFAULT NULL::text, p_only_organization uuid DEFAULT NULL::uuid, p_sample integer DEFAULT 200\", returns: \"TABLE(organization_id uuid, organization_name text, member_id uuid, table_id uuid, record_id uuid, door text, why text)\", security: \"invoker\" },\n { name: \"list_door_disagreements\", args: \"p_pretend text, p_only_organization uuid, p_sample integer, p_exhaustive boolean\", returns: \"TABLE(organization_id uuid, organization_name text, member_id uuid, table_id uuid, record_id uuid, door text, why text)\", security: \"invoker\" },\n { name: \"list_portals\", args: \"p_organization_id uuid, p_archived text DEFAULT 'active'::text\", returns: \"TABLE(portal_id uuid, title text, slug text, client_table_id uuid, client_table text, is_active boolean, tables integer, invited integer, signed_in integer, sign_in_method text, opened_at timestamp with time zone)\", security: \"definer\" },\n { name: \"list_portals_everywhere\", args: \"p_archived text DEFAULT 'active'::text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"listed_predicate_sql\", args: \"p_user uuid, p_organization_id uuid, p_table_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level, p_alias text DEFAULT 'r'::text\", returns: \"text\", security: \"invoker\" },\n { name: \"lookup_value\", args: \"p_organization_id uuid, p_record_id uuid, p_field_data jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"mask_document\", args: \"p_document jsonb, p_visible_keys text[], p_notices jsonb, p_by_id boolean DEFAULT false, p_key_ids jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"mask_document\", args: \"p_document jsonb, p_visible_keys text[], p_notices jsonb, p_by_id boolean DEFAULT false, p_key_ids jsonb DEFAULT '{}'::jsonb, p_declared_keys text[] DEFAULT NULL::text[]\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"mask_history_data\", args: \"p_data jsonb, p_mask jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"mask_says_withheld\", args: \"p_mask jsonb, p_key text\", returns: \"boolean\", security: \"invoker\" },\n { name: \"may_invite_outside\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"member_personal_tables\", args: \"p_organization_id uuid, p_person uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"member_records_take_over\", args: \"p_organization_id uuid, p_from uuid, p_to uuid, p_reason text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"merge_field_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"migrate_choice_keys\", args: \"p_organization_id uuid, p_table_id uuid, p_dry_run boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_delete\", args: \"p_organization_id uuid, p_record_id uuid, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_demote\", args: \"p_organization_id uuid, p_table_id uuid, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_extract_parent\", args: \"p_organization_id uuid, p_id uuid, p_parent_table_id uuid, p_moved_keys text[], p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_merge\", args: \"p_organization_id uuid, p_winner_id uuid, p_loser_id uuid, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_promote\", args: \"p_organization_id uuid, p_table_id uuid, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_purge\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_dry_run boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_purge_hard\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_compliance_reason text DEFAULT NULL::text, p_chunk integer DEFAULT 200, p_dry_run boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_purge_hard_request\", args: \"p_organization_id uuid, p_table_id uuid, p_compliance_reason text\", returns: \"void\", security: \"definer\" },\n { name: \"migrate_reclass\", args: \"p_organization_id uuid, p_id uuid, p_to text DEFAULT 'field'::text, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_rename\", args: \"p_organization_id uuid, p_id uuid, p_to text, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_reparent\", args: \"p_organization_id uuid, p_id uuid, p_parent_id uuid, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_retype\", args: \"p_organization_id uuid, p_id uuid, p_to text, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_split\", args: \"p_organization_id uuid, p_record_id uuid, p_moved_keys text[], p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_undo\", args: \"p_organization_id uuid, p_log_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrations\", args: \"p_organization_id uuid, p_target_id uuid DEFAULT NULL::uuid, p_limit integer DEFAULT 100\", returns: \"TABLE(id uuid, verb text, target_kind text, target_id uuid, note text, applied_at timestamp with time zone, applied_by uuid, undone_at timestamp with time zone)\", security: \"definer\" },\n { name: \"mirror_asks_the_whole_database\", args: \"\", returns: \"TABLE(schema_name text, table_name text, policy_name text, why text)\", security: \"invoker\" },\n { name: \"my_level\", args: \"p_organization_id uuid, p_id uuid, p_type text DEFAULT 'record'::text\", returns: \"permission_level\", security: \"definer\" },\n { name: \"my_levels\", args: \"p_organization_id uuid, p_ids jsonb, p_type text DEFAULT 'record'::text\", returns: \"TABLE(id uuid, level permission_level)\", security: \"definer\" },\n { name: \"organization_clear\", args: \"p_organization_id uuid, p_confirm text, p_and_destroy boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\n { name: \"organization_contents\", args: \"p_organization_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"organization_home_id\", args: \"p_organization_id uuid\", returns: \"uuid\", security: \"invoker\" },\n { name: \"organization_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"organization_pick_lists\", args: \"p_organization_id uuid\", returns: \"TABLE(id uuid, list_name text, description text, updated_at timestamp with time zone, lives_in text)\", security: \"definer\" },\n { name: \"organization_references\", args: \"p_kind text, p_organization_id uuid, p_row jsonb\", returns: \"TABLE(site text, what text, ref_id uuid, openable boolean)\", security: \"invoker\" },\n { name: \"owning_table\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"uuid\", security: \"invoker\" },\n { name: \"owning_table_gone\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"page_ceiling\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"integer\", security: \"invoker\" },\n { name: \"page_contract\", args: \"p_organization_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"page_size\", args: \"p_organization_id uuid, p_door text, p_limit integer, p_default integer DEFAULT NULL::integer, p_ceiling integer DEFAULT NULL::integer\", returns: \"integer\", security: \"invoker\" },\n { name: \"parity_field_types\", args: \"\", returns: \"TABLE(parity_type text, behavior text, made_of text)\", security: \"invoker\" },\n { name: \"parity_type\", args: \"p_field_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"parity_values\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(field_key text, field_id uuid, parity_type text, behavior text, unit text, format text, value jsonb, value_version integer, actor text, written_at timestamp with time zone)\", security: \"invoker\" },\n { name: \"per_value_access_words\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"person_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"phone_canonical\", args: \"p_text text\", returns: \"text\", security: \"invoker\" },\n { name: \"phone_display\", args: \"p_text text\", returns: \"text\", security: \"invoker\" },\n { name: \"phone_pattern\", args: \"\", returns: \"text\", security: \"invoker\" },\n { name: \"pick_list_create\", args: \"p_organization_id uuid, p_list_name text, p_description text DEFAULT NULL::text, p_items jsonb DEFAULT '[]'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pick_list_index\", args: \"p_organization_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pick_list_index_everywhere\", args: \"\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pin_agent_cells\", args: \"p_new jsonb, p_old jsonb, p_agent_keys text[]\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"pipeline_board\", args: \"p_organization_id uuid, p_table_id uuid, p_measure text DEFAULT NULL::text\", returns: \"TABLE(stage_key text, stage_label text, stage_position integer, cards bigint, total numeric, wip_limit integer, over_limit boolean)\", security: \"definer\" },\n { name: \"pipeline_board\", args: \"p_organization_id uuid, p_table_id uuid, p_measure text, p_filter jsonb\", returns: \"TABLE(stage_key text, stage_label text, stage_position integer, cards bigint, total numeric, wip_limit integer, over_limit boolean)\", security: \"definer\" },\n { name: \"pipeline_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pipeline_gate_preview\", args: \"p_organization_id uuid, p_table_id uuid, p_stage text, p_gate jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pipeline_move\", args: \"p_organization_id uuid, p_record_id uuid, p_to text, p_also jsonb DEFAULT '{}'::jsonb, p_expected_version integer DEFAULT NULL::integer\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pipeline_move_many\", args: \"p_organization_id uuid, p_moves jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pipeline_pending\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pipeline_read\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pipeline_transition_refusal\", args: \"p_organization_id uuid, p_record_id uuid, p_to text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pipelines\", args: \"p_organization_id uuid\", returns: \"TABLE(table_id uuid, table_name text, stage_field text, stage_label text, stages integer, rules integer, broken text, updated_at timestamp with time zone, updated_by uuid)\", security: \"definer\" },\n { name: \"plural_of\", args: \"p_word text\", returns: \"text\", security: \"invoker\" },\n { name: \"portal_accents\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"portal_admits\", args: \"p_organization_id uuid, p_user_id uuid DEFAULT NULL::uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"portal_archive\", args: \"p_organization_id uuid, p_portal_id uuid, p_confirm_title text, p_reason text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_card\", args: \"p_organization_id uuid, p_portal_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_declare\", args: \"p_organization_id uuid, p_title text, p_client_table_id uuid, p_tables jsonb, p_portal_id uuid DEFAULT NULL::uuid, p_slug text DEFAULT NULL::text, p_sign_in_method text DEFAULT 'magic_link'::text, p_config jsonb DEFAULT NULL::jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"portal_field_map\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(field_id uuid, field_key text, field_type text, points_at uuid)\", security: \"definer\" },\n { name: \"portal_form\", args: \"p_organization_id uuid, p_portal_id uuid, p_form_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_form_submit\", args: \"p_organization_id uuid, p_portal_id uuid, p_form_id uuid, p_payload jsonb, p_client_key text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_invitation\", args: \"p_slug text, p_email text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_invite\", args: \"p_organization_id uuid, p_portal_id uuid, p_client_record_id uuid, p_email text, p_user_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_invite_accept\", args: \"p_token text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_me\", args: \"\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_preview\", args: \"p_organization_id uuid, p_portal_id uuid, p_principal_id uuid, p_table_id uuid\", returns: \"TABLE(record_id uuid, title text)\", security: \"definer\" },\n { name: \"portal_principal_bind\", args: \"p_organization_id uuid, p_principal_id uuid, p_user_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_public\", args: \"p_slug text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_record_title\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"text\", security: \"definer\" },\n { name: \"portal_restore\", args: \"p_organization_id uuid, p_portal_id uuid, p_confirm_title text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_revoke\", args: \"p_organization_id uuid, p_portal_id uuid, p_principal_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_slug\", args: \"p_organization_id uuid, p_title text, p_portal_id uuid DEFAULT NULL::uuid\", returns: \"text\", security: \"definer\" },\n { name: \"portal_tables\", args: \"p_organization_id uuid\", returns: \"TABLE(portal_id uuid, table_id uuid, name text)\", security: \"definer\" },\n { name: \"portals\", args: \"p_organization_id uuid\", returns: \"TABLE(portal_id uuid, title text, slug text, client_table_id uuid, client_table text, is_active boolean, tables integer, invited integer, signed_in integer, sign_in_method text, opened_at timestamp with time zone)\", security: \"definer\" },\n { name: \"presentation_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"promote_field\", args: \"p_organization_id uuid, p_table_id uuid, p_field_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"promote_table\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"promoted_field_cap\", args: \"\", returns: \"integer\", security: \"invoker\" },\n { name: \"promoted_fields\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(field_id uuid, field_key text, parity_type text, is_unique boolean, value_path text, index_arm text, index_expr text, index_name text, indexable boolean, why_not text)\", security: \"invoker\" },\n { name: \"promoted_index_arm\", args: \"p_field_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"promoted_index_ddl\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(step integer, purpose text, statement text)\", security: \"invoker\" },\n { name: \"promoted_index_expr\", args: \"p_field_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"promoted_index_name\", args: \"p_table_id uuid, p_field_key text, p_unique boolean\", returns: \"text\", security: \"invoker\" },\n { name: \"promoted_query_sql\", args: \"p_organization_id uuid, p_table_id uuid, p_field_key text\", returns: \"text\", security: \"invoker\" },\n { name: \"promoted_read\", args: \"p_organization_id uuid, p_table_id uuid, p_field_key text, p_value text\", returns: \"SETOF uuid\", security: \"invoker\" },\n { name: \"promoted_value_path\", args: \"p_field_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"promotion_inline_ceiling\", args: \"\", returns: \"integer\", security: \"invoker\" },\n { name: \"protected_field_notice\", args: \"p_field custom.record\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"protected_field_query_refusal\", args: \"p_field_id uuid, p_verb text\", returns: \"text\", security: \"definer\" },\n { name: \"protected_field_rule\", args: \"p_token text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"protected_matches\", args: \"p_field_id uuid, p_value jsonb DEFAULT NULL::jsonb\", returns: \"TABLE(row_id uuid, value jsonb)\", security: \"definer\" },\n { name: \"protected_readers_problem\", args: \"p_token text, p_readers jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"protected_value\", args: \"p_token text, p_row_id uuid, p_field_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"protected_value_leaks\", args: \"p_field_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(place text, table_token text, field_key text, row_id uuid, ref text)\", security: \"definer\" },\n { name: \"protected_values\", args: \"p_organization_id uuid, p_token text, p_row_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"provenance_prune\", args: \"p_organization_id uuid DEFAULT NULL::uuid, p_dry_run boolean DEFAULT true, p_limit integer DEFAULT 200000\", returns: \"jsonb\", security: \"definer\" },\n { name: \"provenance_retention_days\", args: \"p_organization_id uuid\", returns: \"integer\", security: \"definer\" },\n { name: \"provenance_write\", args: \"p_organization_id uuid, p_conversation_id uuid, p_turn_id text, p_rows jsonb\", returns: \"integer\", security: \"definer\" },\n { name: \"publish_bind\", args: \"p_organization_id uuid, p_kind text, p_resource_id uuid, p_slug text, p_render_mode text DEFAULT 'page'::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"query_access_ids\", args: \"p_organization_id uuid, p_required text DEFAULT 'viewer'::text\", returns: \"uuid[]\", security: \"invoker\" },\n { name: \"query_across_homes\", args: \"p_organization_id uuid, p_table_id uuid, p_limit integer DEFAULT 50, p_offset integer DEFAULT 0, p_required text DEFAULT 'viewer'::text\", returns: \"TABLE(record_id uuid, home_record_id uuid, data jsonb, created_at timestamp with time zone)\", security: \"definer\" },\n { name: \"query_by_coordinates\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_coordinates jsonb DEFAULT '[]'::jsonb, p_limit integer DEFAULT 50, p_offset integer DEFAULT 0, p_required text DEFAULT 'viewer'::text\", returns: \"TABLE(record_id uuid, table_id uuid, data jsonb, coordinates_matched integer)\", security: \"definer\" },\n { name: \"query_can_see\", args: \"p_organization_id uuid, p_record_id uuid, p_required text DEFAULT 'viewer'::text\", returns: \"boolean\", security: \"definer\" },\n { name: \"query_hot_paths\", args: \"\", returns: \"TABLE(name text, statement text)\", security: \"invoker\" },\n { name: \"query_hot_paths_prepared\", args: \"\", returns: \"TABLE(name text, prepared boolean, generic_plans bigint)\", security: \"invoker\" },\n { name: \"query_is_store_owner\", args: \"\", returns: \"boolean\", security: \"invoker\" },\n { name: \"query_prepare_hot\", args: \"\", returns: \"integer\", security: \"invoker\" },\n { name: \"query_principal\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"query_record_as_of\", args: \"p_organization_id uuid, p_record_id uuid, p_recorded_at timestamp with time zone DEFAULT NULL::timestamp with time zone, p_world_on date DEFAULT NULL::date, p_required text DEFAULT 'viewer'::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"query_record_document\", args: \"p_principal uuid, p_row custom.record\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"query_relation_edges\", args: \"p_organization_id uuid, p_flavor text DEFAULT NULL::text, p_role text DEFAULT NULL::text\", returns: \"TABLE(parent_id uuid, child_id uuid, role text, flavor text)\", security: \"definer\" },\n { name: \"query_rollup\", args: \"p_organization_id uuid, p_roots uuid[], p_flavor text DEFAULT NULL::text, p_role text DEFAULT NULL::text, p_max_depth integer DEFAULT 33, p_required text DEFAULT 'viewer'::text\", returns: \"TABLE(record_id uuid, depth integer)\", security: \"definer\" },\n { name: \"query_rollup_sum\", args: \"p_organization_id uuid, p_roots uuid[], p_field_key text, p_flavor text DEFAULT NULL::text, p_role text DEFAULT NULL::text, p_max_depth integer DEFAULT 33, p_required text DEFAULT 'viewer'::text\", returns: \"numeric\", security: \"definer\" },\n { name: \"query_table_as_of\", args: \"p_organization_id uuid, p_table_id uuid, p_recorded_at timestamp with time zone DEFAULT NULL::timestamp with time zone, p_world_on date DEFAULT NULL::date, p_limit integer DEFAULT 50, p_offset integer DEFAULT 0, p_required text DEFAULT 'viewer'::text\", returns: \"TABLE(record_id uuid, data jsonb)\", security: \"definer\" },\n { name: \"query_table_homes\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"SETOF uuid\", security: \"definer\" },\n { name: \"query_visibility_parity\", args: \"p_organization_id uuid\", returns: \"TABLE(side text, container_type text, container_id uuid, item_type text, item_id uuid, stored_level permission_level, derived_level permission_level, reason text)\", security: \"definer\" },\n { name: \"query_visible_ids\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_required text DEFAULT 'viewer'::text\", returns: \"SETOF uuid\", security: \"definer\" },\n { name: \"reachable_from\", args: \"p_organization_id uuid, p_roots uuid[]\", returns: \"TABLE(record_id uuid, depth integer, via text)\", security: \"invoker\" },\n { name: \"reaches_directly\", args: \"p_user_id uuid, p_type text, p_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level\", returns: \"boolean\", security: \"definer\" },\n { name: \"read_door_carried_ids\", args: \"p_user uuid, p_organization_id uuid, p_table_id uuid, p_required permission_level, OUT o_ids uuid[], OUT o_containers integer\", returns: \"record\", security: \"definer\" },\n { name: \"read_door_granted_ids\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"uuid[]\", security: \"definer\" },\n { name: \"read_door_ladder_ceiling\", args: \"\", returns: \"integer\", security: \"invoker\" },\n { name: \"read_door_parity\", args: \"p_organization_id uuid, p_table_id uuid, p_user uuid, p_required permission_level, p_sample integer\", returns: \"TABLE(record_id uuid, set_based boolean, per_row boolean, verdict text)\", security: \"definer\" },\n { name: \"read_mask\", args: \"p_organization_id uuid, p_record_id uuid, p_action text DEFAULT 'read'::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"read_mask_at\", args: \"p_record_id uuid, p_level_given boolean, p_level permission_level, p_action text DEFAULT 'read'::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"read_mask_for\", args: \"p_user_id uuid, p_organization_id uuid, p_table_id uuid, p_level permission_level, p_action text DEFAULT 'read'::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"read_paths_outside_the_door\", args: \"\", returns: \"TABLE(object_name text, why text)\", security: \"invoker\" },\n { name: \"read_record\", args: \"p_organization_id uuid, p_record_id uuid, p_by_id boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\n { name: \"read_records\", args: \"p_organization_id uuid, p_table_id uuid, p_by_id boolean DEFAULT false, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0\", returns: \"TABLE(id uuid, document jsonb, level permission_level)\", security: \"definer\" },\n { name: \"read_records_archived\", args: \"p_organization_id uuid, p_table_id uuid, p_lane text DEFAULT 'org'::text, p_by_id boolean DEFAULT false, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0\", returns: \"TABLE(id uuid, document jsonb, level permission_level, archived_at timestamp with time zone, archived_by uuid, archived_by_name text)\", security: \"definer\" },\n { name: \"read_records_by_ids\", args: \"p_organization_id uuid, p_table_id uuid, p_record_ids uuid[], p_by_id boolean DEFAULT false\", returns: \"TABLE(id uuid, document jsonb, level permission_level)\", security: \"definer\" },\n { name: \"read_records_in_view_order\", args: \"p_organization_id uuid, p_view_id uuid, p_by_id boolean DEFAULT false, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0, p_filter jsonb DEFAULT NULL::jsonb\", returns: \"TABLE(id uuid, document jsonb, level permission_level, \\\"position\\\" numeric)\", security: \"definer\" },\n { name: \"read_records_matching\", args: \"p_organization_id uuid, p_table_id uuid, p_filter jsonb DEFAULT '{}'::jsonb, p_by_id boolean DEFAULT false, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0\", returns: \"TABLE(id uuid, document jsonb, level permission_level)\", security: \"definer\" },\n { name: \"read_records_page\", args: \"p_organization_id uuid, p_table_id uuid, p_filter jsonb DEFAULT '{}'::jsonb, p_search text DEFAULT NULL::text, p_sort jsonb DEFAULT '[]'::jsonb, p_view_id uuid DEFAULT NULL::uuid, p_by_id boolean DEFAULT false, p_limit integer DEFAULT 50, p_offset integer DEFAULT 0, p_time_zone text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"realtime_topic_admits\", args: \"p_topic text\", returns: \"boolean\", security: \"definer\" },\n { name: \"record_aggregate\", args: \"p_organization_id uuid, p_table_id uuid, p_group_by jsonb DEFAULT '[]'::jsonb, p_measures jsonb DEFAULT '[]'::jsonb, p_bucket jsonb DEFAULT NULL::jsonb, p_filter jsonb DEFAULT '{}'::jsonb, p_limit integer DEFAULT 200, p_required text DEFAULT 'viewer'::text, p_compare jsonb DEFAULT NULL::jsonb, p_search text DEFAULT NULL::text, p_time_zone text DEFAULT NULL::text\", returns: \"TABLE(groups jsonb, measures jsonb, row_count bigint, prior_groups jsonb, prior_measures jsonb, prior_row_count bigint, delta jsonb, compare jsonb)\", security: \"definer\" },\n { name: \"record_aggregate_as_of\", args: \"p_organization_id uuid, p_table_id uuid, p_recorded_at timestamp with time zone, p_measure text DEFAULT 'count'::text, p_field_key text DEFAULT NULL::text, p_group_by text DEFAULT NULL::text, p_match jsonb DEFAULT '{}'::jsonb\", returns: \"TABLE(bucket text, result numeric, row_count bigint, not_numbers bigint, a_non_number text)\", security: \"definer\" },\n { name: \"record_applicability\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(rule_id uuid, rule_name text, rule_version integer, applies boolean, answer jsonb)\", security: \"invoker\" },\n { name: \"record_archiver\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"record_as_of\", args: \"p_organization_id uuid, p_record_id uuid, p_at timestamp with time zone\", returns: \"TABLE(state jsonb, replayed boolean)\", security: \"definer\" },\n { name: \"record_card\", args: \"p_viewer uuid, p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_carrying_edges\", args: \"p_id uuid, p_data_class text, p_data jsonb, p_deleted_at timestamp with time zone\", returns: \"TABLE(container_id uuid, item_id uuid, edge_role text)\", security: \"invoker\" },\n { name: \"record_change_actions\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_change_many\", args: \"p_organization_id uuid, p_table_id uuid, p_changes jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_changes_drain\", args: \"p_organization_id uuid, p_consumer text, p_limit integer DEFAULT 100\", returns: \"TABLE(event_id uuid, organization_id uuid, table_id uuid, record_id uuid, kind text, operation text, version integer, fields jsonb, changed_field_ids jsonb, actor jsonb, chain jsonb, op_id uuid, occurred_at timestamp with time zone, via text)\", security: \"definer\" },\n { name: \"record_delete\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"timestamp with time zone\", security: \"definer\" },\n { name: \"record_entity_edges\", args: \"p_organization_id uuid, p_id uuid, p_table_id uuid, p_data_class text, p_data jsonb, p_deleted_at timestamp with time zone\", returns: \"TABLE(target_type text, target_id uuid, edge_role text, field_id uuid, ord integer)\", security: \"invoker\" },\n { name: \"record_filter_sql\", args: \"p_filter jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"record_filter_sql\", args: \"p_organization_id uuid, p_table_id uuid, p_filter jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"record_headers\", args: \"p_organization_id uuid, p_ids uuid[]\", returns: \"TABLE(id uuid, table_id uuid, created_at timestamp with time zone, updated_at timestamp with time zone, version integer, deleted_at timestamp with time zone, mine boolean, created_by uuid)\", security: \"definer\" },\n { name: \"record_history\", args: \"p_organization_id uuid, p_record_id uuid, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0\", returns: \"TABLE(version integer, occurred_at timestamp with time zone, operation text, operation_label text, actor jsonb, changes jsonb, migration_id uuid, undoable boolean)\", security: \"definer\" },\n { name: \"record_platform_keys\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"record_relation_edges\", args: \"p_organization_id uuid, p_id uuid, p_table_id uuid, p_data_class text, p_data jsonb, p_deleted_at timestamp with time zone\", returns: \"TABLE(target_id uuid, edge_role text, field_id uuid, ord integer)\", security: \"invoker\" },\n { name: \"record_reparent\", args: \"p_organization_id uuid, p_record_id uuid, p_parent_id uuid\", returns: \"void\", security: \"definer\" },\n { name: \"record_resolve\", args: \"p_organization_id uuid, p_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_restore\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"void\", security: \"definer\" },\n { name: \"record_restore_preview\", args: \"p_organization_id uuid, p_record_id uuid, p_version integer, p_field_key text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_restore_version\", args: \"p_organization_id uuid, p_record_id uuid, p_version integer\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_restore_version\", args: \"p_organization_id uuid, p_record_id uuid, p_version integer, p_author jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_row_controls\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_row_controls_set\", args: \"p_organization_id uuid, p_record_id uuid, p_controls jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_runs\", args: \"p_organization_id uuid, p_record_id uuid, p_limit integer DEFAULT 50\", returns: \"TABLE(run_id uuid, kind text, name text, trigger_name text, status text, started_at timestamp with time zone, finished_at timestamp with time zone, steps integer, says text, ran_by uuid)\", security: \"definer\" },\n { name: \"record_scope_context\", args: \"p_organization_id uuid, p_record_id uuid, p_relations integer DEFAULT 12, p_history integer DEFAULT 15, p_siblings integer DEFAULT 8\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_search_sql\", args: \"p_organization_id uuid, p_table_id uuid, p_search text, p_alias text DEFAULT 'r'::text, p_time_zone text DEFAULT NULL::text\", returns: \"text\", security: \"invoker\" },\n { name: \"record_source_key\", args: \"p_table_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"record_source_keys\", args: \"p_table_id uuid\", returns: \"text[]\", security: \"invoker\" },\n { name: \"record_source_table\", args: \"p_key text\", returns: \"uuid\", security: \"invoker\" },\n { name: \"record_stage_pending\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_state_as_of\", args: \"p_record_id uuid, p_at timestamp with time zone\", returns: \"TABLE(state jsonb, replayed boolean)\", security: \"definer\" },\n { name: \"record_table\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"record_triggers\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(trigger_id uuid, name text, definition_id uuid, definition_name text, table_id uuid, event text, operations jsonb, field_ids jsonb, via jsonb, is_active boolean, last_fired_at timestamp with time zone, fire_count integer, updated_at timestamp with time zone)\", security: \"definer\" },\n { name: \"record_update\", args: \"p_organization_id uuid, p_record_id uuid, p_patch jsonb, p_expected_version integer DEFAULT NULL::integer\", returns: \"integer\", security: \"definer\" },\n { name: \"record_update_adding_choices\", args: \"p_organization_id uuid, p_record_id uuid, p_patch jsonb, p_add jsonb, p_expected_version integer DEFAULT NULL::integer\", returns: \"integer\", security: \"definer\" },\n { name: \"record_upsert\", args: \"p_organization_id uuid, p_table_id uuid, p_key text[], p_data jsonb, p_expected_version integer DEFAULT NULL::integer\", returns: \"uuid\", security: \"definer\" },\n { name: \"record_value_one\", args: \"p_organization_id uuid, p_record_id uuid, p_key text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"record_values\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"record_values_of\", args: \"p_row custom.record\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"record_values_step\", args: \"p_row custom.record, p_cache jsonb DEFAULT '{}'::jsonb, OUT o_doc jsonb, OUT o_cache jsonb\", returns: \"record\", security: \"invoker\" },\n { name: \"record_values_versioned\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(field_key text, field_id uuid, value jsonb, value_version integer, source jsonb, absent_reason text, actor text, on_behalf_of text, written_at timestamp with time zone, alternates jsonb)\", security: \"definer\" },\n { name: \"record_words\", args: \"p_organization_id uuid, p_record_id uuid, p_noun text DEFAULT NULL::text\", returns: \"text\", security: \"definer\" },\n { name: \"record_write\", args: \"p_organization_id uuid, p_table_id uuid, p_data jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"record_write_graph\", args: \"p_organization_id uuid, p_table_id uuid, p_parent jsonb, p_edges jsonb DEFAULT '[]'::jsonb, p_children jsonb DEFAULT '[]'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_write_graph_superseding\", args: \"p_organization_id uuid, p_table_id uuid, p_lock_key text, p_idempotence jsonb DEFAULT NULL::jsonb, p_parent jsonb DEFAULT NULL::jsonb, p_edges jsonb DEFAULT '[]'::jsonb, p_children jsonb DEFAULT '[]'::jsonb, p_chain jsonb DEFAULT '{\\\"mode\\\": \\\"first\\\"}'::jsonb, p_rows_state jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_write_many\", args: \"p_organization_id uuid, p_table_id uuid, p_rows jsonb[], p_ids uuid[] DEFAULT NULL::uuid[]\", returns: \"uuid[]\", security: \"definer\" },\n { name: \"records_search\", args: \"p_search text, p_limit integer DEFAULT 50, p_offset integer DEFAULT 0, p_table_ids uuid[] DEFAULT NULL::uuid[], p_organization_ids uuid[] DEFAULT NULL::uuid[], p_include_app_tables boolean DEFAULT false\", returns: \"TABLE(record_id uuid, table_id uuid, table_name text, name text, organization_id uuid, updated_at timestamp with time zone)\", security: \"definer\" },\n { name: \"refusals_claiming_a_level_never_asked\", args: \"\", returns: \"TABLE(function_name text, identity_args text, why text)\", security: \"invoker\" },\n { name: \"relation_carry\", args: \"p_organization_id uuid, p_container_id uuid, p_item_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"relation_edges_withdraw\", args: \"p_organization_id uuid, p_field_ids uuid[], p_why text\", returns: \"integer\", security: \"definer\" },\n { name: \"relation_halves_disagreements\", args: \"p_organization_id uuid DEFAULT NULL::uuid, p_record_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(organization_id uuid, record_id uuid, field_key text, field_id uuid, target_id uuid, direction text, remedy text, why text)\", security: \"definer\" },\n { name: \"relation_halves_repair\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"relation_kernel_record\", args: \"p_organization_id uuid, p_kernel_table_id uuid, p_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"relation_name_key\", args: \"p_text text\", returns: \"text\", security: \"invoker\" },\n { name: \"relation_names_match\", args: \"p_organization_id uuid, p_table_id uuid, p_names text[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"relation_own\", args: \"p_organization_id uuid, p_owner_id uuid, p_target_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"relation_restore\", args: \"p_organization_id uuid, p_relation_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"relation_target_card\", args: \"p_organization_id uuid, p_record_id uuid, p_via_key text DEFAULT NULL::text\", returns: \"TABLE(target_id uuid, target_organization_id uuid, is_foreign boolean, masked boolean, reader_level permission_level, card jsonb, why text)\", security: \"definer\" },\n { name: \"relation_target_external\", args: \"p_connection_token text, p_external_table text, p_external_key text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"relation_target_ours\", args: \"p_entity_token text, p_row_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"relation_targets\", args: \"p_organization_id uuid, p_record_id uuid, p_via_key text\", returns: \"SETOF uuid\", security: \"definer\" },\n { name: \"relation_uncarry\", args: \"p_organization_id uuid, p_container_id uuid, p_item_id uuid\", returns: \"integer\", security: \"definer\" },\n { name: \"relation_value_target_ok\", args: \"p_organization_id uuid, p_field_id uuid, p_field_data jsonb, p_target_id uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"relation_words\", args: \"p_organization_id uuid, p_field_id uuid, p_value text\", returns: \"text\", security: \"definer\" },\n { name: \"relation_words_many\", args: \"p_organization_id uuid, p_field_id uuid, p_record_ids uuid[]\", returns: \"TABLE(record_id uuid, words text, archived boolean)\", security: \"definer\" },\n { name: \"reopen_declared_doors\", args: \"\", returns: \"TABLE(reopened text)\", security: \"definer\" },\n { name: \"required_epoch\", args: \"p_container_type text, p_container_id uuid, p_item_type text, p_item_id uuid\", returns: \"bigint\", security: \"definer\" },\n { name: \"resolve_context\", args: \"p_entity_type text, p_entity_id uuid, p_record_ids uuid[] DEFAULT NULL::uuid[], p_table_ids uuid[] DEFAULT NULL::uuid[], p_system_item_refs text[] DEFAULT NULL::text[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"resolve_first_match\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"resolve_id\", args: \"p_organization_id uuid, p_id uuid\", returns: \"uuid\", security: \"invoker\" },\n { name: \"retired_actor_words\", args: \"\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"reverse_columns\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(key text, label text, source_field_id uuid, source_field_key text, source_field_label text, source_table_id uuid, source_table_name text, cardinality text, read_only boolean)\", security: \"definer\" },\n { name: \"reverse_links_many\", args: \"p_organization_id uuid, p_table_id uuid, p_field_id uuid, p_record_ids uuid[], p_limit integer DEFAULT 10, p_offset integer DEFAULT 0\", returns: \"TABLE(record_id uuid, total integer, links jsonb)\", security: \"definer\" },\n { name: \"rollup_value\", args: \"p_organization_id uuid, p_record_id uuid, p_field_data jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"row_actions\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"row_sits_in_a_personal_table\", args: \"p_type text, p_organization_id uuid, p_id uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"row_template_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_spec jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"row_templates\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(template_id uuid, name text, table_id uuid, \\\"values\\\" jsonb, created_at timestamp with time zone, updated_at timestamp with time zone)\", security: \"definer\" },\n { name: \"rule_applies\", args: \"p_organization_id uuid, p_rule_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"rule_context\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"rule_declare\", args: \"p_organization_id uuid, p_spec jsonb, p_rule_id uuid DEFAULT NULL::uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"rule_dependency_edges\", args: \"p_organization_id uuid, p_row custom.record DEFAULT NULL::custom.record\", returns: \"TABLE(needs text, needed text)\", security: \"invoker\" },\n { name: \"rule_eval\", args: \"p_organization_id uuid, p_expr jsonb, p_values jsonb, p_context jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"rule_field_key\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"rule_field_label\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"rule_filter_node_sql\", args: \"p_organization_id uuid, p_table_id uuid, p_node jsonb, p_map jsonb, p_visible text[]\", returns: \"text\", security: \"invoker\" },\n { name: \"rule_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"rule_members\", args: \"p_organization_id uuid, p_rule_id uuid\", returns: \"SETOF custom.record\", security: \"invoker\" },\n { name: \"rule_members_visible\", args: \"p_organization_id uuid, p_rule_id uuid, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0\", returns: \"TABLE(id uuid, document jsonb, level permission_level)\", security: \"definer\" },\n { name: \"rule_membership\", args: \"p_organization_id uuid, p_rule_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"rule_node_kinds\", args: \"\", returns: \"TABLE(node text, evaluated_by text, note text)\", security: \"invoker\" },\n { name: \"rule_restore\", args: \"p_organization_id uuid, p_rule_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"rule_run\", args: \"p_organization_id uuid, p_rule_id uuid, p_values jsonb, p_context jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"rule_sql_op\", args: \"p_op text, p_a jsonb, p_b jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"rule_truth\", args: \"p_answer jsonb\", returns: \"boolean\", security: \"invoker\" },\n { name: \"rule_uses\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"rule_version\", args: \"p_organization_id uuid, p_rule_id uuid\", returns: \"integer\", security: \"invoker\" },\n { name: \"said\", args: \"p_value text, p_when_there_is_none text\", returns: \"text\", security: \"invoker\" },\n { name: \"scope_item_row_of\", args: \"p_field custom.record\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"scope_item_value_type\", args: \"p_field jsonb, p_carried jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"scope_items_of\", args: \"p_org uuid, p_table uuid\", returns: \"SETOF custom.record\", security: \"invoker\" },\n { name: \"scope_member_reaches\", args: \"p_user_id uuid, p_record_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level\", returns: \"boolean\", security: \"invoker\" },\n { name: \"scope_row_of\", args: \"p_rec custom.record\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"scope_rows_of\", args: \"p_org uuid, p_types uuid[] DEFAULT NULL::uuid[]\", returns: \"TABLE(id uuid, table_id uuid, type_sort integer, sort_order integer, name text, type_doc jsonb, row_doc jsonb)\", security: \"invoker\" },\n { name: \"scope_setting_back\", args: \"p_value jsonb, p_behavior text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"scope_table_provision\", args: \"p_organization_id uuid, p_item_id uuid, p_scope_id uuid, p_home_id uuid DEFAULT NULL::uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"scope_type_row_of\", args: \"p_table custom.record\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"scope_value_columns\", args: \"p_org uuid, p_field jsonb, p_value_type text, p_value jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"seen_among\", args: \"p_user_id uuid, p_ids uuid[]\", returns: \"uuid[]\", security: \"definer\" },\n { name: \"sensitivity_rank\", args: \"p_sensitivity text\", returns: \"integer\", security: \"invoker\" },\n { name: \"set_table_confidential_arman_explicitly_approved\", args: \"p_table_id uuid, p_readers jsonb, p_arman_words text, p_approved_on date, p_maker_is_reader boolean DEFAULT NULL::boolean\", returns: \"jsonb\", security: \"definer\" },\n { name: \"share_access\", args: \"p_organization_id uuid, p_subject_id uuid\", returns: \"TABLE(principal_kind text, principal_id uuid, principal_label text, level permission_level, reason text, reason_detail text, via_type text, via_id uuid, revocable boolean)\", security: \"definer\" },\n { name: \"share_grant\", args: \"p_organization_id uuid, p_subject_id uuid, p_principal_kind text, p_principal_id uuid, p_level permission_level DEFAULT 'viewer'::permission_level\", returns: \"jsonb\", security: \"definer\" },\n { name: \"share_lane_set\", args: \"p_organization_id uuid, p_subject_id uuid, p_choice text, p_level permission_level DEFAULT NULL::permission_level\", returns: \"jsonb\", security: \"definer\" },\n { name: \"share_lanes\", args: \"\", returns: \"TABLE(choice text, lane text, discoverable boolean, label text, means text)\", security: \"definer\" },\n { name: \"share_levels\", args: \"\", returns: \"TABLE(level permission_level, ordinal integer, label text, means text)\", security: \"definer\" },\n { name: \"share_people\", args: \"p_organization_id uuid, p_subject_id uuid DEFAULT NULL::uuid, p_query text DEFAULT NULL::text, p_limit integer DEFAULT 25\", returns: \"TABLE(user_id uuid, email text, display_name text, membership text, already_at permission_level, already_why text)\", security: \"definer\" },\n { name: \"share_revoke\", args: \"p_organization_id uuid, p_subject_id uuid, p_principal_kind text, p_principal_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"share_subject_name\", args: \"p_organization_id uuid, p_type text, p_id uuid\", returns: \"text\", security: \"definer\" },\n { name: \"shared_only_disagreements\", args: \"p_pretend text DEFAULT NULL::text\", returns: \"TABLE(organization_id uuid, organization_name text, member_id uuid, record_id uuid, table_id uuid, ladder boolean, read_door boolean, rls_mirror boolean, why text)\", security: \"invoker\" },\n { name: \"shares_outside\", args: \"p_organization_id uuid\", returns: \"TABLE(invitation_id uuid, table_id uuid, table_name text, email text, level text, level_label text, status text, joined boolean, expired boolean, invited_at timestamp with time zone, expires_at timestamp with time zone, say text)\", security: \"definer\" },\n { name: \"sign_request_cancel\", args: \"p_organization_id uuid, p_request_id uuid, p_reason text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"sign_request_create\", args: \"p_organization_id uuid, p_render_id uuid, p_field_key text, p_signer_email text, p_signer_name text, p_expires_in interval DEFAULT '14 days'::interval\", returns: \"jsonb\", security: \"definer\" },\n { name: \"sign_request_decline\", args: \"p_token text, p_reason text DEFAULT NULL::text, p_ip text DEFAULT NULL::text, p_user_agent text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"sign_request_public\", args: \"p_token text, p_origin text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"sign_request_remind\", args: \"p_organization_id uuid, p_request_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"sign_request_sentence\", args: \"p_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"sign_request_sign\", args: \"p_token text, p_signed_name text, p_mark text, p_image text DEFAULT NULL::text, p_ip text DEFAULT NULL::text, p_user_agent text DEFAULT NULL::text, p_origin text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"sign_request_state\", args: \"p_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"sign_request_unchanged\", args: \"p_organization_id uuid, p_request_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"sign_requests\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(request_id uuid, render_id uuid, record_id uuid, field_key text, document_title text, signer_name text, signer_email text, signer_has_account boolean, state text, sentence text, document_version integer, document_hash text, sent_at timestamp with time zone, expires_at timestamp with time zone, viewed_at timestamp with time zone, signed_at timestamp with time zone, declined_at timestamp with time zone, invalidated_at timestamp with time zone, signature_id uuid, signature_mark text, reminder_count integer)\", security: \"definer\" },\n { name: \"sign_token_decode\", args: \"p_token text\", returns: \"bytea\", security: \"invoker\" },\n { name: \"sign_token_encode\", args: \"p_bytes bytea\", returns: \"text\", security: \"invoker\" },\n { name: \"silent_page_doors\", args: \"\", returns: \"TABLE(door text, why text)\", security: \"definer\" },\n { name: \"size_refusal\", args: \"p_organization_id uuid, p_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"source_next_pointer\", args: \"p_sources jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"source_pointer\", args: \"p_sources jsonb, p_source jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"stage_rule_enforcement\", args: \"p_organization_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"stage_rule_on_fail_kinds\", args: \"\", returns: \"TABLE(behaviour text, note text)\", security: \"invoker\" },\n { name: \"stamp_value_envelopes\", args: \"p_data jsonb, p_actor text, p_on_behalf_of text, p_at timestamp with time zone\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"status_groups_keyed\", args: \"p_organization_id uuid, p_options_table_id uuid, p_groups jsonb, p_kept jsonb, p_label text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"status_groups_of\", args: \"p_groups jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"storage_modes\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"store_census_pair_ceiling\", args: \"\", returns: \"integer\", security: \"invoker\" },\n { name: \"store_is_open\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"store_off_sentence\", args: \"p_organization_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"subscription_cadences\", args: \"p_organization_id uuid\", returns: \"text[]\", security: \"definer\" },\n { name: \"subscription_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_spec jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"subscription_mute\", args: \"p_organization_id uuid, p_rule_id uuid, p_muted boolean DEFAULT true\", returns: \"boolean\", security: \"definer\" },\n { name: \"subscription_preview\", args: \"p_organization_id uuid, p_rule_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"subscriptions\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(rule_id uuid, name text, table_id uuid, saved_view_id uuid, cadence text, schedule text, quiet_hours jsonb, channel text, recipient_user_id uuid, event_key text, muted boolean, mine boolean, i_may_mute boolean, last_sent_at timestamp with time zone, next_digest_at timestamp with time zone)\", security: \"definer\" },\n { name: \"table_add_rung\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"permission_level\", security: \"invoker\" },\n { name: \"table_archive\", args: \"p_organization_id uuid, p_table_id uuid, p_chunk integer DEFAULT 50, p_include_table boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_archive_deliberately\", args: \"p_organization_id uuid, p_table_id uuid, p_typed_slug text, p_reason text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_capacity\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_carries_its_rows\", args: \"p_user_id uuid, p_table_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level\", returns: \"boolean\", security: \"definer\" },\n { name: \"table_column_source\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"table_contents\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(record_id uuid, kind text, goes_at integer)\", security: \"invoker\" },\n { name: \"table_copies_in_progress\", args: \"\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_declare\", args: \"p_organization_id uuid, p_spec jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"table_decorate\", args: \"p_organization_id uuid, p_table_id uuid, p_path text[], p_value jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_decorations\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_dimensions\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_dimensions_set\", args: \"p_organization_id uuid, p_table_id uuid, p_overrides jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_duplicate\", args: \"p_table_id uuid, p_with_records boolean DEFAULT false, p_name text DEFAULT NULL::text, p_organization_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_duplicate_continue\", args: \"p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_ensure\", args: \"p_organization_id uuid, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_facts\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(table_id uuid, visibility text, mine boolean, kept_by_the_app boolean, kept_for text, offered_as_context boolean, keeper_group text, keeper_says text, used_in_kind text, used_in_id uuid, used_in_table_id uuid, foundation boolean)\", security: \"definer\" },\n { name: \"table_find\", args: \"p_organization_id uuid, p_slug text DEFAULT NULL::text, p_name text DEFAULT NULL::text, p_kept_for text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_from_example\", args: \"p_organization_id uuid, p_home_id uuid, p_example jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_has_a_visible_record\", args: \"p_user uuid, p_organization_id uuid, p_table_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"table_home\", args: \"p_table_id uuid, p_to_organization_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_is_foundation\", args: \"p_data jsonb\", returns: \"boolean\", security: \"invoker\" },\n { name: \"table_is_live\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"table_is_options_table\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"table_is_platform_context\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"table_kept_for_derived\", args: \"p_data jsonb, p_is_kernel boolean, p_is_options boolean\", returns: \"text\", security: \"invoker\" },\n { name: \"table_kept_out_of_lists\", args: \"p_kept_for text\", returns: \"boolean\", security: \"invoker\" },\n { name: \"table_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"table_kind_facts\", args: \"p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_list_everywhere\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_list_everywhere\", args: \"p_organization_id uuid, p_include_app_tables boolean\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"table_move\", args: \"p_table_id uuid, p_to_organization_id uuid, p_expected_version integer DEFAULT NULL::integer\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_placement\", args: \"p_organization_id uuid, p_table_id uuid, p_data jsonb, p_is_kernel boolean DEFAULT false\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"table_record_ceiling\", args: \"\", returns: \"integer\", security: \"invoker\" },\n { name: \"table_record_ceiling\", args: \"p_organization_id uuid\", returns: \"integer\", security: \"invoker\" },\n { name: \"table_restore\", args: \"p_organization_id uuid, p_table_id uuid, p_chunk integer DEFAULT 20\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_row_counts\", args: \"p_organization_id uuid, p_table_ids uuid[]\", returns: \"TABLE(table_id uuid, visible_rows bigint)\", security: \"definer\" },\n { name: \"table_row_defaults\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_row_defaults_apply\", args: \"p_organization_id uuid, p_table_id uuid, p_after uuid DEFAULT NULL::uuid, p_budget_ms integer DEFAULT 4000\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_row_defaults_set\", args: \"p_organization_id uuid, p_table_id uuid, p_defaults jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_rules\", args: \"p_organization_id uuid, p_table_id uuid, p_use text, p_record_type text DEFAULT NULL::text\", returns: \"SETOF custom.record\", security: \"invoker\" },\n { name: \"table_share_outside\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_share_outside_accept\", args: \"p_token text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_share_outside_for_me\", args: \"\", returns: \"TABLE(invitation_id uuid, organization_id uuid, organization text, table_id uuid, table_name text, level text, level_label text, token text, expires_at timestamp with time zone, say text)\", security: \"definer\" },\n { name: \"table_share_outside_grant\", args: \"p_organization_id uuid, p_table_id uuid, p_person text, p_level permission_level DEFAULT 'viewer'::permission_level\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_share_outside_invite\", args: \"p_organization_id uuid, p_table_id uuid, p_email text, p_level permission_level DEFAULT 'viewer'::permission_level\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_share_outside_resend\", args: \"p_organization_id uuid, p_invitation_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_share_outside_revoke\", args: \"p_organization_id uuid, p_invitation_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_stage_field\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"text\", security: \"definer\" },\n { name: \"table_storage\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"table_sync\", args: \"p_organization_id uuid, p_home_id uuid, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_transfer_owner\", args: \"p_table_id uuid, p_to_person uuid, p_reason text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_type_field\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"text\", security: \"definer\" },\n { name: \"table_unique_rule_fields\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"table_webhook_archive\", args: \"p_organization_id uuid, p_webhook_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"table_webhook_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_target_url text, p_events text[] DEFAULT NULL::text[], p_description text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_webhooks\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(webhook_id uuid, target_url text, description text, events text[], is_active boolean, last_attempt_at timestamp with time zone, last_success_at timestamp with time zone, consecutive_failures integer, owner_id uuid, created_at timestamp with time zone)\", security: \"definer\" },\n { name: \"table_work_kind\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"tables_at_home\", args: \"p_organization_id uuid, p_home_ids uuid[]\", returns: \"TABLE(table_id uuid, home_record_id uuid, kind text)\", security: \"definer\" },\n { name: \"tables_described_without_asking\", args: \"\", returns: \"TABLE(function_name text, identity_args text, why text)\", security: \"invoker\" },\n { name: \"tables_i_can_open\", args: \"\", returns: \"TABLE(table_id uuid, table_name text, organization_id uuid, organization_name text, member boolean, visibility text, updated_at timestamp with time zone)\", security: \"definer\" },\n { name: \"tables_listed_among\", args: \"p_organization_id uuid, p_tables uuid[]\", returns: \"SETOF uuid\", security: \"invoker\" },\n { name: \"tables_seen_among\", args: \"p_user_id uuid, p_organization_ids uuid[], p_among uuid[]\", returns: \"TABLE(organization_id uuid, id uuid, seen boolean)\", security: \"definer\" },\n { name: \"tables_seen_once_per_group\", args: \"p_user_id uuid, p_organization_ids uuid[]\", returns: \"TABLE(organization_id uuid, id uuid, seen boolean)\", security: \"definer\" },\n { name: \"tables_shared_with_me\", args: \"\", returns: \"TABLE(table_id uuid, organization_id uuid, organization text, table_name text, level text, level_label text, shared_at timestamp with time zone, opens boolean, say text)\", security: \"definer\" },\n { name: \"template_archive\", args: \"p_template_id uuid, p_restore boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\n { name: \"template_declare\", args: \"p_scope text, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"template_from_tables\", args: \"p_organization_id uuid, p_table_ids uuid[], p_include_rows boolean DEFAULT false, p_rows_per_table integer DEFAULT 25\", returns: \"jsonb\", security: \"definer\" },\n { name: \"template_install\", args: \"p_organization_id uuid, p_template_id uuid, p_budget_ms integer DEFAULT 4000\", returns: \"jsonb\", security: \"definer\" },\n { name: \"template_install_claim\", args: \"p_organization_id uuid, p_install_id uuid, p_kind text, p_label text, p_source_id uuid DEFAULT NULL::uuid, p_lease_seconds integer DEFAULT NULL::integer\", returns: \"jsonb\", security: \"definer\" },\n { name: \"template_install_note\", args: \"p_organization_id uuid, p_install_id uuid, p_kind text, p_id uuid, p_label text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"template_keep\", args: \"p_template_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"template_restore\", args: \"p_organization_id uuid, p_install_id uuid, p_budget_ms integer DEFAULT 4000\", returns: \"jsonb\", security: \"definer\" },\n { name: \"template_uninstall\", args: \"p_organization_id uuid, p_install_id uuid, p_budget_ms integer DEFAULT 4000\", returns: \"jsonb\", security: \"definer\" },\n { name: \"templates\", args: \"p_filter jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"text_head_bytes\", args: \"p_text text, p_bytes bigint\", returns: \"text\", security: \"invoker\" },\n { name: \"trg_associations_bump_visibility\", args: \"\", returns: \"trigger\", security: \"definer\" },\n { name: \"undeclared_keys\", args: \"p_organization_id uuid, p_table_id uuid, p_data jsonb\", returns: \"text[]\", security: \"invoker\" },\n { name: \"unresolved_sources_of\", args: \"p_sources jsonb, p_visible text[], p_by_id boolean DEFAULT false, p_key_ids jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"validate_custom_fields\", args: \"p_token text, p_organization_id uuid, p_values jsonb\", returns: \"void\", security: \"invoker\" },\n { name: \"validate_value_envelope\", args: \"p_organization_id uuid, p_fields custom.record[], p_data jsonb\", returns: \"void\", security: \"invoker\" },\n { name: \"validate_values\", args: \"p_organization_id uuid, p_fields custom.record[], p_values jsonb, p_record_type text DEFAULT NULL::text\", returns: \"void\", security: \"invoker\" },\n { name: \"value_alternate_keys\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"value_envelope_keys\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"value_envelope_ok\", args: \"p_data jsonb\", returns: \"boolean\", security: \"invoker\" },\n { name: \"value_envelope_refusal\", args: \"p_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"value_read\", args: \"p_organization_id uuid, p_record_id uuid, p_key text\", returns: \"TABLE(field_key text, field_id uuid, value jsonb, value_version integer, source jsonb, absent_reason text, actor text, on_behalf_of text, written_at timestamp with time zone, alternates jsonb)\", security: \"definer\" },\n { name: \"value_restore\", args: \"p_organization_id uuid, p_record_id uuid, p_field_key text, p_version integer\", returns: \"jsonb\", security: \"definer\" },\n { name: \"value_restore\", args: \"p_organization_id uuid, p_record_id uuid, p_field_key text, p_version integer, p_author jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"value_versions\", args: \"p_old jsonb, p_new jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"view_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_spec jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"view_designate\", args: \"p_organization_id uuid, p_table_id uuid, p_view_id uuid, p_layout text DEFAULT NULL::text\", returns: \"uuid\", security: \"definer\" },\n { name: \"view_keys\", args: \"\", returns: \"TABLE(path text, shape text, layouts text[], writer text, sentence text)\", security: \"invoker\" },\n { name: \"view_keys_check\", args: \"p_organization_id uuid, p_table_id uuid, p_set jsonb, p_old jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"view_look_read\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"view_look_set\", args: \"p_organization_id uuid, p_table_id uuid, p_view_id uuid, p_look jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"view_record_order_set\", args: \"p_organization_id uuid, p_view_id uuid, p_record_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"views\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(view_id uuid, name text, table_id uuid, filters jsonb, definition jsonb, created_at timestamp with time zone)\", security: \"definer\" },\n { name: \"visibility_ancestors\", args: \"p_item_type text, p_item_id uuid\", returns: \"TABLE(container_type text, container_id uuid, depth integer, max_level permission_level)\", security: \"definer\" },\n { name: \"visibility_as_of\", args: \"p_organization_id uuid, p_record_id uuid, p_at timestamp with time zone\", returns: \"TABLE(principal_kind text, principal_id uuid, level permission_level, through_kind text, through_id uuid, reason text, replayed boolean, held_from timestamp with time zone, held_to timestamp with time zone)\", security: \"definer\" },\n { name: \"visibility_cache_rebuild\", args: \"\", returns: \"integer\", security: \"definer\" },\n { name: \"visibility_parity\", args: \"\", returns: \"TABLE(side text, container_type text, container_id uuid, item_type text, item_id uuid, stored_level permission_level, derived_level permission_level, reason text)\", security: \"definer\" },\n { name: \"visibility_warm\", args: \"p_container_type text, p_container_id uuid\", returns: \"integer\", security: \"definer\" },\n { name: \"visible_predicate_sql\", args: \"p_user uuid, p_organization_id uuid, p_table_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level, p_alias text DEFAULT 'r'::text\", returns: \"text\", security: \"definer\" },\n { name: \"visible_record_ids\", args: \"p_user_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level\", returns: \"TABLE(id uuid)\", security: \"definer\" },\n { name: \"visible_set\", args: \"p_user uuid, p_organization_id uuid, p_table_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level, OUT o_all_visible boolean, OUT o_true_visibility platform.visibility[], OUT o_granted_all uuid[], OUT o_granted_visible uuid[], OUT o_carried_visible uuid[], OUT o_ladder_calls integer, OUT o_fallback boolean, OUT o_note text\", returns: \"record\", security: \"definer\" },\n { name: \"where_id_opens\", args: \"p_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"where_lists_live\", args: \"p_list_ids uuid[]\", returns: \"TABLE(list_id uuid, lives_in text, address text, why text)\", security: \"definer\" },\n { name: \"where_tables_live\", args: \"p_table_ids uuid[]\", returns: \"TABLE(table_id uuid, lives_in text, why text)\", security: \"definer\" },\n { name: \"whole_value_ceiling\", args: \"p_organization_id uuid\", returns: \"bigint\", security: \"invoker\" },\n { name: \"whole_value_complete\", args: \"p_organization_id uuid, p_record_id uuid, p_field_key text, p_file_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"whole_value_head\", args: \"p_text text\", returns: \"text\", security: \"invoker\" },\n { name: \"whole_value_park\", args: \"p_organization_id uuid, p_table_id uuid, p_record_id uuid, p_owner_id uuid, p_visibility platform.visibility, p_data jsonb, p_park jsonb\", returns: \"void\", security: \"invoker\" },\n { name: \"whole_value_pointer_of\", args: \"p_values jsonb, p_sources jsonb, p_key text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"whole_value_source\", args: \"p_text text, p_writer_src jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"whole_values_waiting\", args: \"p_organization_id uuid, p_record_ids uuid[]\", returns: \"TABLE(record_id uuid, field_key text, pointer text, value_version integer, sha256 text, bytes bigint, chars bigint, owner_id uuid, record_visibility text, table_id uuid, table_name text)\", security: \"definer\" },\n { name: \"widget_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"with_whole_value_pointers\", args: \"p_document jsonb, p_values jsonb, p_sources jsonb, p_visible text[], p_by_id boolean DEFAULT false, p_key_ids jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"withheld_marker\", args: \"p_mask jsonb, p_key text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"withheld_sentence\", args: \"p_mask jsonb, p_key text\", returns: \"text\", security: \"invoker\" },\n { name: \"work_approval_approvers\", args: \"p_organization_id uuid, p_subject_id uuid, p_approver_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(user_id uuid, name text, why text)\", security: \"definer\" },\n { name: \"work_approval_decide\", args: \"p_organization_id uuid, p_approval_id uuid, p_approve boolean, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_approval_kinds\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"work_approval_may_decide\", args: \"p_organization_id uuid, p_approval_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"work_approval_read\", args: \"p_organization_id uuid, p_approval_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_approval_request\", args: \"p_organization_id uuid, p_subject_id uuid, p_change jsonb, p_note text DEFAULT NULL::text, p_approver_id uuid DEFAULT NULL::uuid, p_origin text DEFAULT 'person'::text, p_conversation_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_approval_withdrawal\", args: \"p_organization_id uuid, p_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"work_assign\", args: \"p_organization_id uuid, p_record_id uuid, p_assignee_user_id uuid, p_due_date timestamp with time zone DEFAULT NULL::timestamp with time zone, p_clear_due boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_assignment_fields\", args: \"p_options_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(key text, label text, spec jsonb)\", security: \"invoker\" },\n { name: \"work_decide_many\", args: \"p_organization_id uuid, p_decisions jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_has_assignment\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"work_inbox\", args: \"p_organization_id uuid DEFAULT NULL::uuid, p_limit integer DEFAULT 50, p_offset integer DEFAULT 0, p_include_decided boolean DEFAULT false, p_view text DEFAULT 'inbox'::text\", returns: \"TABLE(item_id uuid, kind text, origin text, title text, subject_id uuid, subject_kind text, summary text, state text, due_on timestamp with time zone, due_state text, actionable boolean, requested_by uuid, requested_by_name text, at timestamp with time zone, table_id uuid, table_name text, decided_by uuid, decided_by_name text, decided_at timestamp with time zone, outcome text, snoozed_until timestamp with time zone, cleared_at timestamp with time zone, snoozed_count integer, cleared_count integer, undo_seconds integer, undo_refusal text)\", security: \"definer\" },\n { name: \"work_instantiation_shape\", args: \"p_organization_id uuid, p_instantiation_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_list\", args: \"p_organization_id uuid DEFAULT NULL::uuid, p_flavour text DEFAULT 'mine'::text, p_include_finished boolean DEFAULT false, p_limit integer DEFAULT 100, p_offset integer DEFAULT 0\", returns: \"TABLE(record_id uuid, table_id uuid, table_name text, title text, assignee_id uuid, assignee_name text, assignee_user_id uuid, due_on timestamp with time zone, due_state text, status text, terminal boolean, assigned_by uuid, updated_at timestamp with time zone)\", security: \"definer\" },\n { name: \"work_person\", args: \"p_organization_id uuid, p_user_id uuid, p_create boolean DEFAULT true\", returns: \"uuid\", security: \"definer\" },\n { name: \"work_record_states\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(state_id uuid, name text, sort integer, terminal boolean, is_current boolean, allowed boolean, refusal text)\", security: \"definer\" },\n { name: \"work_relation_kinds\", args: \"\", returns: \"TABLE(kind text, available boolean, why text)\", security: \"invoker\" },\n { name: \"work_set_state\", args: \"p_organization_id uuid, p_record_id uuid, p_state_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_slot_expire\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"integer\", security: \"definer\" },\n { name: \"work_slot_hold\", args: \"p_organization_id uuid, p_table_id uuid, p_slot_key text, p_holder text, p_ttl interval DEFAULT '00:15:00'::interval\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_slot_holds\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(hold_id uuid, slot_key text, holder text, expires_at timestamp with time zone, expired boolean)\", security: \"definer\" },\n { name: \"work_slot_index_name\", args: \"p_table_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"work_slot_release\", args: \"p_organization_id uuid, p_hold_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"work_slots_declare\", args: \"p_organization_id uuid, p_name text, p_slug text, p_home_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_state_id\", args: \"p_organization_id uuid, p_table_id uuid, p_value text\", returns: \"uuid\", security: \"invoker\" },\n { name: \"work_states\", args: \"\", returns: \"TABLE(sort integer, name text, terminal boolean, next text[])\", security: \"invoker\" },\n { name: \"work_take_assignment\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_template_declare\", args: \"p_organization_id uuid, p_name text, p_graph jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"work_template_instantiate\", args: \"p_organization_id uuid, p_template_id uuid, p_overrides jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_template_refusal\", args: \"p_graph jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"work_template_shape\", args: \"p_organization_id uuid, p_template_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_templates\", args: \"p_organization_id uuid, p_limit integer DEFAULT 100\", returns: \"TABLE(template_id uuid, name text, nodes integer, relations integer, created_at timestamp with time zone)\", security: \"definer\" },\n { name: \"work_transition_refusal\", args: \"p_organization_id uuid, p_from_state_id uuid, p_to_state_id uuid\", returns: \"text\", security: \"definer\" },\n { name: \"work_whose_turn\", args: \"p_organization_id uuid, p_table_id uuid, p_include_finished boolean DEFAULT false\", returns: \"TABLE(record_id uuid, title text, assignee_id uuid, turn text, due_on timestamp with time zone, state text, status text, terminal boolean)\", security: \"definer\" },\n] as const;\n\n/** The campaign's own knobs, with the value the store resolves them to today. */\nexport const STORE_KNOBS = [\n { key: \"accessible_entity_ids_guard\", value: \"true\", type: \"boolean\" },\n { key: \"action_run_records_max\", value: \"5000\", type: \"integer\" },\n { key: \"agent_context_reads_the_copy\", value: \"true\", type: \"boolean\" },\n { key: \"agent_context_value_cap_bytes\", value: \"0\", type: \"integer\" },\n { key: \"agent_schema_changes\", value: \"\\\"ask\\\"\", type: \"string\" },\n { key: \"archive_confirm_over\", value: \"1000\", type: \"integer\" },\n { key: \"back_links\", value: \"true\", type: \"boolean\" },\n { key: \"batch_items_max\", value: \"500\", type: \"integer\" },\n { key: \"choice_nudge\", value: \"\\\"ask\\\"\", type: \"string\" },\n { key: \"closed_custom_field_tables\", value: \"[\\\"party\\\"]\", type: \"json\" },\n { key: \"code_paths_enabled\", value: \"true\", type: \"boolean\" },\n { key: \"consumer_chat_seeding_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"consumer_checkout_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"consumer_context_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"consumer_education_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"consumer_extension_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"consumer_grid_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"consumer_retirement_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"consumer_saved_ai_outputs_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"consumer_scopes_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"containment_depth_ceiling\", value: \"16\", type: \"integer\" },\n { key: \"context_copy_following\", value: \"true\", type: \"boolean\" },\n { key: \"cross_organization_links\", value: \"false\", type: \"boolean\" },\n { key: \"data_home_default_kind\", value: \"\\\"all\\\"\", type: \"string\" },\n { key: \"data_home_default_order\", value: \"\\\"updated\\\"\", type: \"enum\" },\n { key: \"data_home_default_scope\", value: \"\\\"all\\\"\", type: \"enum\" },\n { key: \"data_home_default_view\", value: \"\\\"table\\\"\", type: \"enum\" },\n { key: \"decision_undo_seconds\", value: \"5\", type: \"integer\" },\n { key: \"decoration_rules_max\", value: \"50\", type: \"integer\" },\n { key: \"decorations_max_bytes\", value: \"262144\", type: \"integer\" },\n { key: \"document_letterhead\", value: \"{}\", type: \"json\" },\n { key: \"document_max_bytes\", value: \"1048576\", type: \"integer\" },\n { key: \"enrichment_batch_ceiling\", value: \"200\", type: \"integer\" },\n { key: \"enrichment_confidence_floor\", value: \"0.6\", type: \"number\" },\n { key: \"enrichment_cost_cap_cents\", value: \"2000\", type: \"integer\" },\n { key: \"enrichment_model\", value: \"\\\"claude-fable-5-latest\\\"\", type: \"string\" },\n { key: \"enrichment_sensitivity_ceiling\", value: \"\\\"internal\\\"\", type: \"string\" },\n { key: \"entity_types_guard\", value: \"false\", type: \"boolean\" },\n { key: \"example_rows_max\", value: \"500\", type: \"integer\" },\n { key: \"export_rows_ceiling\", value: \"100000\", type: \"integer\" },\n { key: \"external_principal_enabled\", value: \"true\", type: \"boolean\" },\n { key: \"field_sensitivity_levels\", value: \"{\\\"edit\\\": {\\\"public\\\": \\\"editor\\\", \\\"internal\\\": \\\"editor\\\", \\\"restricted\\\": \\\"admin\\\", \\\"confidential\\\": \\\"admin\\\"}, \\\"read\\\": {\\\"public\\\": \\\"viewer\\\", \\\"internal\\\": \\\"viewer\\\", \\\"restricted\\\": \\\"admin\\\", \\\"confidential\\\": \\\"editor\\\"}}\", type: \"json\" },\n { key: \"form_draft_days\", value: \"30\", type: \"integer\" },\n { key: \"form_draft_max_bytes\", value: \"65536\", type: \"integer\" },\n { key: \"form_draft_saves_per_hour\", value: \"240\", type: \"integer\" },\n { key: \"form_redirect_domains\", value: \"[]\", type: \"json\" },\n { key: \"grid_layout\", value: \"{\\\"mode\\\": \\\"auto\\\", \\\"wrap\\\": false, \\\"row_height\\\": \\\"normal\\\", \\\"fit_max_columns\\\": 8, \\\"freeze_first_column\\\": false}\", type: \"json\" },\n { key: \"inbound_domain\", value: \"\\\"inbound.matrxserver.com\\\"\", type: \"string\" },\n { key: \"inbox_reminder_after_days\", value: \"3\", type: \"integer\" },\n { key: \"member_default_level\", value: \"\\\"viewer\\\"\", type: \"enum\" },\n { key: \"outside_invite_who\", value: \"\\\"org_admins_and_table_owners\\\"\", type: \"string\" },\n { key: \"page_size_ceiling\", value: \"1000\", type: \"integer\" },\n { key: \"protected_field_rules\", value: \"{\\\"hr_employee\\\": {\\\"arm\\\": \\\"hr.arm_write\\\", \\\"rule\\\": \\\"hr.custom_field_access\\\", \\\"readers\\\": [{\\\"field\\\": \\\"subject\\\"}, {\\\"capability\\\": \\\"hr.identity.read\\\"}, {\\\"capability\\\": \\\"hr.working_record.write\\\"}, {\\\"level\\\": \\\"editor\\\", \\\"capability\\\": \\\"hr.identity.write\\\"}]}, \\\"hr_candidate\\\": {\\\"arm\\\": \\\"hr.arm_write\\\", \\\"rule\\\": \\\"hr.custom_field_access\\\", \\\"readers\\\": [{\\\"field\\\": \\\"subject\\\"}, {\\\"capability\\\": \\\"hr.identity.read\\\"}, {\\\"capability\\\": \\\"hr.working_record.write\\\"}, {\\\"level\\\": \\\"editor\\\", \\\"capability\\\": \\\"hr.identity.write\\\"}]}, \\\"hr_position_assignment\\\": {\\\"arm\\\": \\\"hr.arm_write\\\", \\\"rule\\\": \\\"hr.custom_field_access\\\", \\\"readers\\\": [{\\\"field\\\": \\\"subject\\\"}, {\\\"capability\\\": \\\"hr.identity.read\\\"}, {\\\"capability\\\": \\\"hr.working_record.write\\\"}, {\\\"level\\\": \\\"editor\\\", \\\"capability\\\": \\\"hr.identity.write\\\"}]}, \\\"hr_training_assignment\\\": {\\\"arm\\\": \\\"hr.arm_write\\\", \\\"rule\\\": \\\"hr.custom_field_access\\\", \\\"readers\\\": [{\\\"field\\\": \\\"subject\\\"}, {\\\"capability\\\": \\\"hr.identity.read\\\"}, {\\\"capability\\\": \\\"hr.working_record.write\\\"}, {\\\"level\\\": \\\"editor\\\", \\\"capability\\\": \\\"hr.identity.write\\\"}]}}\", type: \"json\" },\n { key: \"provenance_retention_days\", value: \"30\", type: \"number\" },\n { key: \"row_action_steps_max\", value: \"60\", type: \"integer\" },\n { key: \"row_actions_max\", value: \"24\", type: \"integer\" },\n { key: \"sandbox_expanded_frame_height_px\", value: \"20000\", type: \"integer\" },\n { key: \"sandbox_frame_height_px\", value: \"4000\", type: \"integer\" },\n { key: \"sandbox_message_bytes\", value: \"65536\", type: \"integer\" },\n { key: \"sandbox_org_components\", value: \"true\", type: \"boolean\" },\n { key: \"scope_members_admitted\", value: \"true\", type: \"boolean\" },\n { key: \"scopes_written_in_the_store\", value: \"true\", type: \"boolean\" },\n { key: \"signup_provisioning_guard\", value: \"false\", type: \"boolean\" },\n { key: \"stage_rule_enforcement\", value: \"\\\"refuse\\\"\", type: \"enum\" },\n { key: \"table_record_ceiling\", value: \"150000\", type: \"integer\" },\n { key: \"table_sync_rows_max\", value: \"20000\", type: \"integer\" },\n { key: \"table_webhooks_max\", value: \"10\", type: \"integer\" },\n { key: \"time_zone\", value: \"\\\"UTC\\\"\", type: \"string\" },\n { key: \"value_max_bytes\", value: \"100000\", type: \"integer\" },\n { key: \"view_record_order_max\", value: \"20000\", type: \"integer\" },\n { key: \"week_start\", value: \"\\\"monday\\\"\", type: \"enum\" },\n { key: \"world_publish_enabled\", value: \"false\", type: \"boolean\" },\n] as const;\n\n/**\n * Every SQLSTATE the store's own function bodies raise, with the functions that\n * raise it. This is the list the client's refusal mapper is checked against: a\n * code the store can raise and the package cannot name is a hole, and the\n * real-door suite says so by name.\n */\nexport const STORE_REFUSAL_CODES = [\n { code: \"02000\", raised_by: \"_checklist_instantiate,_entity_change_file,_portal_config_judge,_portal_invite_payload,_read_record_with,_share_write_person,_table_share_invite_payload,checklist_declare,checklist_run,checklist_step_complete,checklist_step_refusal,checklist_template_shape,conversation_scope_bind,dashboard_delete,dashboard_restore,dashboard_run,doc_letterhead,doc_render_body,doc_render_document,doc_render_read,doc_sign,doc_signature_intact,doc_signature_read,doc_template_delete,doc_template_read,doc_template_restore,doc_template_save,enrich_pin,entity_field_protect_arman_explicitly_approved,entity_field_retire,entity_field_update,entity_record_read,entity_row_propose,entity_row_write,entity_value_write,external_history_event,external_rows,external_stub_upsert,external_writes_set,field_choice_usage,field_restore,field_update_rehoming_choices,form_archive,form_restore,io_restore,migrate_delete,migrate_extract_parent,migrate_merge,migrate_reclass,migrate_rename,migrate_reparent,migrate_retype,migrate_split,migrate_undo,organization_clear,portal_archive,portal_card,portal_declare,portal_form,portal_form_submit,portal_invite,portal_invite_accept,portal_preview,portal_principal_bind,portal_restore,portal_revoke,record_change_many,record_delete,record_restore,record_restore_preview,record_row_controls,record_row_controls_set,record_table,record_update,record_write_graph_superseding,relation_halves_repair,relation_restore,relation_uncarry,rule_restore,set_table_confidential_arman_explicitly_approved,share_access,share_grant,share_lane_set,share_people,share_revoke,sign_request_cancel,sign_request_create,sign_request_remind,sign_request_unchanged,table_archive,table_archive_deliberately,table_restore,table_row_defaults,table_row_defaults_apply,table_row_defaults_set,table_share_outside_accept,table_share_outside_grant,table_share_outside_invite,table_share_outside_resend,table_share_outside_revoke,template_from_tables,visibility_as_of,work_approval_decide,work_approval_read,work_approval_request,work_assign,work_record_states,work_set_state\" },\n { code: \"0A000\", raised_by: \"checklist_step_complete,entity_row_write,external_rows,external_source_declare,external_write_through,promote_field,promoted_index_expr,promoted_query_sql,promoted_read,read_records_page,rule_eval,rule_filter_node_sql,work_assign\" },\n { code: \"22003\", raised_by: \"context_resolve\" },\n { code: \"22004\", raised_by: \"_entity_change_file,_entity_custom_fields_guard,_io_outbox_claim,_portal_config_judge,_share_write_person,_value_envelope,actor_word,agg_assert_key,agg_compare_windows,agg_sql,anon_capture,anon_token_issue,anon_write,assert_client_may_reach,assert_scope_door,booking_declare,capture_submit,checklist_declare,context_resolve,context_template_define,context_type_write,dashboard_block_normalize,dashboard_declare,dashboard_window_sql,doc_render_write,doc_sign,doc_signature_write,doc_template_save,enrich_land,enrich_normalize,entity_field_protect_arman_explicitly_approved,entity_row_propose,external_history_event,external_rows,external_source_declare,external_stub_upsert,external_write_through,external_writes_set,field_history,form_declare,form_look_options,form_submit,home_add,inbox_snooze,io_comment_write,io_import_begin,io_infer_column,io_outbox_drain,io_outbox_release_claimed,io_outbox_subscribe,io_restore,migrate_choice_keys,migrate_purge,migrate_purge_hard,migrate_reclass,migrate_split,migrate_undo,organization_clear,organization_contents,pipeline_declare,pipeline_gate_preview,portal_declare,portal_form_submit,portal_invite,portal_principal_bind,provenance_retention_days,provenance_write,query_across_homes,query_by_coordinates,query_rollup,record_aggregate_as_of,record_delete,record_reparent,record_resolve,record_restore,record_update,record_upsert,record_write,record_write_graph,record_write_graph_superseding,record_write_many,relation_carry,relation_halves_repair,relation_own,row_template_declare,rule_declare,set_table_confidential_arman_explicitly_approved,share_grant,sign_request_create,sign_request_sign,subscription_declare,table_archive,table_archive_deliberately,table_declare,table_duplicate,table_move,table_restore,table_share_outside_grant,table_share_outside_invite,template_declare,value_restore,view_declare,view_designate,view_look_read,view_look_set,whole_value_complete,work_approval_decide,work_approval_request,work_template_declare\" },\n { code: \"22007\", raised_by: \"_template_date,agg_parse_moment,dashboard_window_sql\" },\n { code: \"22012\", raised_by: \"formula_eval,rule_eval,rule_sql_op\" },\n { code: \"22023\", raised_by: \"_action_check,_booking_availability,_ctx_dataset_field_holds,_ctx_reference_value_holds,_ctx_store_scope,_ctx_tree_part,_decorations_check,_entity_change_file,_entity_custom_fields_guard,_form_look_judge,_fx_date,_fx_num,_fx_regex,_fx_unit,_fxp_level,_fxp_resolve,_fxp_tokens,_portal_config_judge,_rule_eval_seated,_table_dimensions_check,_take_op_id,_template_bind,_value_envelope,_view_field_key,_view_key_value,_work_shape_guard,_write_via_mark,action_run,actor_word,agent_change_trust,agg_assert_key,agg_calendar,agg_compare_windows,agg_sql,anon_token_issue,booking_declare,containment_parent,context_scope_write,context_scopes,context_template_define,context_type_write,context_values,count_records_archived,dashboard_block_normalize,dashboard_run,dashboard_target_field_assert,dashboard_window_sql,data_home,data_home_changed_by,doc_render_body,doc_render_write,doc_signature_write,drill_resolve,enrich_declare,enrich_land,enrich_normalize,enrich_pin,entity_fields_across,entity_read_mask,entity_reference_rows,entity_reference_search,entity_reference_words,entity_row_write,entity_value_write,external_history_event,external_source_declare,external_stub_upsert,external_write_through,field_access,field_history,field_update,form_declare,form_draft_save,formula_eval,formula_parse,grid_layout_check,hub_changed_by,inbound_domain,inbox_snooze,io_export,io_import_begin,io_import_finish,io_import_plan,io_import_report,io_proposal_accept,list_portals,listed_predicate_sql,member_records_take_over,migrate_merge,migrate_reclass,my_levels,organization_clear,page_size,pick_list_create,pin_agent_cells,pipeline_move,pipeline_move_many,portal_declare,portal_form_submit,provenance_write,publish_bind,query_by_coordinates,query_rollup,query_rollup_sum,read_records_archived,read_records_in_view_order,read_records_page,record_aggregate_as_of,record_change_many,record_filter_sql,record_row_controls_set,record_search_sql,record_update,record_upsert,record_write_graph,record_write_graph_superseding,record_write_many,records_search,relation_carry,relation_names_match,row_template_declare,rule_eval,rule_filter_node_sql,rule_members,rule_members_visible,rule_sql_op,scope_table_provision,share_grant,share_lane_set,sign_request_create,sign_request_sign,subscription_declare,table_archive_deliberately,table_ensure,table_find,table_from_example,table_move,table_row_defaults_set,table_rules,table_share_outside_grant,table_sync,table_transfer_owner,table_webhook_declare,template_declare,template_from_tables,template_install_claim,template_install_note,templates,view_declare,view_keys_check,view_look_set,view_record_order_set,visibility_as_of,where_lists_live,where_tables_live,work_approval_request,work_decide_many,work_inbox,work_list,work_slot_hold\" },\n { code: \"23503\", raised_by: \"_action_check,_booking_availability,_checklist_instantiate,_containment_guard,_ctx_store_value,_decorations_check,_display_spec_for,_field_document_for,_field_type_parity_guard,_pipeline_stage_key,_record_rule_uses,action_declare,action_run,agg_digest_assemble,anon_publish,anon_rate_take,anon_token_issue,anon_write,assert_organization_wall,autonumber_backfill,booking_cancel,booking_confirm,booking_declare,booking_hold,booking_reschedule,capture_publish,checklist_declare,checklist_steps_table,comment_write,dashboard_declare,delete_rule,doc_sign,doc_template_save,enrich_declare,enrich_due,enrich_land,form_declare,form_draft_save,form_submit,grid_layout,home_add,inbound_declare,inbound_mail_land,inbound_set,io_comment_write,io_import_begin,io_import_finish,io_import_report,io_import_rows,io_proposal_accept,migrate_demote,migrate_promote,migrate_purge_hard,pipeline_board,pipeline_declare,pipeline_move,pipeline_read,pipeline_transition_refusal,promote_field,promote_table,read_records_in_view_order,read_records_page,record_applicability,record_reparent,record_write_graph_superseding,relation_carry,relation_own,resolve_first_match,row_template_declare,rule_applies,rule_declare,rule_eval,rule_filter_node_sql,rule_members,rule_members_visible,rule_run,sign_request_create,subscription_mute,subscription_preview,table_decorate,table_dimensions_set,table_from_example,table_webhook_archive,table_webhook_declare,view_declare,view_designate,view_look_set,view_record_order_set,whole_value_complete,work_set_state,work_take_assignment,work_template_instantiate\" },\n { code: \"23505\", raised_by: \"_ctx_store_item,_ctx_store_scope,_ctx_store_type,_portal_config_judge,_share_write_person,_unique_rule_holds,doc_sign,doc_signature_write,entity_field_declare,field_declare,field_restore,field_update,form_restore,home_add,inbound_declare,io_proposal_accept,relation_carry,relation_own,relation_restore,sign_request_cancel,sign_request_create,table_share_outside_resend,work_approval_decide,work_slot_hold\" },\n { code: \"23514\", raised_by: \"_checklist_instantiate,_checklist_step_guard,_containment_guard,_ctx_dataset_field_holds,_ctx_scope_parent_holds,_ctx_store_item,_ctx_value_fits_its_scope,_dated_values_guard,_derived_fields,_display_format_check,_display_spec_for,_entity_choice_keys,_entity_custom_fields_guard,_field_choices_save,_field_class_guard,_field_default_fitted,_field_document_for,_field_kind_shape_ok,_field_shape_guard,_field_type_parity_guard,_kind_value_ok,_merge_field_shape_guard,_merge_field_temporal_guard,_promoted_field_cap_guard,_record_rule_uses,_record_source_key_is_record,_relation_halves_agree,_relation_kernel_targets,_resolve_choice_words,_rule_shape_guard,_rule_topology_guard,_store_relation_edge_names_its_field,_table_columns_word_guard,_table_shape_guard,_undeclared_key_guard,_value_envelope,_with_display,_work_shape_guard,_workdoors_approval_guard,action_run,assert_columns_are_defined,assert_entity_is_organization_scoped,booking_declare,capture_publish,capture_sheet_declare,checklist_declare,checklist_step_complete,dashboard_restore,doc_sign,doc_signature_write,doc_template_restore,doc_template_save,entity_field_protect_arman_explicitly_approved,entity_field_retire,entity_field_update,entity_records_find,entity_table,entity_value_write,field_declare,field_restore,field_retire,field_update,field_update_rehoming_choices,form_restore,home_add,io_comment_write,io_import_rows,migrate_merge,migrate_purge_hard,portal_archive,portal_restore,record_restore,record_update_adding_choices,record_upsert,record_write_graph,record_write_graph_superseding,relation_carry,relation_halves_repair,relation_own,relation_restore,rollup_value,row_template_declare,rule_restore,sign_request_create,sign_request_sign,status_groups_keyed,status_groups_of,table_from_example,table_restore,validate_value_envelope,validate_values,whole_value_complete,work_set_state,work_slots_declare,work_take_assignment,work_template_instantiate\" },\n { code: \"40001\", raised_by: \"has_visibility_at,table_move,whole_value_complete\" },\n { code: \"42501\", raised_by: \"_agent_change_gate,_context_copy_fence,_copy_evaluation_note,_copy_evaluation_reimage,_copy_in_progress_guard,_doc_render_immutable,_doc_signature_immutable,_entity_change_file,_entity_custom_fields_guard,_field_definition_write,_field_write_door,_io_outbox_server_only,_portal_config_judge,_portal_principal_here,_read_record_with,_rule_definition_write,_share_write_person,_store_door,_table_dimensions_infer,_table_duplicate_step,_table_shape_guard,_template_call,_value_envelope,_workdoors_approval_guard,agent_change_trust,agent_table_claim,agg_fields_readable_assert,anon_capture,anon_inbound_land,anon_publish,anon_token_issue,anon_token_verify,anon_write,assert_client_may_change,assert_client_may_open,assert_client_may_reach,assert_may_know_table,assert_organization_admin,assert_scope_door,assert_store_door,booking_confirm,booking_declare,booking_hold,capture_submit,checklist_run,comment_write,context_item_archive,context_item_restore,context_item_write,context_resolve,context_scope_archive,context_scope_restore,context_scope_write,context_tags_set,context_type_archive,context_type_restore,context_type_write,conversation_scope_bind,conversation_scope_unbind,count_records_archived,dashboard_target_field_assert,doc_sign,enrich_declare,enrich_due,enrich_land,enrich_normalize,entity_field_declare,entity_field_retire,entity_field_update,entity_row_propose,entity_row_write,entity_value_write,external_write_through,field_restore,form_declare,form_draft_save,form_public_asks,form_submit,inbound_mail_land,inbox_clear,inbox_snooze,inbox_unclear,inbox_unsnooze,io_comment_resolve,io_comment_write,io_import_begin,io_import_finish,io_restore,member_personal_tables,migrate_purge,migrate_purge_hard,migrate_purge_hard_request,migrate_reclass,my_levels,organization_clear,organization_contents,portal_declare,portal_form,portal_form_submit,portal_invitation,portal_invite,portal_invite_accept,portal_principal_bind,promote_table,protected_matches,query_visibility_parity,read_record,read_records,read_records_archived,read_records_by_ids,read_records_matching,read_records_page,record_delete,record_row_controls,record_table,record_write_graph,relation_halves_disagreements,relation_halves_repair,resolve_context,reverse_links_many,scope_table_provision,share_grant,subscription_mute,subscription_preview,table_archive_deliberately,table_copies_in_progress,table_duplicate,table_duplicate_continue,table_kind_facts,table_move,table_row_defaults_apply,table_row_defaults_set,table_share_outside_accept,table_share_outside_grant,table_share_outside_invite,table_share_outside_resend,table_sync,table_transfer_owner,table_webhook_declare,template_declare,template_install,templates,view_declare,view_look_set,view_record_order_set,visibility_as_of,where_lists_live,where_tables_live,whole_value_complete,work_approval_decide,work_approval_read,work_approval_request,work_person\" },\n { code: \"42703\", raised_by: \"entity_table,portal_declare\" },\n { code: \"42883\", raised_by: \"_template_call\" },\n { code: \"42P17\", raised_by: \"_field_reads_what_it_reads,far_value\" },\n { code: \"53400\", raised_by: \"anon_rate_take,delete_cascade_closure,enrich_due,enrich_land,promote_field\" },\n { code: \"54000\", raised_by: \"_table_dimensions_check,action_run,data_home_changed_by,form_draft_save,hub_changed_by,pipeline_move_many,record_change_many,record_headers,relation_names_match,reverse_links_many,table_decorate,table_from_example,table_row_counts,table_sync,table_webhook_declare,view_record_order_set,work_decide_many\" },\n { code: \"54001\", raised_by: \"record_delete\" },\n { code: \"55000\", raised_by: \"_code_depends_refuse,_io_outbox_claim,entity_field_protect_arman_explicitly_approved,inbox_clear,inbox_snooze,io_outbox_release,io_outbox_subscribe,table_duplicate,table_ensure,table_move,template_install,template_restore,work_approval_decide,work_approval_request\" },\n { code: \"57014\", raised_by: \"formula_eval\" },\n { code: \"MXD01\", raised_by: \"_held_change_refusal\" },\n { code: \"MXD02\", raised_by: \"entity_row_propose\" },\n { code: \"P0001\", raised_by: \"action_run,context_scope_write\" },\n { code: \"P0002\", raised_by: \"inbox_clear,inbox_snooze,publish_bind,template_archive,template_install,template_install_claim,template_install_note,template_keep,template_restore,template_uninstall,whole_value_complete\" },\n { code: \"PT409\", raised_by: \"entity_row_write,record_change_many,record_update,record_upsert,record_write_graph_superseding\" },\n { code: \"PT428\", raised_by: \"_record_rule_uses\" },\n] as const;\n\n/** `platform.entity_types` — the registered tokens a Table or relation may name. */\nexport const ENTITY_TOKENS = [\n \"access_delta_probe\",\n \"access_delta_run\",\n \"access_request\",\n \"account_addon\",\n \"acquisition_block\",\n \"activity\",\n \"admin_audit_log\",\n \"admin_email_log\",\n \"admin_markdown_sample\",\n \"admin_user\",\n \"admission_config\",\n \"agent\",\n \"agent_card\",\n \"agent_definition_version\",\n \"agent_drift_alert\",\n \"agent_exemplar\",\n \"agent_mandate_note\",\n \"agent_prompt_remediation\",\n \"agent_run\",\n \"agent_run_stage\",\n \"agent_schedule\",\n \"agent_schedule_claim\",\n \"agent_shortcut\",\n \"agent_surface_binding\",\n \"agent_template\",\n \"agent_term_list\",\n \"agent_usage\",\n \"agent_user_kv\",\n \"ai_api\",\n \"ai_calls\",\n \"ai_endpoint\",\n \"ai_model\",\n \"ai_model_alias\",\n \"ai_offering\",\n \"ai_provider\",\n \"ai_setting\",\n \"ai_setting_profile\",\n \"ai_translation_cell\",\n \"ai_usage_executions\",\n \"ai_usage_hourly\",\n \"ai_usage_hourly_watermark\",\n \"analysis_result\",\n \"anon_form\",\n \"anon_function_birth_grandfather\",\n \"anon_hit\",\n \"anon_inbound\",\n \"anon_replay\",\n \"anon_submission\",\n \"anon_token\",\n \"api_field_warning\",\n \"api_request_log\",\n \"app\",\n \"app_config\",\n \"app_config_history\",\n \"app_definition_version\",\n \"app_error\",\n \"app_execution\",\n \"app_instance\",\n \"app_log\",\n \"app_log_muted_pattern\",\n \"app_log_norm_exception\",\n \"app_rate_limit\",\n \"app_setting\",\n \"app_sync_status\",\n \"approach\",\n \"artifact\",\n \"assessment\",\n \"assessment_item\",\n \"assessment_result\",\n \"assignment_session\",\n \"assist\",\n \"assist_producer_policy\",\n \"assist_producer_policy_history\",\n \"association_type\",\n \"assurance_level\",\n \"attempt\",\n \"audit_broken_functions\",\n \"audit_canonical_findings\",\n \"audit_exemption\",\n \"audit_function_deps\",\n \"audit_function_runtime_probe\",\n \"audit_m2m_candidates\",\n \"audit_refresh_log\",\n \"audit_stale_registry\",\n \"audit_unregistered_candidates\",\n \"base_entity_template\",\n \"batch_cost_event\",\n \"batch_provider_batch\",\n \"batch_work_item\",\n \"billing_capability\",\n \"billing_capability_limit\",\n \"billing_connect_account\",\n \"billing_coupon\",\n \"billing_coupon_redemption\",\n \"billing_customer\",\n \"billing_free_period_grant\",\n \"billing_plan\",\n \"billing_plan_limit\",\n \"billing_price\",\n \"billing_product\",\n \"billing_spend_approval\",\n \"billing_spend_guardrail\",\n \"billing_stripe_event\",\n \"billing_subscription\",\n \"billing_usage_ledger\",\n \"billing_usage_reset\",\n \"billing_user_plan\",\n \"block_state\",\n \"board\",\n \"browser_account_binding\",\n \"browser_action_event\",\n \"browser_authenticator_window\",\n \"browser_capture\",\n \"browser_control_request\",\n \"browser_handoff\",\n \"browser_login_attempt\",\n \"browser_login_recipe\",\n \"browser_profile\",\n \"browser_profile_checkpoint\",\n \"browser_run\",\n \"browser_site_observation\",\n \"browser_site_policy\",\n \"browser_stream_ticket\",\n \"build_lock\",\n \"calendar_event\",\n \"campaign_watch_ramp_gate_run\",\n \"campaign_watch_switch_outbox\",\n \"campaign_watch_switch_window\",\n \"canvas_comment\",\n \"canvas_comment_like\",\n \"canvas_item\",\n \"canvas_item_state\",\n \"canvas_like\",\n \"canvas_score\",\n \"canvas_view\",\n \"capture_window\",\n \"carrying_rule\",\n \"catalog_entries_history\",\n \"catalog_entry\",\n \"category\",\n \"change_type_default\",\n \"chat_user_usage_summary\",\n \"citations\",\n \"class_purchase\",\n \"classifier_revision_ledger\",\n \"client_callable_door\",\n \"client_callable_door_retirement\",\n \"client_excluded_column_unregistered\",\n \"cmp_entry\",\n \"cmp_feedback\",\n \"code_file\",\n \"code_folder\",\n \"code_repository\",\n \"coding_session\",\n \"coding_session_entry\",\n \"comment\",\n \"commerce_asset_allocation\",\n \"commerce_asset_grading\",\n \"commerce_asset_identifier\",\n \"commerce_asset_lot_event\",\n \"commerce_asset_mandate_result\",\n \"commerce_asset_price_factor\",\n \"commerce_asset_reshoot_request\",\n \"commerce_asset_review\",\n \"commerce_asset_unknown\",\n \"commerce_certified_printer\",\n \"commerce_cloud_sync_connection\",\n \"commerce_ebay_business_policy\",\n \"commerce_ebay_category\",\n \"commerce_ebay_category_aspect\",\n \"commerce_ebay_category_tree\",\n \"commerce_ebay_custom_policy\",\n \"commerce_ebay_inventory_item\",\n \"commerce_ebay_inventory_item_group\",\n \"commerce_ebay_inventory_item_group_member\",\n \"commerce_ebay_inventory_location\",\n \"commerce_ebay_listing\",\n \"commerce_ebay_marketplace_policy\",\n \"commerce_ebay_media_asset\",\n \"commerce_ebay_notification_destination\",\n \"commerce_ebay_notification_event\",\n \"commerce_ebay_notification_subscription\",\n \"commerce_ebay_notification_topic\",\n \"commerce_ebay_offer\",\n \"commerce_ebay_order\",\n \"commerce_ebay_order_line_item\",\n \"commerce_ebay_shipping_fulfillment\",\n \"commerce_ebay_store_category\",\n \"commerce_human_correction\",\n \"commerce_intake_artifact\",\n \"commerce_intake_asset\",\n \"commerce_intake_batch\",\n \"commerce_label_batch\",\n \"commerce_label_code\",\n \"commerce_marketplace_account\",\n \"commerce_marketplace_account_deletion_audit\",\n \"commerce_marketplace_api_call\",\n \"commerce_marketplace_rate_budget\",\n \"commerce_marketplace_site\",\n \"commerce_marketplace_sync_run\",\n \"commerce_prediction_outcome\",\n \"commerce_print_order\",\n \"commerce_product\",\n \"commerce_product_channel_ref\",\n \"commerce_product_media\",\n \"commerce_product_variant\",\n \"commerce_recall_audit\",\n \"communication_calendar_selected_snapshot_state\",\n \"communication_channel_readiness\",\n \"comparison_set\",\n \"component_group\",\n \"contact_medium\",\n \"contact_submission\",\n \"content_certification\",\n \"content_ir_kind\",\n \"content_ir_kind_component\",\n \"content_ir_kind_component_incident\",\n \"content_ir_kind_conformance\",\n \"content_ir_kind_edge\",\n \"content_ir_kind_example\",\n \"content_ir_kind_instance\",\n \"content_ir_kind_surface\",\n \"content_lane\",\n \"context_access_log\",\n \"context_item\",\n \"context_item_suggestion\",\n \"context_item_value\",\n \"context_value_refs\",\n \"conversation\",\n \"conversation_value\",\n \"courts\",\n \"credential_attachment\",\n \"credential_item\",\n \"credential_mutation_receipt\",\n \"crm_address\",\n \"crm_affiliation\",\n \"crm_blocklist_entry\",\n \"crm_contact_candidate\",\n \"crm_deal\",\n \"crm_deal_stage_event\",\n \"crm_enrichment_call\",\n \"crm_interaction\",\n \"crm_merge_candidate\",\n \"crm_outreach_list\",\n \"crm_outreach_list_member\",\n \"crm_party_merge\",\n \"crm_party_research\",\n \"crm_registry_ingest_run\",\n \"crm_registry_source\",\n \"crm_sending_claim\",\n \"crm_sending_event\",\n \"crm_sending_identity\",\n \"crm_sending_identity_check\",\n \"crm_sending_policy\",\n \"custom_agent_table_trust\",\n \"custom_agg_digest_checked\",\n \"custom_entity_definition\",\n \"custom_field_definition\",\n \"custom_field_target\",\n \"custom_io_outbox_consumer\",\n \"custom_io_outbox_consumption\",\n \"custom_record\",\n \"custom_share_tails_mine_repair\",\n \"custom_template\",\n \"custom_template_install\",\n \"cx_agent_memory\",\n \"cx_agent_plan\",\n \"cx_agent_task\",\n \"cx_code_edit\",\n \"cx_code_message_file\",\n \"cx_conversation_documents\",\n \"cx_media\",\n \"cx_observational_memory\",\n \"cx_observational_memory_event\",\n \"cx_pending_injection\",\n \"cx_request\",\n \"cx_request_snapshot\",\n \"cx_tool_trace\",\n \"cx_user_request\",\n \"cx_user_todo\",\n \"dashboard_saved_view\",\n \"data_rights_event\",\n \"data_store\",\n \"data_store_members\",\n \"dataset\",\n \"ddl_guard_log\",\n \"deck_suggestion\",\n \"definer_class_exemption\",\n \"definer_client_grant_grandfather\",\n \"definer_grant_baseline\",\n \"deprecated_relation\",\n \"derive_run\",\n \"dev_login_audit\",\n \"dict_entry\",\n \"dict_provider_publication\",\n \"dict_setting\",\n \"dm_conversation\",\n \"dm_message\",\n \"dm_participant\",\n \"doc_render\",\n \"doc_signature\",\n \"dockets\",\n \"document\",\n \"document_version\",\n \"domain_classification\",\n \"edge_payload_kind\",\n \"egress_device\",\n \"egress_pairing\",\n \"egress_ticket\",\n \"emails\",\n \"embedding_cache\",\n \"embeddings_google_gemini_2_1536\",\n \"embeddings_oai_3_small_1536\",\n \"embeddings_voyage_4_large_1024\",\n \"embeddings_voyage_code_3_1024\",\n \"endpoint_family_sweep_state\",\n \"engine_owner_task\",\n \"entity_grant\",\n \"entity_protected_value\",\n \"entity_protected_value_version\",\n \"entity_relationship\",\n \"entity_type\",\n \"esign_campaign\",\n \"esign_campaign_member\",\n \"esign_consent_disclosure\",\n \"esign_envelope\",\n \"esign_envelope_certificate\",\n \"esign_envelope_document\",\n \"esign_envelope_event\",\n \"esign_envelope_external_ref\",\n \"esign_envelope_signer\",\n \"esign_provider\",\n \"esign_provider_binding\",\n \"esign_signing_key\",\n \"execution_event_cursor\",\n \"extension_auth_code\",\n \"external_link\",\n \"external_source\",\n \"extract_sweep_state\",\n \"fc_card\",\n \"fc_detail\",\n \"fc_set\",\n \"feature_doc\",\n \"feature_knob\",\n \"feedback_comments\",\n \"feedback_user_messages\",\n \"field_component\",\n \"file\",\n \"file_analysis\",\n \"file_entities\",\n \"file_overrides\",\n \"file_page_annotations\",\n \"file_pages\",\n \"file_rag_job\",\n \"file_version\",\n \"files_account_tier\",\n \"files_machine_written_prefix\",\n \"files_sync_mapping\",\n \"files_user_account\",\n \"flashcard_data\",\n \"flashcard_history\",\n \"flashcard_sets\",\n \"flexible_data\",\n \"folder\",\n \"function_contract\",\n \"game_badge\",\n \"game_result\",\n \"game_room\",\n \"global_execution\",\n \"global_execution_checkpoint\",\n \"global_execution_control\",\n \"global_execution_event\",\n \"global_meter_entry\",\n \"global_origin\",\n \"global_request\",\n \"google_document\",\n \"growth_loop_event\",\n \"growth_loop_run\",\n \"growth_loop_stage_run\",\n \"guardian_link\",\n \"guest_conversion_audit\",\n \"guest_execution_log\",\n \"guest_executions\",\n \"guided_checklist_run\",\n \"heatmap_save\",\n \"hindsight_enrollment\",\n \"hindsight_finding\",\n \"hindsight_regression_case\",\n \"hindsight_replay\",\n \"hindsight_replay_step\",\n \"hindsight_review\",\n \"hr_access_audit\",\n \"hr_access_role\",\n \"hr_accommodation_request\",\n \"hr_ai_evidence\",\n \"hr_alert_routing_rule\",\n \"hr_application\",\n \"hr_approval_authority\",\n \"hr_approval_delegation\",\n \"hr_asset\",\n \"hr_asset_assignment\",\n \"hr_attendance_exception\",\n \"hr_auto_close_rule\",\n \"hr_availability\",\n \"hr_background_check\",\n \"hr_benefits_event\",\n \"hr_calculation_snapshot\",\n \"hr_candidate\",\n \"hr_candidate_conversion\",\n \"hr_candidate_message\",\n \"hr_careers_portal\",\n \"hr_checklist_item\",\n \"hr_checklist_run\",\n \"hr_checklist_template\",\n \"hr_checklist_template_item\",\n \"hr_compensation\",\n \"hr_corrective_action\",\n \"hr_course\",\n \"hr_course_version\",\n \"hr_credential\",\n \"hr_crew\",\n \"hr_deduction_code\",\n \"hr_department\",\n \"hr_derived_grant\",\n \"hr_disposition_event\",\n \"hr_earning_code\",\n \"hr_eeo_response\",\n \"hr_emergency_contact\",\n \"hr_employee\",\n \"hr_employee_private\",\n \"hr_employer_profile\",\n \"hr_employment\",\n \"hr_employment_pin\",\n \"hr_engagement\",\n \"hr_establishment\",\n \"hr_external_identity\",\n \"hr_field_policy\",\n \"hr_holiday\",\n \"hr_holiday_calendar\",\n \"hr_i9\",\n \"hr_i9_document\",\n \"hr_incident\",\n \"hr_incident_party\",\n \"hr_interview\",\n \"hr_interview_kit\",\n \"hr_job_title\",\n \"hr_jurisdiction\",\n \"hr_jurisdiction_rule\",\n \"hr_jurisdiction_rule_class\",\n \"hr_jurisdiction_rule_org_decision\",\n \"hr_jurisdiction_rule_test\",\n \"hr_kiosk_device\",\n \"hr_kiosk_session\",\n \"hr_labor_target\",\n \"hr_leave_case\",\n \"hr_leave_enrollment\",\n \"hr_leave_ledger\",\n \"hr_leave_policy\",\n \"hr_leave_request\",\n \"hr_legal_hold\",\n \"hr_legal_hold_item\",\n \"hr_location\",\n \"hr_new_hire_report\",\n \"hr_offer\",\n \"hr_opening\",\n \"hr_overtime_alert\",\n \"hr_overtime_alert_rule\",\n \"hr_overtime_preapproval\",\n \"hr_pay_group\",\n \"hr_pay_period\",\n \"hr_pay_period_employment\",\n \"hr_payroll_export\",\n \"hr_payroll_export_line\",\n \"hr_position_assignment\",\n \"hr_posting\",\n \"hr_posting_publication\",\n \"hr_provider_binding\",\n \"hr_provider_event\",\n \"hr_provisioning_result\",\n \"hr_punch\",\n \"hr_recalculation_batch\",\n \"hr_record_class\",\n \"hr_records_request\",\n \"hr_reference_check\",\n \"hr_reporting_line\",\n \"hr_requisition\",\n \"hr_restricted_note\",\n \"hr_retention_rule\",\n \"hr_role_assignment\",\n \"hr_schedule\",\n \"hr_schedule_change\",\n \"hr_schedule_guidance\",\n \"hr_schedule_template\",\n \"hr_schedule_template_shift\",\n \"hr_scorecard\",\n \"hr_separation\",\n \"hr_shift\",\n \"hr_shift_claim\",\n \"hr_staffing_requirement\",\n \"hr_survey\",\n \"hr_survey_invitation\",\n \"hr_survey_question\",\n \"hr_survey_response\",\n \"hr_tax_registration\",\n \"hr_tax_withholding\",\n \"hr_time_adjustment\",\n \"hr_training_assignment\",\n \"hr_training_attempt\",\n \"hr_transcript_entry\",\n \"hr_verification_letter_request\",\n \"hr_work_interval\",\n \"hr_workflow_binding\",\n \"hr_workflow_decision\",\n \"hr_workflow_definition\",\n \"hr_workflow_event\",\n \"hr_workflow_failure\",\n \"hr_workflow_flow_type\",\n \"hr_workflow_instance\",\n \"hr_workflow_step\",\n \"hr_workflow_step_definition\",\n \"hr_workweek\",\n \"html_extraction\",\n \"iam_access_audit\",\n \"iam_api_key\",\n \"iam_emergency_door_request\",\n \"iam_org_availability_key\",\n \"iam_read_lane_v2_rollout\",\n \"idempotency\",\n \"industry\",\n \"industry_curator\",\n \"infra_status\",\n \"ingest_runs\",\n \"integration_connection\",\n \"integration_connection_resource\",\n \"interview_decision_interview\",\n \"interview_decision_question\",\n \"interview_document_revision\",\n \"interview_hole\",\n \"interview_question\",\n \"interview_session\",\n \"interview_turn\",\n \"invitation\",\n \"invitation_code\",\n \"invitation_request\",\n \"io_comment\",\n \"io_contract\",\n \"io_import\",\n \"io_outbox\",\n \"item\",\n \"item_mastery\",\n \"judge_verdict\",\n \"jurisdiction_policy\",\n \"keyword_classification_queue\",\n \"kg_alert\",\n \"kg_chunk_entities\",\n \"kg_chunks\",\n \"kg_clusters\",\n \"kg_edges\",\n \"kg_entities\",\n \"kg_entity_aliases\",\n \"kg_suggestion_ack\",\n \"kg_sweep_queue\",\n \"kg_sweep_run\",\n \"kg_sweep_state\",\n \"kg_value_match\",\n \"knob_override\",\n \"knob_override_audit\",\n \"knob_rung_lock\",\n \"knob_scope_kind\",\n \"knob_write_door\",\n \"league_membership\",\n \"learn_doc\",\n \"library_doc\",\n \"lifecycle_archive\",\n \"lifecycle_archive_row\",\n \"lifecycle_audit\",\n \"lifecycle_entity_plan\",\n \"lifecycle_map_build\",\n \"lifecycle_reference_map\",\n \"lifecycle_run\",\n \"lifecycle_tier_ledger\",\n \"location\",\n \"mandate\",\n \"mandate_advance_batch_row\",\n \"mandate_binding\",\n \"mandate_candidate\",\n \"mandate_candidate_run\",\n \"mandate_candidate_run_payload\",\n \"mandate_goal_clauses\",\n \"mandate_observation\",\n \"mandate_reference\",\n \"mandate_scan\",\n \"mandate_treatment\",\n \"marketing_initiative\",\n \"masterwork_corpus_item\",\n \"masterwork_run\",\n \"masterwork_run_kind\",\n \"masterwork_source\",\n \"math_course_structure\",\n \"math_problem\",\n \"matrx_action_ledger\",\n \"mcp_config\",\n \"mcp_server\",\n \"mcp_user_conn\",\n \"media_capture_handoff\",\n \"media_catalog_setting\",\n \"media_library_item\",\n \"media_selection_item\",\n \"media_selection_job\",\n \"media_source_library\",\n \"meet_call_invite\",\n \"meet_chat_message\",\n \"meet_invitee\",\n \"meet_meeting\",\n \"meet_note\",\n \"meet_occurrence_override\",\n \"meet_participant\",\n \"meet_recording\",\n \"meet_transcript_segment\",\n \"membership\",\n \"membership_grant\",\n \"merge_field_provenance\",\n \"message\",\n \"message_template\",\n \"message_template_detail\",\n \"meta_excluded_schema\",\n \"meta_table_stats_history\",\n \"metadata_reserved_keys\",\n \"microservice_project\",\n \"migration_log\",\n \"mtx_media_heal_queue\",\n \"mtx_public_url_guard\",\n \"ner_shadow\",\n \"note\",\n \"note_folder\",\n \"notification\",\n \"notification_channel_preference\",\n \"notification_event_override\",\n \"notification_event_type\",\n \"notification_preference\",\n \"notification_submission\",\n \"notify_outsider_door_baseline\",\n \"oauth_handoff_claim\",\n \"opinion_clusters\",\n \"opinions\",\n \"ops_check_item\",\n \"ops_check_run\",\n \"ops_db_host_sample\",\n \"ops_issue_class\",\n \"ops_issue_event\",\n \"ops_proof_check\",\n \"ops_proof_run\",\n \"ops_proof_scenario\",\n \"org_admin_audit\",\n \"org_change_policy\",\n \"org_context_ledger\",\n \"org_industries\",\n \"org_member_control\",\n \"org_module_config\",\n \"org_plan\",\n \"organization\",\n \"organization_preferences\",\n \"organization_visibility_version\",\n \"output_feedback\",\n \"outreach_acceptance\",\n \"page_extraction_job\",\n \"page_extraction_page_run\",\n \"page_extraction_results\",\n \"page_extraction_runs\",\n \"page_intent_queue\",\n \"page_mapping_queue\",\n \"part_config\",\n \"part_config_sub\",\n \"party\",\n \"party_contact_point\",\n \"passkey_credential\",\n \"pb_claim_appeals_fd31de\",\n \"pb_insurance_claims_fd31de\",\n \"pc_article\",\n \"pc_episode\",\n \"pc_show\",\n \"pc_studio_run\",\n \"pc_studio_run_asset\",\n \"pdf_consolidation_log\",\n \"pdf_redaction_audit\",\n \"pdf_redaction_key_escrow\",\n \"permission_grant\",\n \"plan_cms_fill_item\",\n \"plan_cms_fill_job\",\n \"plan_entity\",\n \"plan_node\",\n \"plan_node_artifact\",\n \"plan_node_step\",\n \"plan_profile\",\n \"platform_action_request\",\n \"platform_actor_session\",\n \"platform_actor_token\",\n \"platform_actor_token_event\",\n \"platform_class_approval_by_arman\",\n \"platform_continued_access\",\n \"platform_cutover_census_run\",\n \"platform_cutover_evaluation_replaced\",\n \"platform_cutover_evaluation_write\",\n \"platform_cutover_seam\",\n \"platform_cutover_seam_measure\",\n \"platform_cutover_seam_press\",\n \"platform_dated_change\",\n \"platform_doors_only_pending_cutover\",\n \"platform_google_calendar_event_create_intent\",\n \"platform_google_task_create_intent\",\n \"platform_kernel_fingerprint_record\",\n \"platform_org_knob_override\",\n \"platform_outcome_event\",\n \"platform_outsider_consumer\",\n \"platform_provision_base_contract_pending\",\n \"platform_reachability\",\n \"platform_reachability_rebuild_pending\",\n \"platform_realtime_topic_prefix\",\n \"platform_reference_category\",\n \"platform_reference_declaration\",\n \"platform_repo\",\n \"platform_saved_view\",\n \"platform_schema\",\n \"platform_secure_delivery\",\n \"platform_share_link\",\n \"platform_strict_class_probe\",\n \"platform_user_knob_override\",\n \"podcast_race\",\n \"position\",\n \"processed_document\",\n \"processed_document_page\",\n \"product_capture_file\",\n \"product_capture_item\",\n \"product_capture_payload\",\n \"product_capture_product\",\n \"product_capture_question\",\n \"profile\",\n \"project\",\n \"prompt\",\n \"provider_account\",\n \"provider_account_credential\",\n \"provision\",\n \"provision_generate_target\",\n \"provision_grant\",\n \"provision_marker\",\n \"provision_rule_message\",\n \"provision_schema\",\n \"provision_shape_debt\",\n \"provision_spec\",\n \"provision_spec_grandfather\",\n \"provision_vocabulary\",\n \"provlock_recall_visits_all8u5\",\n \"purpose\",\n \"quiz_session\",\n \"rag_ingest_run\",\n \"rag_library_audit_log\",\n \"rate_limit_buckets\",\n \"reachability_pending\",\n \"recompute_queue\",\n \"record\",\n \"record_alias\",\n \"redaction_mapping\",\n \"research_analysis\",\n \"research_content\",\n \"research_context_bundle\",\n \"research_document\",\n \"research_intent\",\n \"research_keyword\",\n \"research_media\",\n \"research_source\",\n \"research_synthesis\",\n \"research_tag\",\n \"research_template\",\n \"research_topic\",\n \"retention_policy\",\n \"retrieval_audit\",\n \"review_queue\",\n \"route_manifest_entry\",\n \"row_version\",\n \"rulebook\",\n \"runtime_operation_stream\",\n \"runtime_operation_stream_batch\",\n \"sandbox_instance\",\n \"sch_agent_task\",\n \"sch_run\",\n \"sch_task\",\n \"sch_trigger\",\n \"schema_client_exposure\",\n \"schema_migration_ledger\",\n \"schema_migration_legacy\",\n \"schema_migration_slot_grandfather\",\n \"schema_templates\",\n \"scope\",\n \"scope_association_suggestion\",\n \"scope_dataset_instance\",\n \"scope_door_registry\",\n \"scope_item_value_suggestion\",\n \"scope_suggestion\",\n \"scope_type\",\n \"scrape_domain\",\n \"scrape_domain_settings\",\n \"scrape_failure_log\",\n \"scrape_parsed_page\",\n \"scrape_path_override\",\n \"scrape_path_pattern\",\n \"scrape_retry_queue\",\n \"search_item\",\n \"seo_ai_capability\",\n \"seo_ai_visibility_citation\",\n \"seo_ai_visibility_claim\",\n \"seo_ai_visibility_panel\",\n \"seo_ai_visibility_response\",\n \"seo_ai_visibility_signal\",\n \"seo_backlink\",\n \"seo_backlink_change_event\",\n \"seo_backlink_dimension_snapshot\",\n \"seo_backlink_observation\",\n \"seo_backlink_snapshot\",\n \"seo_change_assessment\",\n \"seo_change_event\",\n \"seo_change_item\",\n \"seo_change_metric\",\n \"seo_change_set\",\n \"seo_change_theory\",\n \"seo_collection_run\",\n \"seo_competitor\",\n \"seo_competitor_observation\",\n \"seo_competitor_opportunity\",\n \"seo_coverage_mention\",\n \"seo_coverage_tracker\",\n \"seo_dimension_value_matcher\",\n \"seo_engine_schedule\",\n \"seo_geo_place\",\n \"seo_gsc_dig_rule\",\n \"seo_keyword\",\n \"seo_keyword_class_rule\",\n \"seo_keyword_edge\",\n \"seo_keyword_facet\",\n \"seo_keyword_market\",\n \"seo_keyword_market_observation\",\n \"seo_keyword_place\",\n \"seo_keyword_saved_view\",\n \"seo_keyword_topic\",\n \"seo_landscape_brief\",\n \"seo_link_gap_domain\",\n \"seo_link_gap_match\",\n \"seo_map_facet\",\n \"seo_map_facet_value\",\n \"seo_map_topic\",\n \"seo_page_measurement_health\",\n \"seo_page_performance\",\n \"seo_pr_moment\",\n \"seo_provider_call\",\n \"seo_provider_task\",\n \"seo_rank_observation\",\n \"seo_rank_target\",\n \"seo_raw_payload\",\n \"seo_referring_domain_profile\",\n \"seo_reputation_case\",\n \"seo_search_performance_daily\",\n \"seo_serp_mention\",\n \"seo_serp_opportunity\",\n \"seo_serp_result\",\n \"seo_serp_snapshot\",\n \"seo_site_geo_area\",\n \"seo_site_keyword_offering\",\n \"seo_site_keyword_value\",\n \"seo_site_offering_value\",\n \"seo_site_topic_value\",\n \"seo_site_value_combo\",\n \"seo_site_value_worth\",\n \"seo_site_vocabulary\",\n \"seo_source_request\",\n \"seo_starter_pack\",\n \"seo_starter_pack_item\",\n \"seo_story_angle\",\n \"seo_topic\",\n \"seo_topical_map\",\n \"seo_tracker_story\",\n \"seo_web_analytics_daily\",\n \"share_link\",\n \"shareable_resource_registry\",\n \"shared_canvas_item\",\n \"short_link\",\n \"shortcut_category\",\n \"sign_in_fk_legacy\",\n \"skill\",\n \"skill_category\",\n \"skill_detail\",\n \"skill_render_definition\",\n \"sms_consent\",\n \"sms_conversation\",\n \"sms_message\",\n \"sms_message_media\",\n \"sms_notification\",\n \"sms_notification_preference\",\n \"sms_phone_number\",\n \"sms_rate_limits\",\n \"sms_webhook_logs\",\n \"soft_delete_cascade_job\",\n \"soft_delete_edge\",\n \"source_authority\",\n \"space_payload\",\n \"stage_ref_kind\",\n \"stamped_write_table\",\n \"structure\",\n \"structured_list\",\n \"studio_cleaned_segments\",\n \"studio_concept_items\",\n \"studio_documents\",\n \"studio_module_segments\",\n \"studio_raw_segments\",\n \"studio_recording_chunks\",\n \"studio_recording_segments\",\n \"studio_run\",\n \"studio_session\",\n \"studio_session_settings\",\n \"study_attempt\",\n \"study_goal\",\n \"study_media\",\n \"study_plan\",\n \"study_plan_block\",\n \"study_plan_day\",\n \"study_reminder_context\",\n \"study_reminder_delivery\",\n \"study_session\",\n \"study_source_chunk\",\n \"study_streak\",\n \"study_structured_section\",\n \"superseded_policy\",\n \"surface\",\n \"system_announcement\",\n \"system_context_item\",\n \"system_error\",\n \"system_orgs\",\n \"system_write_failure\",\n \"t13_backfill_ledger\",\n \"t13_default_ledger\",\n \"t13_row_column_events\",\n \"tag\",\n \"task\",\n \"task_user_state\",\n \"taxonomy_node\",\n \"team\",\n \"template_context_items\",\n \"template_scope_types\",\n \"templates\",\n \"test_handset_inbox\",\n \"test_handset_verification\",\n \"thread\",\n \"tool\",\n \"tool_binding\",\n \"tool_bundle\",\n \"tool_call\",\n \"tool_definition_version\",\n \"tool_executor\",\n \"tool_surface_defaults\",\n \"tool_test_sample\",\n \"tool_ui\",\n \"tool_ui_incident\",\n \"tool_ui_version\",\n \"topic_placement_queue\",\n \"transcript\",\n \"trigger_event\",\n \"udt_dataset_fields\",\n \"udt_dataset_row_versions\",\n \"udt_dataset_rows\",\n \"udt_dataset_template\",\n \"udt_dataset_template_fields\",\n \"udt_document\",\n \"udt_document_snapshot\",\n \"udt_structured_list_items\",\n \"udt_workbook_snapshot\",\n \"ui_client\",\n \"ui_surface_agent_pref\",\n \"ui_surface_agent_role\",\n \"ui_surface_client_tool\",\n \"ui_surface_config\",\n \"ui_surface_item_type\",\n \"ui_surface_value\",\n \"ui_surface_write_target\",\n \"univer_payload\",\n \"unsubscribe_token\",\n \"uploads_inflight\",\n \"user\",\n \"user_achievement\",\n \"user_active_context\",\n \"user_analysis_preference\",\n \"user_email_preference\",\n \"user_entity_state\",\n \"user_feedback\",\n \"user_follows\",\n \"user_form_profile\",\n \"user_markdown_sample\",\n \"user_memory\",\n \"user_preference\",\n \"user_profile\",\n \"user_secret\",\n \"user_secret_audit\",\n \"user_secret_grant\",\n \"user_stat\",\n \"user_storage_usage\",\n \"user_surface_state\",\n \"vault_fill_approvals\",\n \"vault_fill_devices\",\n \"vault_fill_nonces\",\n \"visibility_cache\",\n \"visibility_epoch\",\n \"voice\",\n \"war_room\",\n \"wbx_demo\",\n \"wbx_guidance\",\n \"wbx_highlight\",\n \"wbx_pattern\",\n \"wbx_recipe\",\n \"wbx_screenshot\",\n \"wbx_seo_audit\",\n \"wc_claim\",\n \"wc_impairment_definition\",\n \"wc_injury\",\n \"wc_report\",\n \"web_analysis_item\",\n \"web_brand\",\n \"web_brand_asset\",\n \"web_brand_offering\",\n \"web_business_fact\",\n \"web_business_location\",\n \"web_channel_analytics_daily\",\n \"web_crawl_event\",\n \"web_crawl_preset\",\n \"web_crawl_schedule\",\n \"web_crawl_session\",\n \"web_crawl_url\",\n \"web_discovered_item\",\n \"web_finding\",\n \"web_gsc_page_stat\",\n \"web_link_edge\",\n \"web_listing_publisher\",\n \"web_location_listing\",\n \"web_news_item\",\n \"web_offering_template\",\n \"web_page\",\n \"web_page_content\",\n \"web_page_evidence\",\n \"web_page_sitemap\",\n \"web_property\",\n \"web_provider\",\n \"web_result\",\n \"web_screenshot\",\n \"web_site\",\n \"web_site_endpoint_rule\",\n \"web_site_item_config\",\n \"web_site_offering\",\n \"web_sitemap\",\n \"web_snapshot\",\n \"web_tag_manager_snapshot\",\n \"web_voice_fingerprint\",\n \"web_youtube_video\",\n \"webhook_deliveries\",\n \"webhook_dispatch_state\",\n \"webhooks\",\n \"wf_node_data_slot\",\n \"work_claim\",\n \"work_item\",\n \"workbook\",\n \"worker_heartbeat\",\n \"workflow\",\n \"workflow_card\",\n \"workflow_checkpoint\",\n \"workflow_comparison\",\n \"workflow_definition_version\",\n \"workflow_idempotency\",\n \"workflow_job\",\n \"workflow_node_events\",\n \"workflow_node_outcome\",\n \"workflow_plan\",\n \"workflow_plan_event\",\n \"workflow_plan_sample\",\n \"workflow_recovery_audit\",\n \"workflow_run\",\n \"workflow_run_cost\",\n \"workflow_run_facts\",\n \"workflow_run_log\",\n \"workflow_runtime_surface\",\n \"workflow_template\",\n \"workflow_trigger\",\n \"workflow_trigger_fire\",\n \"workflow_work_item\",\n \"working_document\",\n \"write_guard_key\",\n \"youtube_quota_day\",\n \"youtube_search\",\n \"youtube_video\",\n] as const;\n\nexport type StoreRefusalCode = (typeof STORE_REFUSAL_CODES)[number][\"code\"];\nexport type StoreDoorName = (typeof STORE_DOORS)[number][\"name\"];\nexport type EntityToken = (typeof ENTITY_TOKENS)[number];\nexport type KernelTableName = (typeof KERNEL_TABLES)[number][\"name\"];\n","// src/templates/validate.ts — @ai-matrx/records (templates, internal)\n//\n// THE QUALITY GATE'S Q1 AND Q2, AS CODE — and the pieces the installer shares with it.\n//\n// resolveRelativeDates(spec, today) every \"@today±N…\" token → the store's date/moment text\n// storeAggregate(...) custom.record_aggregate over seed rows, its semantics exactly\n// toUseCase(spec) the five UseCase singulars, derived (never stated twice)\n// validateTemplate(spec, {agents}) Q1 law/shape/graph + Q2 capability, by sentence\n//\n// The mirrors were written from the store's own bodies, read on the clone 2026-10-02:\n// custom.agg_sql / agg_value_sql / record_filter_sql / dashboard_window_sql (aggregates and\n// filters), custom._table_dimensions_infer / _table_dimensions_check (Dimensions),\n// custom.doc_tokens / doc_render_body (merge fields), custom.portal_declare (names_via),\n// custom.io_import_begin (imports). A mirror that disagrees with its door is a defect in\n// the mirror: fix it here, never loosen a template to pass it.\n\nimport { tableSettingsProblems } from \"./confidential\";\nimport { extrasProblems } from \"./extras\";\nimport { DECLARABLE_FIELD_KINDS, PARITY_FIELD_TYPES, STORE_DOORS } from \"../store.generated\";\nimport type { AggregateFilter, AggregateMeasure } from \"../aggregate\";\nimport type { UseCase, UseCaseTable } from \"../use-cases/types\";\nimport { validateUseCase, type UseCaseProblem } from \"../use-cases/validate\";\nimport { findBannedLabel } from \"../use-cases/placeholders\";\n// payloads.ts holds the booking-columns check the validator also asks;\n// it imports nothing from here.\nimport { bookingColumnsProblem } from \"./payloads\";\nimport {\n CAPABILITY_WORDS,\n CHOICE_COLORS,\n ENTITY_REFERENCE_KINDS,\n DEFAULT_TEMPLATE_AGENT,\n INDUSTRY_GROUPS,\n RELATIVE_DATE,\n SHARED_BLOCKS,\n SHARED_BLOCK_IDS,\n STRENGTHS,\n TEACHES_FEATURES,\n TEMPLATE_AUDIENCES,\n TEMPLATE_JOBS,\n TEMPLATE_REFERENCE_DATE,\n TEMPLATE_SPEC_VERSION,\n TEMPLATE_VIEW_KINDS,\n type AgentSnapshotRow,\n type CapabilityWord,\n type SharedBlockId,\n type TemplateField,\n type TemplateSpec,\n type TemplateTable,\n type TemplateView,\n type WalkAction,\n type WalkMove,\n} from \"./types\";\n\n// ═════════════════════════════════════════════════════════════════════════════\n// Relative dates\n// ═════════════════════════════════════════════════════════════════════════════\n\nconst pad = (n: number, w = 2) => String(n).padStart(w, \"0\");\n\n/** The UTC offset (\"-04:00\") of a local wall-clock moment in an IANA zone. */\nexport function zoneOffset(localIso: string, timeZone: string): string {\n const [d, t = \"00:00\"] = localIso.split(\"T\");\n const [y, mo, da] = (d ?? \"\").split(\"-\").map(Number);\n const [h, mi] = t.split(\":\").map(Number);\n const guess = Date.UTC(y ?? 1970, (mo ?? 1) - 1, da ?? 1, h ?? 0, mi ?? 0);\n const read = (at: number) => {\n const part = new Intl.DateTimeFormat(\"en-US\", { timeZone, timeZoneName: \"longOffset\" })\n .formatToParts(new Date(at))\n .find((p) => p.type === \"timeZoneName\")?.value;\n const m = /GMT([+-])(\\d{2}):?(\\d{2})?/.exec(part ?? \"\");\n return m ? (m[1] === \"-\" ? -1 : 1) * (Number(m[2]) * 60 + Number(m[3] ?? 0)) : 0;\n };\n const minutes = read(guess - read(guess) * 60_000);\n const sign = minutes < 0 ? \"-\" : \"+\";\n return `${sign}${pad(Math.floor(Math.abs(minutes) / 60))}:${pad(Math.abs(minutes) % 60)}`;\n}\n\nfunction addToDay(today: string, sign: string, n: number, unit: string): string {\n const [y, m, d] = today.split(\"-\").map(Number) as [number, number, number];\n const k = sign === \"-\" ? -n : n;\n if (unit === \"d\" || unit === \"w\") {\n const at = new Date(Date.UTC(y, m - 1, d + (unit === \"w\" ? 7 * k : k)));\n return `${at.getUTCFullYear()}-${pad(at.getUTCMonth() + 1)}-${pad(at.getUTCDate())}`;\n }\n const months = unit === \"y\" ? 12 * k : k;\n const first = new Date(Date.UTC(y, m - 1 + months, 1));\n const last = new Date(Date.UTC(first.getUTCFullYear(), first.getUTCMonth() + 1, 0)).getUTCDate();\n return `${first.getUTCFullYear()}-${pad(first.getUTCMonth() + 1)}-${pad(Math.min(d, last))}`;\n}\n\nconst WEEKDAYS = [\"sun\", \"mon\", \"tue\", \"wed\", \"thu\", \"fri\", \"sat\"];\nconst WEEKDAY_NAMES = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nconst dayOfWeek = (day: string) => new Date(`${day}T00:00:00Z`).getUTCDay();\nconst shiftDays = (day: string, n: number) => addToDay(day, n < 0 ? \"-\" : \"+\", Math.abs(n), \"d\");\n\nfunction addBusinessDays(day: string, n: number): string {\n let d = day;\n let left = Math.abs(n);\n while (left > 0) {\n d = shiftDays(d, n < 0 ? -1 : 1);\n const w = dayOfWeek(d);\n if (w !== 0 && w !== 6) left -= 1;\n }\n return d;\n}\n\n/** One token → \"2026-10-08\" or \"2026-10-08T09:30:00-04:00\". `null` when it is not a token. */\nexport function resolveDateToken(token: string, today: string, timeZone: string): string | null {\n const m = RELATIVE_DATE.exec(token);\n if (!m) return null;\n let day = today;\n const anchor = m[1] ?? \"today\";\n if (anchor !== \"today\") {\n const name = anchor.replace(/^(last|next)-/, \"\");\n const monday = shiftDays(today, -((dayOfWeek(today) + 6) % 7));\n day = shiftDays(monday, (WEEKDAYS.indexOf(name) + 6) % 7 + (anchor.startsWith(\"last-\") ? -7 : anchor.startsWith(\"next-\") ? 7 : 0));\n }\n if (m[2]) {\n const n = Number(m[3]) * (m[2] === \"-\" ? -1 : 1);\n day = m[4] === \"b\" ? addBusinessDays(day, n) : addToDay(day, m[2], Number(m[3]), m[4] ?? \"d\");\n }\n if (m[5]) {\n const w = dayOfWeek(day);\n if (w === 6) day = shiftDays(day, 2);\n if (w === 0) day = shiftDays(day, 1);\n }\n if (m[6] === undefined) return day;\n const local = `${day}T${m[6]}:${m[7]}`;\n return `${local}:00${zoneOffset(local, timeZone)}`;\n}\n\n/** True when the token carries an explicit time of day. */\nexport function relativeHasTime(token: string): boolean {\n return RELATIVE_DATE.exec(token)?.[6] !== undefined;\n}\n\n/**\n * Every relative-date token anywhere in the spec, resolved against `today` (the install\n * day, \"YYYY-MM-DD\") in the business's time zone. Returns a copy; the input is untouched.\n */\nexport function resolveRelativeDates<T extends Pick<TemplateSpec, \"business\">>(spec: T, today: string): T {\n const tz = spec.business?.timezone || \"UTC\";\n const walk = (v: unknown): unknown => {\n if (typeof v === \"string\") return resolveDateToken(v, today, tz) ?? v;\n if (Array.isArray(v)) return v.map(walk);\n if (v && typeof v === \"object\") return Object.fromEntries(Object.entries(v).map(([k, x]) => [k, walk(x)]));\n return v;\n };\n return walk(spec) as T;\n}\n\n// ═════════════════════════════════════════════════════════════════════════════\n// custom.record_aggregate, mirrored\n// ═════════════════════════════════════════════════════════════════════════════\n\n/** An exact decimal as a fraction, so nothing is rounded (Postgres numeric is exact). */\ninterface Q {\n n: bigint;\n d: bigint;\n}\nconst gcd = (a: bigint, b: bigint): bigint => (b === 0n ? (a < 0n ? -a : a) : gcd(b, a % b));\nconst q = (n: bigint, d: bigint): Q => {\n if (d < 0n) [n, d] = [-n, -d];\n const g = gcd(n, d) || 1n;\n return { n: n / g, d: d / g };\n};\nconst qAdd = (a: Q, b: Q) => q(a.n * b.d + b.n * a.d, a.d * b.d);\nconst qCmp = (a: Q, b: Q) => (a.n * b.d === b.n * a.d ? 0 : a.n * b.d < b.n * a.d ? -1 : 1);\n\n/** `text::numeric` as Postgres reads it, or null when Postgres would refuse the cast. */\nexport function parseNumeric(text: string): Q | null {\n const m = /^\\s*([+-]?)(\\d*)(?:\\.(\\d*))?(?:[eE]([+-]?\\d+))?\\s*$/.exec(text);\n if (!m || (!m[2] && !m[3])) return null;\n const frac = m[3] ?? \"\";\n let n = BigInt(`${m[1] === \"-\" ? \"-\" : \"\"}${m[2] || \"0\"}${frac}` || \"0\");\n let d = 10n ** BigInt(frac.length);\n const e = Number(m[4] ?? 0);\n if (e > 0) n *= 10n ** BigInt(e);\n if (e < 0) d *= 10n ** BigInt(-e);\n return q(n, d);\n}\n\n/** Exact and terminating → a JS number, else null (the answer could not be written exactly). */\nfunction qToNumber(v: Q): number | null {\n let d = v.d;\n while (d % 2n === 0n) d /= 2n;\n while (d % 5n === 0n) d /= 5n;\n if (d !== 1n) return null;\n let k = 0n;\n while ((10n ** k) % v.d !== 0n) k += 1n;\n const neg = v.n < 0n;\n const scaled = ((neg ? -v.n : v.n) * 10n ** k) / v.d;\n const scale = Number(k);\n const s = scaled.toString().padStart(scale + 1, \"0\");\n return Number(`${neg ? \"-\" : \"\"}${scale ? `${s.slice(0, -scale)}.${s.slice(-scale)}` : s}`);\n}\n\n/** `custom.agg_value_sql`: the Value envelope's `value` when there is one, else the key; as TEXT (`->>`). */\nexport function storeText(v: unknown): string | null {\n if (v === undefined || v === null) return null;\n if (typeof v === \"object\" && !Array.isArray(v) && \"value\" in (v as object)) return storeText((v as { value: unknown }).value);\n if (typeof v === \"string\") return v;\n if (typeof v === \"number\") return numberText(v);\n if (typeof v === \"boolean\") return String(v);\n return JSON.stringify(v);\n}\n\n/** A JSON number as jsonb `->>` prints it: plain digits, never \"1e+21\" or \"1e-7\". */\nexport function numberText(n: number): string {\n const t = String(n);\n if (!/e/i.test(t)) return t;\n const m = /^(-?)(\\d)(?:\\.(\\d+))?e([+-]\\d+)$/i.exec(t);\n if (!m) return t;\n const digits = `${m[2]}${m[3] ?? \"\"}`;\n const exp = Number(m[4]) - (m[3]?.length ?? 0);\n if (exp >= 0) return `${m[1]}${digits}${\"0\".repeat(exp)}`;\n const pos = digits.length + exp;\n return pos > 0 ? `${m[1]}${digits.slice(0, pos)}.${digits.slice(pos)}` : `${m[1]}0.${\"0\".repeat(-pos)}${digits}`;\n}\n\n/** The day part of a stored date or moment (\"2026-10-05\"), or null. */\nfunction dayOfMoment(v: unknown): string | null {\n const t = storeText(v);\n return t && /^\\d{4}-\\d{2}-\\d{2}/.test(t) ? t.slice(0, 10) : null;\n}\n\n/** The value inside a Value envelope ({value: …}), or the value itself. */\nexport function unwrap(v: unknown): unknown {\n return v && typeof v === \"object\" && !Array.isArray(v) && \"value\" in (v as object) ? unwrap((v as { value: unknown }).value) : v;\n}\n\n/** A window bound (custom.dashboard_window_sql: `v_raw::timestamptz`, a bare date read in the session zone, UTC). */\nfunction boundMoment(raw: string): number | null {\n const text = raw.trim();\n if (!text) return null;\n const at = Date.parse(/^\\d{4}-\\d{2}-\\d{2}$/.test(text) ? `${text}T00:00:00Z` : text);\n return Number.isNaN(at) ? null : at;\n}\n\nexport interface SeedRow {\n key: string;\n values: Record<string, unknown>;\n archived?: boolean;\n}\n\n/** custom.record_filter_sql (flat map): scalar = TEXT equality, null = absent/JSON-null (never \"\"), object = half-open window. */\nexport function storeFilterMatches(row: SeedRow, filter: Record<string, AggregateFilter> | undefined, _timeZone: string): boolean {\n if (!filter) return true;\n return Object.entries(filter).every(([key, want]) => {\n const have = storeText(row.values[key]);\n if (want === null) return have === null;\n if (typeof want === \"object\") {\n // custom.dashboard_moment_sql: `nullif(value, '')::timestamptz` — a bare date is read in the\n // SESSION zone (UTC), not the organization's (that reading is agg_moment_sql's, for buckets).\n const at = have === null || have === \"\" ? null : boundMoment(have);\n if (at === null) return false;\n const w = want as { from?: string; to?: string };\n const from = w.from ? boundMoment(w.from) : null;\n const to = w.to ? boundMoment(w.to) : null;\n return (from === null || at >= from) && (to === null || at < to);\n }\n return have === String(want);\n });\n}\n\nexport type AggregateOutcome = { ok: true; value: number | null; exact: boolean } | { ok: false; says: string };\n\n/**\n * custom.record_aggregate for ONE measure over seed rows (live, non-archived), as the store\n * computes it: count(*); sum/avg/min/max/median over `nullif(text,'')::numeric` (a text that\n * is not a number is a refusal; no values at all is NULL, not 0); filled/empty/unique by\n * `nullif(text,'')`. Exact: an average that does not terminate is reported as inexact.\n */\n// ═════════════════════════════════════════════════════════════════════════════\n// Formula fields (custom.field_declare formula_text → custom.formula_parse / formula_eval)\n// ═════════════════════════════════════════════════════════════════════════════\n\n/** custom.formula_node_kinds(), the functions a formula may call (read on the clone 2026-10-03). */\nexport const FORMULA_FUNCTIONS = new Set([\n \"ABS\", \"AND\", \"ARRAYCOMPACT\", \"ARRAYJOIN\", \"AVERAGE\", \"BLANK\", \"CONCATENATE\", \"CONTAINS\", \"DATEADD\", \"DATEDIFF\",\n \"DATETIME_FORMAT\", \"DAY\", \"FIND\", \"IF\", \"ISBLANK\", \"LEFT\", \"LEN\", \"LOWER\", \"MAX\", \"MIN\", \"MONTH\", \"NOT\", \"OR\",\n \"REGEX_MATCH\", \"RIGHT\", \"ROUND\", \"SUBSTITUTE\", \"SUM\", \"SWITCH\", \"TODAY\", \"NOW\", \"TRIM\", \"UPPER\", \"WORKDAY\", \"YEAR\",\n]);\n\ntype FxTok = { t: \"ref\" | \"num\" | \"str\" | \"name\" | \"op\"; v: string };\nfunction fxTokens(text: string): FxTok[] | string {\n const out: FxTok[] = [];\n let i = 0;\n while (i < text.length) {\n const c = text[i]!;\n if (/\\s/.test(c)) i += 1;\n else if (c === \"{\") {\n const j = text.indexOf(\"}\", i);\n if (j < 0) return \"a { has no closing }\";\n out.push({ t: \"ref\", v: text.slice(i + 1, j).trim() });\n i = j + 1;\n } else if (c === \"'\" || c === '\"') {\n const j = text.indexOf(c, i + 1);\n if (j < 0) return \"a quoted word has no closing quote\";\n out.push({ t: \"str\", v: text.slice(i + 1, j) });\n i = j + 1;\n } else if (/[0-9.]/.test(c)) {\n const m = /^[0-9]*\\.?[0-9]+/.exec(text.slice(i))!;\n out.push({ t: \"num\", v: m[0] });\n i += m[0].length;\n } else if (/[A-Za-z_]/.test(c)) {\n const m = /^[A-Za-z_][A-Za-z_0-9]*/.exec(text.slice(i))!;\n out.push({ t: \"name\", v: m[0] });\n i += m[0].length;\n } else if (\"+-*/(),%\".includes(c)) {\n out.push({ t: \"op\", v: c });\n i += 1;\n } else return `\"${c}\" is not part of a formula`;\n }\n return out;\n}\n\ntype FxNode = { k: \"num\"; v: Q } | { k: \"str\"; v: string } | { k: \"ref\"; v: string } | { k: \"bin\"; op: string; a: FxNode; b: FxNode } | { k: \"neg\"; a: FxNode } | { k: \"call\"; f: string; args: FxNode[] };\n/** Parse a formula text, or say what is wrong with it. */\nexport function parseFormula(text: string): FxNode | string {\n const toks = fxTokens(text);\n if (typeof toks === \"string\") return toks;\n let p = 0;\n const peek = () => toks[p];\n const fail = (why: string): never => {\n throw new Error(why);\n };\n const expr = (): FxNode => {\n let a = term();\n while (peek()?.t === \"op\" && (peek()!.v === \"+\" || peek()!.v === \"-\")) {\n const op = toks[p++]!.v;\n a = { k: \"bin\", op, a, b: term() };\n }\n return a;\n };\n const term = (): FxNode => {\n let a = factor();\n while (peek()?.t === \"op\" && (peek()!.v === \"*\" || peek()!.v === \"/\" || peek()!.v === \"%\")) {\n const op = toks[p++]!.v;\n a = { k: \"bin\", op, a, b: factor() };\n }\n return a;\n };\n const factor = (): FxNode => {\n const tk = toks[p++];\n if (!tk) return fail(\"the formula ends too early\");\n if (tk.t === \"num\") return { k: \"num\", v: parseNumeric(tk.v)! };\n if (tk.t === \"str\") return { k: \"str\", v: tk.v };\n if (tk.t === \"ref\") return { k: \"ref\", v: tk.v };\n if (tk.t === \"op\" && tk.v === \"-\") return { k: \"neg\", a: factor() };\n if (tk.t === \"op\" && tk.v === \"(\") {\n const e = expr();\n if (toks[p++]?.v !== \")\") fail(\"a ( has no closing )\");\n return e;\n }\n if (tk.t === \"name\") {\n const f = tk.v.toUpperCase();\n if (!FORMULA_FUNCTIONS.has(f)) fail(`${tk.v} is not a formula function the store knows`);\n if (toks[p++]?.v !== \"(\") fail(`${f} is followed by its arguments in ( )`);\n const args: FxNode[] = [];\n if (peek()?.v !== \")\") {\n args.push(expr());\n while (peek()?.v === \",\") {\n p += 1;\n args.push(expr());\n }\n }\n if (toks[p++]?.v !== \")\") fail(`${f}( has no closing )`);\n return { k: \"call\", f, args };\n }\n return fail(`\"${tk.v}\" is out of place`);\n };\n try {\n const e = expr();\n if (p !== toks.length) return `\"${toks[p]!.v}\" is out of place`;\n return e;\n } catch (err) {\n return (err as Error).message;\n }\n}\n\n/** Every `{Label}` a formula reads. */\nexport function formulaRefs(n: FxNode): string[] {\n if (n.k === \"ref\") return [n.v];\n if (n.k === \"bin\") return [...formulaRefs(n.a), ...formulaRefs(n.b)];\n if (n.k === \"neg\") return formulaRefs(n.a);\n if (n.k === \"call\") return n.args.flatMap(formulaRefs);\n return [];\n}\n\n/**\n * custom.formula_eval for the part the gate mirrors exactly: + − × ÷ % (an empty value counts as\n * 0), ABS, and DATEDIFF (whole units, truncated toward zero). Anything else answers \"unsupported\",\n * and a question over it is refused rather than guessed.\n */\nexport function evalFormula(n: FxNode, valueOf: (label: string) => unknown): { ok: true; v: Q | null } | { ok: false; why: string } {\n const num = (x: FxNode): Q | { why: string } => {\n const r = evalFormula(x, valueOf);\n if (!r.ok) return { why: r.why };\n return r.v ?? q(0n, 1n);\n };\n switch (n.k) {\n case \"num\":\n return { ok: true, v: n.v };\n case \"str\":\n return { ok: false, why: \"it computes text\" };\n case \"ref\": {\n const t = storeText(valueOf(n.v));\n if (t === null || t === \"\") return { ok: true, v: null };\n const v = parseNumeric(t);\n return v ? { ok: true, v } : { ok: false, why: `{${n.v}} is not a number` };\n }\n case \"neg\": {\n const a = num(n.a);\n return \"why\" in a ? { ok: false, why: a.why } : { ok: true, v: q(-a.n, a.d) };\n }\n case \"bin\": {\n const a = num(n.a);\n const b = num(n.b);\n if (\"why\" in a) return { ok: false, why: a.why };\n if (\"why\" in b) return { ok: false, why: b.why };\n if (n.op === \"+\") return { ok: true, v: qAdd(a, b) };\n if (n.op === \"-\") return { ok: true, v: qAdd(a, q(-b.n, b.d)) };\n if (n.op === \"*\") return { ok: true, v: q(a.n * b.n, a.d * b.d) };\n if (b.n === 0n) return { ok: false, why: \"it divides by zero on a row\" };\n if (n.op === \"/\") return { ok: true, v: q(a.n * b.d, a.d * b.n) };\n return { ok: false, why: \"% is not mirrored\" };\n }\n case \"call\": {\n if (n.f === \"ABS\" && n.args.length === 1) {\n const a = num(n.args[0]!);\n return \"why\" in a ? { ok: false, why: a.why } : { ok: true, v: q(a.n < 0n ? -a.n : a.n, a.d) };\n }\n if (n.f === \"DATEDIFF\" && n.args.length === 3 && n.args[2]!.k === \"str\") {\n const ms = (x: FxNode) => (x.k === \"ref\" ? Date.parse(storeText(valueOf(x.v)) ?? \"\") : NaN);\n const a = ms(n.args[0]!);\n const b = ms(n.args[1]!);\n if (!Number.isFinite(a) || !Number.isFinite(b)) return { ok: false, why: \"DATEDIFF reads an empty or unreadable date on a row\" };\n const unit = { days: 86_400_000, hours: 3_600_000, minutes: 60_000 }[n.args[2]!.v];\n if (!unit) return { ok: false, why: \"DATEDIFF's unit is days, hours or minutes\" };\n return { ok: true, v: q(BigInt(Math.trunc((b - a) / unit)), 1n) };\n }\n return { ok: false, why: `${n.f} is not mirrored by the gate` };\n }\n }\n}\n\n/** A view's rows: its flat `filters` (equality, null, window) AND each `anyOf` (`where`: or of eq). */\nexport function viewMatches(row: SeedRow, view: { filters?: Record<string, AggregateFilter> | undefined; anyOf?: Record<string, string[]> | undefined }, timeZone: string): boolean {\n if (!storeFilterMatches(row, view.filters, timeZone)) return false;\n return Object.entries(view.anyOf ?? {}).every(([k, vals]) => {\n const t = storeText(row.values?.[k]);\n return t !== null && vals.includes(t);\n });\n}\n\nexport function storeAggregate(rows: SeedRow[], measure: AggregateMeasure, filter: Record<string, AggregateFilter> | undefined, timeZone: string): AggregateOutcome {\n const live = rows.filter((r) => !r.archived && storeFilterMatches(r, filter, timeZone));\n const op = measure.op;\n if (op === \"count\") return { ok: true, value: live.length, exact: true };\n if (!measure.key) return { ok: false, says: `A ${op} names the column it reads.` };\n const texts = live.map((r) => storeText(r.values[measure.key as string]));\n const present = texts.filter((t): t is string => t !== null && t !== \"\");\n if (op === \"filled\") return { ok: true, value: present.length, exact: true };\n if (op === \"empty\") return { ok: true, value: live.length - present.length, exact: true };\n if (op === \"unique\") return { ok: true, value: new Set(present).size, exact: true };\n const nums: Q[] = [];\n for (const t of present) {\n const v = parseNumeric(t);\n if (!v) return { ok: false, says: `\"${t}\" is not a number, so the store would refuse to ${op} \"${measure.key}\".` };\n nums.push(v);\n }\n if (!nums.length) return { ok: true, value: null, exact: true };\n let result: Q;\n if (op === \"sum\" || op === \"avg\") {\n result = nums.reduce(qAdd, q(0n, 1n));\n if (op === \"avg\") result = q(result.n, result.d * BigInt(nums.length));\n } else if (op === \"min\" || op === \"max\") {\n result = nums.reduce((a, b) => ((op === \"min\" ? qCmp(b, a) < 0 : qCmp(b, a) > 0) ? b : a));\n } else if (op === \"median\") {\n const s = [...nums].sort(qCmp);\n const mid = Math.floor(s.length / 2);\n result = s.length % 2 ? (s[mid] as Q) : q(qAdd(s[mid - 1] as Q, s[mid] as Q).n, qAdd(s[mid - 1] as Q, s[mid] as Q).d * 2n);\n } else return { ok: false, says: `\"${op}\" is not a measure the store computes.` };\n const value = qToNumber(result);\n return value === null ? { ok: true, value: Number(result.n) / Number(result.d), exact: false } : { ok: true, value, exact: true };\n}\n\n/** True when the JSON number `answer` is exactly `value` (no rounding either way). */\nfunction sameNumber(answer: number, value: number): boolean {\n const a = parseNumeric(String(answer));\n const b = parseNumeric(String(value));\n return !!a && !!b && qCmp(a, b) === 0;\n}\n\n// ═════════════════════════════════════════════════════════════════════════════\n// Field kinds\n// ═════════════════════════════════════════════════════════════════════════════\n\nconst BEHAVIOR_OF = new Map<string, string>([\n ...PARITY_FIELD_TYPES.map((t) => [t.parity_type as string, t.behavior as string] as [string, string]),\n ...DECLARABLE_FIELD_KINDS.map((k) => [k.kind as string, k.behavior as string] as [string, string]),\n [\"number\", \"range\"],\n [\"integer\", \"range\"],\n [\"decimal\", \"range\"],\n [\"float\", \"range\"],\n [\"long_text\", \"text\"],\n [\"string\", \"text\"],\n [\"text\", \"text\"],\n]);\nconst behaviorOf = (f: { parityType: string }) => BEHAVIOR_OF.get(f.parityType) ?? f.parityType;\nconst isDate = (f: { parityType: string }) => f.parityType === \"datetime\" || f.parityType === \"date\";\nconst isNumber = (f: { parityType: string }) => behaviorOf(f) === \"range\" && !isDate(f);\nconst isComputed = (f: { parityType: string }) => [\"formula\", \"lookup\", \"rollup\", \"autonumber\", \"created_time\", \"modified_time\"].includes(f.parityType);\nconst isChoice = (f: { parityType: string }) => [\"select\", \"multi_select\", \"list\"].includes(f.parityType);\nconst isRelation = (f: { parityType: string }) => behaviorOf(f) === \"relation\";\nconst SENSITIVITY_RANK = [\"public\", \"internal\", \"confidential\", \"restricted\"];\nconst CONTEXT_RANK = [\"include\", \"summarize\", \"on_request\", \"exclude\"];\n/** Stage names that say when something happened (their dates are never \"any\" without a reason). */\nexport const TIME_BOUND_STAGE = /\\b(?:no[- ]?show|completed?|done|seen|checked[- ]?in|arrived|delivered|shipped|paid|received|scheduled|booked|confirmed|dispatched|on[- ]site|in[- ]visit|overdue|in the chair|served|met|visited|visit|signed|closed|issued|sent|picked up|installed|first contact|contacted|demo(?: held| given| done)?|consult(?:ation)?|tour(?:ed)?|showing|shown|called|interview(?:ed)?|inspected|inspection)\\b/i;\n/** Stage names that end a record's journey. */\nconst TERMINAL_STAGE = /^(?:cancell?ed|no[- ]?show|lost|closed[- ]lost|declined|closed|withdrawn|fell off|rejected|void(?:ed)?|skipped|missed)$/i;\nconst CHART_BLOCK_KINDS = new Set([\"bar\", \"column\", \"line\", \"donut\"]);\nconst BUCKETS = [\"year\", \"quarter\", \"month\", \"week\", \"day\"];\nconst AGG_OPERATIONS = [\"count\", \"sum\", \"avg\", \"min\", \"max\", \"median\", \"filled\", \"empty\", \"unique\"];\nconst MEASURE_KEY = /^[a-zA-Z_][a-zA-Z0-9_]{0,62}$/;\n/** custom._field_document_for: a list link holds at most this many targets unless it declares relation_max. */\nconst STORE_LIST_RELATION_MAX = 25;\n\n/** The first of the field's own rules a value breaks, as a sentence; null when it obeys them all. */\nexport function ruleBreak(field: TemplateField, v: unknown): string | null {\n const t = storeText(v) ?? \"\";\n if (t === \"\") return null;\n if (field.choices?.length && !field.multi && typeof v === \"string\" && !field.choices.includes(v)) return `\"${v}\" is not one of \"${field.label}\"'s choices.`;\n for (const rule of field.rules ?? []) {\n if (rule.kind === \"min\" || rule.kind === \"max\") {\n const n = parseNumeric(t);\n const bound = parseNumeric(String(rule.value));\n if (n && bound && (rule.kind === \"min\" ? qCmp(n, bound) < 0 : qCmp(n, bound) > 0)) return `${t} breaks \"${field.label}\"'s rule: at ${rule.kind === \"min\" ? \"least\" : \"most\"} ${rule.value}.`;\n } else if (rule.kind === \"length\") {\n if (rule.value !== undefined && t.length > Number(rule.value)) return `\"${t}\" is longer than \"${field.label}\" allows (${rule.value}).`;\n if (rule.min !== undefined && t.length < rule.min) return `\"${t}\" is shorter than \"${field.label}\" allows (${rule.min}).`;\n } else if (rule.kind === \"pattern\" && rule.value !== undefined) {\n try {\n if (!new RegExp(String(rule.value)).test(t)) return `\"${t}\" does not match \"${field.label}\"'s own pattern.`;\n } catch {\n return `\"${field.label}\"'s pattern is not a pattern.`;\n }\n }\n }\n return null;\n}\n\n// ═════════════════════════════════════════════════════════════════════════════\n// Shared blocks and the derived UseCase\n// ═════════════════════════════════════════════════════════════════════════════\n\n/** A shared block's table as this template seeds it. */\nexport function blockTable(block: SharedBlockId, rows: TemplateSpec[\"sharedBlocks\"][number][\"rows\"]): TemplateTable {\n const b = SHARED_BLOCKS[block];\n return {\n token: b.table,\n name: b.name,\n labelSingular: b.labelSingular,\n labelPlural: b.labelPlural,\n type: \"entity\",\n display: \"grid\",\n weight: \"light\",\n ordered: false,\n titleField: b.titleField,\n describes: b.describes,\n fields: b.fields.map(({ sameAs: _sameAs, ...f }) => ({ ...f }) as TemplateField),\n rows,\n };\n}\n\n/** The template's own tables plus every shared block it seeds. */\nexport function allTables(spec: Pick<TemplateSpec, \"tables\" | \"sharedBlocks\">): TemplateTable[] {\n return [...(spec.tables ?? []), ...(spec.sharedBlocks ?? []).filter((s) => SHARED_BLOCKS[s.block]).map((s) => blockTable(s.block, s.rows ?? []))];\n}\n\nconst MERGE_TOKEN = /\\{\\{\\s*([^}]*?)\\s*\\}\\}/g;\n\nfunction plainFilter(filter: Record<string, AggregateFilter> | undefined): string | undefined {\n if (!filter) return undefined;\n return Object.entries(filter)\n .map(([k, v]) => (v === null ? `${k} is empty` : typeof v === \"object\" ? `${k} is in the window` : `${k} is ${String(v)}`))\n .join(\" and \");\n}\n\ntype Partial5 = Partial<Pick<UseCase, \"form\" | \"pipeline\" | \"dashboardQuestion\" | \"documentTemplate\" | \"notificationRule\">>;\n\nfunction deriveSingulars(spec: TemplateSpec): Partial5 {\n const out: Partial5 = {};\n const form = spec.forms?.[0];\n if (form) out.form = form;\n const stages = spec.extras?.find((e) => e.kind === \"stage_rules\");\n if (stages?.kind === \"stage_rules\") {\n const field = allTables(spec).find((t) => t.token === stages.table)?.fields.find((f) => f.key === stages.stageField);\n out.pipeline = {\n token: stages.token,\n name: stages.name,\n describes: stages.movesMessage ?? stages.name,\n table: stages.table,\n stageField: stages.stageField,\n stages: (field?.choices ?? Object.keys(stages.stages ?? {})).map((key) => ({ key, label: key, describes: stages.stages?.[key] ?? \"\" })),\n };\n }\n const q6 = spec.agent?.question;\n if (q6?.expect) {\n const op = q6.expect.measure.op;\n out.dashboardQuestion = {\n question: q6.ask,\n whyItMatters: q6.whyItMatters,\n table: q6.expect.table,\n aggregate: ([\"count\", \"sum\", \"avg\", \"min\", \"max\"].includes(op) ? op : \"count\") as \"count\",\n ...(q6.expect.measure.key ? { of: q6.expect.measure.key } : {}),\n ...(plainFilter(q6.expect.filter) ? { filter: plainFilter(q6.expect.filter) as string } : {}),\n answerUnit: q6.expect.unit,\n };\n }\n const doc = spec.extras?.find((e) => e.kind === \"document\");\n if (doc?.kind === \"document\") {\n const fields = allTables(spec).find((t) => t.token === doc.table)?.fields ?? [];\n const keys = [...new Set([...`${doc.title}\\n${doc.body}`.matchAll(MERGE_TOKEN)].map((m) => m[1] ?? \"\"))];\n out.documentTemplate = {\n token: doc.token,\n name: doc.name,\n describes: doc.describes,\n table: doc.table,\n title: doc.title,\n body: doc.body,\n mergeFields: keys.map((key) => ({ key, from: key, describes: fields.find((f) => f.key === key)?.label ?? key })),\n };\n }\n const note = spec.extras?.find((e) => e.kind === \"notification\");\n if (note?.kind === \"notification\") {\n out.notificationRule = { token: note.token, name: note.name, describes: note.describes, when: note.when, audience: note.audience, channel: note.channel, message: note.message };\n }\n return out;\n}\n\n/** A template seen as a use case: the five singulars are there when the template carries them. */\nexport type DerivedUseCase = Omit<UseCase, \"form\" | \"pipeline\" | \"dashboardQuestion\" | \"documentTemplate\" | \"notificationRule\"> & Partial5;\n\n/**\n * The template as a use case, for every existing use-case consumer: the singulars come from\n * forms[0], the first stage_rules, the agent's question, the first document and the first\n * notification WHEN the template has them. A template owes at least two extras (handoff §5),\n * not one of each kind, so a missing singular is simply absent — never an error.\n */\nexport function toUseCase(spec: TemplateSpec): DerivedUseCase {\n const singulars = deriveSingulars(spec);\n return {\n id: spec.id,\n useCase: spec.useCase,\n industry: spec.vertical,\n business: spec.business,\n cleanupTag: spec.cleanupTag,\n tables: allTables(spec) as UseCaseTable[],\n relationships: spec.relationships,\n provenance: spec.provenance,\n ...singulars,\n };\n}\n\n/** validateUseCase over the derived use case, minus the \"a use case owes a …\" lines a template does not owe. */\nexport function useCaseProblemsOf(spec: TemplateSpec): UseCaseProblem[] {\n return validateUseCase(toUseCase(spec) as unknown as UseCase).problems.filter((p) => !SINGULAR_OWES.has(p.at));\n}\n\n// ═════════════════════════════════════════════════════════════════════════════\n// Q2 — who provides each capability word\n// ═════════════════════════════════════════════════════════════════════════════\n\n/**\n * The layouts records-ui draws today — a MIRROR of `VIEW_LAYOUTS` in\n * `apps/shared/records-ui/src/views.ts` (records cannot import records-ui). A test reads\n * that file and fails when the two disagree.\n */\nexport const RECORDS_UI_VIEW_LAYOUTS = [\"grid\", \"kanban\", \"calendar\", \"gallery\", \"timeline\", \"list\"] as const;\n/** Mirror of records-ui `CalendarMode` (CalendarView.tsx). */\nexport const RECORDS_UI_CALENDAR_MODES = [\"month\", \"week\", \"day\", \"list\"] as const;\n/**\n * Field surfaces records-ui draws beyond the plain kinds, each checked against records-ui by\n * the suite: `rating` (a number with format rating — FieldFormatPicker), `signature` (drawn on\n * the form and seen as a drawing — docs.ts / SignBlock).\n */\nexport const RECORDS_UI_FIELD_SURFACES = [\"rating\", \"signature\"] as const;\n\nconst DOOR_FOR: Partial<Record<CapabilityWord, string>> = {\n form: \"form_declare\",\n // form_declare takes {field, ask, help, required} per question (read on the clone).\n \"form.question_text\": \"form_declare\",\n booking: \"booking_declare\",\n portal: \"portal_declare\",\n dashboard: \"dashboard_declare\",\n // dashboard_block_normalize accepts a per-block table_id.\n \"dashboard.multi_table\": \"dashboard_block_normalize\",\n drill_down: \"drill_resolve\",\n dimensions: \"table_dimensions_set\",\n digest: \"subscription_declare\",\n checklist: \"checklist_declare\",\n document: \"doc_template_save\",\n \"document.esign\": \"doc_sign\",\n notification: \"rule_declare\",\n stage_rules: \"pipeline_declare\",\n row_action: \"action_declare\",\n \"import.upsert\": \"io_import_begin\",\n \"archive.restore\": \"record_restore\",\n agent: \"agent_context\",\n \"view.kanban.swimlanes\": \"view_declare\",\n};\n\n/** Words nobody provides yet, and who owes them. */\nconst OWED_BY: Partial<Record<CapabilityWord, string>> = {\n automation: \"lane 11\",\n};\n\nexport interface CapabilityStatus {\n word: string;\n provided: boolean;\n by: string;\n}\n\nconst STORE_DOOR_NAMES = new Set(STORE_DOORS.map((d) => d.name as string));\nconst STORE_FIELD_KINDS = new Set<string>(BEHAVIOR_OF.keys());\n\nexport function capabilityStatus(word: string): CapabilityStatus {\n if (!(CAPABILITY_WORDS as readonly string[]).includes(word)) return { word, provided: false, by: \"nobody — not a capability word\" };\n const w = word as CapabilityWord;\n const owed = OWED_BY[w];\n if (owed) return { word, provided: false, by: owed };\n if (w === \"view.calendar.month\") {\n return (RECORDS_UI_CALENDAR_MODES as readonly string[]).includes(\"month\")\n ? { word, provided: true, by: \"records-ui CalendarView (month)\" }\n : { word, provided: false, by: \"lane 10\" };\n }\n if (w.startsWith(\"view.\") && w !== \"view.kanban.swimlanes\") {\n return (RECORDS_UI_VIEW_LAYOUTS as readonly string[]).includes(w.slice(5))\n ? { word, provided: true, by: \"records-ui VIEW_LAYOUTS\" }\n : { word, provided: false, by: \"lane 10\" };\n }\n if (w.startsWith(\"field.\")) {\n const kind = w.slice(6);\n if ((RECORDS_UI_FIELD_SURFACES as readonly string[]).includes(kind)) return { word, provided: true, by: \"records-ui field surfaces\" };\n return STORE_FIELD_KINDS.has(kind) ? { word, provided: true, by: \"custom.field_kinds()\" } : { word, provided: false, by: \"lane 10\" };\n }\n if (w === \"seed.attachments\") {\n return STORE_DOOR_NAMES.has(\"file_kernel_id\") && STORE_DOOR_NAMES.has(\"record_write\")\n ? { word, provided: true, by: \"plan.ts attachments step (custom.file_kernel_id + custom.record_write)\" }\n : { word, provided: false, by: \"the chair\" };\n }\n if (w === \"choice.colors\") return { word, provided: true, by: \"records-ui choiceLooks (display_format choices)\" };\n const door = DOOR_FOR[w];\n if (door) return STORE_DOOR_NAMES.has(door) ? { word, provided: true, by: `custom.${door}` } : { word, provided: false, by: \"the chair\" };\n return { word, provided: false, by: \"nobody — no provider mapped\" };\n}\n\n/** Every capability the spec USES. `requires` must equal this set — no less, no more. */\nexport function capabilitiesUsed(spec: TemplateSpec): Set<CapabilityWord> {\n const used = new Set<CapabilityWord>();\n for (const view of spec.views ?? []) {\n used.add(`view.${view.kind}` as CapabilityWord);\n if (view.kind === \"kanban\" && view.swimlaneBy) used.add(\"view.kanban.swimlanes\");\n if (view.kind === \"calendar\" && view.span === \"month\") used.add(\"view.calendar.month\");\n if (view.kind === \"gallery\") used.add(\"seed.attachments\");\n }\n if (spec.teaches === \"gallery\") used.add(\"seed.attachments\");\n for (const table of allTables(spec)) {\n for (const field of table.fields ?? []) {\n const word = `field.${field.parityType}`;\n if ((CAPABILITY_WORDS as readonly string[]).includes(word)) used.add(word as CapabilityWord);\n if (field.choiceColors && Object.keys(field.choiceColors).length) used.add(\"choice.colors\");\n if (field.format === \"rating\") used.add(\"field.rating\");\n if (field.format === \"signature\") used.add(\"field.signature\");\n }\n }\n if (spec.forms?.length) {\n used.add(\"form\");\n used.add(\"form.question_text\");\n }\n if (spec.dimensions?.length) used.add(\"dimensions\");\n if (spec.agent) used.add(\"agent\");\n for (const extra of spec.extras ?? []) {\n if (extra.kind === \"dashboard\") {\n used.add(\"dashboard\");\n if (extra.blocks.some((b) => b.table && b.table !== extra.table)) used.add(\"dashboard.multi_table\");\n } else if (extra.kind === \"document\") {\n used.add(\"document\");\n if (extra.signature) used.add(\"document.esign\");\n } else used.add(extra.kind as CapabilityWord);\n }\n for (const step of spec.walk ?? []) {\n if (step?.action?.kind === \"import\") used.add(\"import.upsert\");\n if (step?.action?.kind === \"archive\" || step?.action?.kind === \"restore\") used.add(\"archive.restore\");\n }\n return used;\n}\n\n// ═════════════════════════════════════════════════════════════════════════════\n// G6 — no real people\n// ═════════════════════════════════════════════════════════════════════════════\n\n/** The designated test numbers (aidream/designated_test_recipients.py): real handsets, never seed data. */\nexport const DESIGNATED_REAL_NUMBERS = [\"9498072145\", \"9496662578\", \"9497027626\"] as const;\n\nconst DIGIT_ZEROS = [0x0660, 0x06f0, 0x07c0, 0x0966, 0x09e6, 0x0a66, 0x0ae6, 0x0b66, 0x0be6, 0x0c66, 0x0ce6, 0x0d66, 0x0e50, 0x0ed0, 0x0f20, 0x1040, 0x17e0, 0x1810, 0xff10];\n\n/** Unicode digits → ASCII, every dash/hyphen → \"-\", every odd space → \" \" (so a disguised number reads as one). */\nexport function normalizeForPhones(text: string): string {\n return text\n .normalize(\"NFKC\")\n .replace(/\\p{Nd}/gu, (c) => {\n const cp = c.codePointAt(0) ?? 48;\n const zero = DIGIT_ZEROS.find((z) => cp >= z && cp <= z + 9);\n return zero === undefined ? c : String(cp - zero);\n })\n .replace(/[\\u2010-\\u2015\\u2212\\ufe58\\ufe63\\uff0d]/g, \"-\")\n .replace(/[\\u00a0\\u2000-\\u200b\\u202f\\u205f\\u3000]/g, \" \");\n}\n\n/** NANP with separators (or parentheses) — what a phone looks like inside prose. */\nconst NANP_IN_TEXT = /(?:\\+?1[\\s.-]?)?(?:\\((\\d{3})\\)[\\s.-]?|\\b(\\d{3})[\\s.-])(\\d{3})[\\s.-](\\d{4})\\b/g;\n/** NANP in a phone FIELD, where bare digits are a phone too. */\nconst NANP_IN_FIELD = /(?:\\+?1[\\s.-]?)?\\(?\\b(\\d{3})\\)?[\\s.-]?(\\d{3})[\\s.-]?(\\d{4})\\b/g;\n/** Any international number written with a country code other than +1. */\nconst INTL = /\\+(?!1\\b)(\\d{1,3})[\\s.-]?\\(?\\d[\\d\\s().-]{5,}\\d/g;\n/** Ofcom's drama ranges (UK numbers reserved for fiction), without spaces, after +44 or 0. */\nconst OFCOM_DRAMA = /^(?:207946(0\\d{3})|1214960\\d{3}|1314960\\d{3}|1134960\\d{3}|1614960\\d{3}|1174960\\d{3}|2890180\\d{3}|29\\d{2}0180\\d{3}|7700900\\d{3})$/;\n\nfunction nanpBad(area: string, exchange: string, line: string): boolean {\n const n = Number(line);\n return exchange !== \"555\" || n < 100 || n > 199 || (DESIGNATED_REAL_NUMBERS as readonly string[]).includes(`${area}${exchange}${line}`);\n}\n\n/**\n * Every number in `text` that is not fictional: a NANP number outside 555-0100…0199 (or a\n * designated real handset), or an international number outside the UK's Ofcom drama ranges.\n * `phoneField` = the text IS a phone value, so bare digits count; in prose a number needs\n * separators, so an NPI or an order number is never read as a phone.\n */\nexport function phonesOutsideFictionalRange(text: string, phoneField = false): string[] {\n const t = normalizeForPhones(text);\n const out: string[] = [];\n for (const m of t.matchAll(INTL)) {\n const digits = m[0].replace(/\\D/g, \"\");\n const cc = m[1] ?? \"\";\n const national = digits.slice(cc.length).replace(/^0/, \"\");\n if (!(cc === \"44\" && OFCOM_DRAMA.test(national))) out.push(m[0].trim());\n }\n const rest = t.replace(INTL, \" \");\n if (phoneField && /^\\s*0\\d[\\d\\s-]{8,}\\d\\s*$/.test(rest)) {\n const national = rest.replace(/\\D/g, \"\").replace(/^0/, \"\");\n if (!OFCOM_DRAMA.test(national)) out.push(rest.trim());\n return out;\n }\n for (const m of rest.matchAll(phoneField ? NANP_IN_FIELD : NANP_IN_TEXT)) {\n const [area, ex, line] = phoneField ? [m[1], m[2], m[3]] : [m[1] ?? m[2], m[3], m[4]];\n if (nanpBad(area ?? \"\", ex ?? \"\", line ?? \"\")) out.push(m[0].trim());\n }\n return out;\n}\n\n/** Public mail providers: real domains millions of real people use — never \"fictional\". */\nexport const PUBLIC_MAIL_DOMAINS = [\n \"gmail.com\", \"googlemail.com\", \"outlook.com\", \"hotmail.com\", \"live.com\", \"msn.com\", \"yahoo.com\", \"ymail.com\", \"icloud.com\", \"me.com\", \"mac.com\",\n \"aol.com\", \"proton.me\", \"protonmail.com\", \"pm.me\", \"zoho.com\", \"gmx.com\", \"gmx.net\", \"mail.com\", \"yandex.com\", \"fastmail.com\", \"hey.com\", \"tutanota.com\",\n \"comcast.net\", \"verizon.net\", \"att.net\", \"sbcglobal.net\", \"bellsouth.net\", \"cox.net\", \"qq.com\", \"163.com\", \"web.de\",\n] as const;\n\n/** Every domain an email, a website or a url in the text uses. */\nexport function domainsIn(text: string): string[] {\n const found = new Set<string>();\n for (const m of text.matchAll(/[a-z0-9._%+-]+@([a-z0-9-]+(?:\\.[a-z0-9-]+)+)/gi)) found.add((m[1] ?? \"\").toLowerCase());\n for (const m of text.matchAll(/\\bhttps?:\\/\\/([a-z0-9-]+(?:\\.[a-z0-9-]+)+)/gi)) found.add((m[1] ?? \"\").toLowerCase().replace(/^www\\./, \"\"));\n for (const m of text.matchAll(/\\bwww\\.([a-z0-9-]+(?:\\.[a-z0-9-]+)+)/gi)) found.add((m[1] ?? \"\").toLowerCase().replace(/\\.$/, \"\"));\n return [...found];\n}\n\n/** \"4127 Calloway Palm Way, Suite 6\" → \"Calloway Palm Way\"; no house number → null. */\nexport function numberedStreet(line: string): string | null {\n const m = /^\\s*\\d+[A-Za-z]?\\s+(.+?)\\s*(?:,.*|\\s+(?:suite|ste\\.?|unit|apt\\.?|#)\\s*.*)?$/i.exec(line);\n return m ? (m[1] ?? null) : null;\n}\n\n// ═════════════════════════════════════════════════════════════════════════════\n// The verdict\n// ═════════════════════════════════════════════════════════════════════════════\n\nexport type TemplateStatus = \"pass\" | \"fail\" | `waiting on ${string}`;\n\nexport interface TemplateVerdict {\n ok: boolean;\n status: TemplateStatus;\n problems: UseCaseProblem[];\n waiting: CapabilityStatus[];\n}\n\nexport interface ValidateOptions {\n /** templates/AGENTS.snapshot.json — the platform agents a template may copy. */\n agents?: AgentSnapshotRow[];\n /**\n * The rest of the library (every other template file), so a template copied from another can\n * be told it still carries that business's names, people or sentences.\n * G1 always passes it; a single-file check without it skips only this cross-file rule.\n */\n library?: { specs: TemplateSpec[]; signatures?: unknown };\n /**\n * \"gallery\" (default): a published platform template — the full bar.\n * \"describe\": a private one-off spec made from one sentence (the /make describe box). Its tables,\n * fields, links, forms, views and booking pages are held to the same rules; what only a gallery\n * card needs is not asked for — catalogue keys, strengths, provenance, the teaching walk, the agent,\n * seed rows and how the seed looks on screen — and `requires` is worked out, never written.\n */\n profile?: \"gallery\" | \"describe\";\n}\n\n/** Problem roots only a published gallery template owes (the describe profile does not ask for them). */\nconst GALLERY_ONLY_ROOTS = [\"catalogueId\", \"strengths\", \"teaches\", \"agent\", \"walk\", \"provenance\", \"requires\", \"persona\"];\n\n/** Every piece of text a person reads in the template, with where it sits. Keys and tokens are not text. */\nexport function templateText(spec: TemplateSpec): Array<[string, string]> {\n const out: Array<[string, string]> = [];\n const add = (at: string, v: unknown) => {\n if (typeof v === \"string\" && v.trim()) out.push([at, v]);\n };\n const b = spec.business;\n add(\"business.name\", b?.name);\n add(\"business.legalName\", b?.legalName);\n add(\"business.describes\", b?.describes);\n add(\"business.website\", b?.website);\n add(\"business.email\", b?.email);\n add(\"useCase\", spec.useCase);\n for (const t of allTables(spec)) {\n add(`tables (${t.token}).name`, t.name);\n add(`tables (${t.token}).labelPlural`, t.labelPlural);\n add(`tables (${t.token}).labelSingular`, t.labelSingular);\n add(`tables (${t.token}).describes`, t.describes);\n const byKey = new Map(t.fields.map((f) => [f.key, f]));\n for (const f of t.fields) {\n add(`tables (${t.token}).fields (${f.key}).label`, f.label);\n add(`tables (${t.token}).fields (${f.key}).help`, f.help);\n for (const c of f.choices ?? []) add(`tables (${t.token}).fields (${f.key}).choices`, c);\n }\n for (const r of t.rows) {\n for (const [k, v] of Object.entries(r.values ?? {})) {\n const f = byKey.get(k);\n if (f && !isRelation(f)) add(`tables (${t.token}).rows (${r.key}).${k}`, unwrap(v));\n }\n }\n }\n for (const v of spec.views ?? []) add(`views (${v.token}).name`, v.name);\n for (const f of spec.forms ?? []) {\n add(`forms (${f.token}).name`, f.name);\n add(`forms (${f.token}).describes`, f.describes);\n add(`forms (${f.token}).confirmation`, f.confirmation);\n add(`forms (${f.token}).submitLabel`, f.submitLabel);\n for (const q of f.fields ?? []) {\n add(`forms (${f.token}).fields (${q.fieldKey}).ask`, q.ask);\n add(`forms (${f.token}).fields (${q.fieldKey}).help`, q.help);\n }\n }\n const walkStrings = (at: string, v: unknown): void => {\n if (typeof v === \"string\") add(at, v);\n else if (Array.isArray(v)) v.forEach((x, i) => walkStrings(`${at}[${i}]`, x));\n else if (v && typeof v === \"object\") for (const [k, x] of Object.entries(v)) if (![\"token\", \"table\", \"kind\", \"field\", \"view\", \"path\", \"stageField\", \"dateField\", \"fieldKey\", \"key\", \"row\", \"form\", \"surface\", \"dedupeKey\", \"columns\", \"of\", \"groupBy\", \"stateKey\", \"clientTable\", \"namesVia\", \"visibleFields\", \"editableFields\", \"aboutTable\", \"ref\", \"role\", \"dependsOn\", \"requires\", \"by\"].includes(k)) walkStrings(`${at}.${k}`, x);\n };\n (spec.extras ?? []).forEach((e) => walkStrings(`extras (${e.token})`, e));\n (spec.walk ?? []).forEach((w, i) => {\n add(`walk[${i}].says`, w?.says);\n const a = w?.action as { kind?: string; rows?: string[][]; sourceName?: string } | undefined;\n if (a?.kind === \"import\") {\n add(`walk[${i}].action.sourceName`, a.sourceName);\n a.rows?.forEach((row, ri) => row.forEach((c) => add(`walk[${i}].action.rows[${ri}]`, c)));\n }\n });\n add(\"agent.name\", spec.agent?.name);\n add(\"agent.question.ask\", spec.agent?.question?.ask);\n add(\"agent.question.whyItMatters\", spec.agent?.question?.whyItMatters);\n for (const v of spec.agent?.variables ?? []) add(`agent.variables (${v.name}).describes`, v.describes);\n for (const f of spec.foundation ?? []) add(`foundation (${f.table}).keptFor`, f.keptFor);\n return out;\n}\n\n/** People named in a template: its team and its person-name columns. */\nexport function peopleOf(spec: TemplateSpec): string[] {\n const out = new Set<string>();\n for (const t of allTables(spec)) {\n const nameFields = t.fields.filter((f) => /(^|_)(full_)?name$|^(owner|patient|client|contact|person|member|customer)_?name$/.test(f.key));\n for (const f of nameFields) for (const r of t.rows) {\n const v = storeText(r.values?.[f.key]);\n if (v && /^[A-Z][a-z]+(?:[ -][A-Z][a-z'’-]+)+$/.test(v.trim())) out.add(v.trim());\n }\n }\n return [...out];\n}\n\n/** Prose a person reads (not row values): where copied sentences hide. */\nfunction proseOf(spec: TemplateSpec): Array<[string, string]> {\n return templateText(spec).filter(([at]) => !at.startsWith(\"tables (\"));\n}\n\nconst words8 = (text: string) => text.toLowerCase().replace(/\\{\\{[^}]*\\}\\}/g, \" \").split(/[^a-z0-9']+/).filter(Boolean);\n\n/**\n * FOREIGN TEXT: what belongs to ANOTHER template file — its business and legal name, its\n * domains, its people — and any run of eight or more words copied verbatim from its prose (a\n * persona, a document, a message, a question, a walk step). A template made by copying another\n * and renaming the obvious parts still carries a sentence of it; this finds it. A shared trade\n * word (\"patient\", \"pool\") is never foreign: two businesses in one trade speak alike.\n */\n/**\n * What another template contributes to the foreign-text rule, worked out ONCE per spec object: the library\n * check runs every file against every other, so rebuilding these per pair grew with the square of the library\n * (G1 passed 240 s at ~280 files on a loaded machine).\n */\nconst FOREIGN_INDEX = new WeakMap<TemplateSpec, { name: string; tokens: Array<[string, string]>; grams: Set<string> }>();\nfunction foreignIndexOf(other: TemplateSpec) {\n let ix = FOREIGN_INDEX.get(other);\n if (ix) return ix;\n const tokens: Array<[string, string]> = [];\n for (const v of [other.business?.name, other.business?.legalName]) if (v) tokens.push([v, \"its business name\"]);\n for (const d of other.provenance?.fictionalDomains ?? []) tokens.push([d, \"one of its domains\"]);\n for (const p of peopleOf(other)) tokens.push([p, \"one of its people\"]);\n const grams = new Set<string>();\n for (const [, v] of proseOf(other)) {\n const w = words8(v);\n for (let i = 0; i + 8 <= w.length; i += 1) grams.add(w.slice(i, i + 8).join(\" \"));\n }\n ix = { name: other.business?.name ?? other.id, tokens, grams };\n FOREIGN_INDEX.set(other, ix);\n return ix;\n}\n\nexport function foreignTextProblems(spec: TemplateSpec, library: { specs: TemplateSpec[]; signatures?: unknown }): UseCaseProblem[] {\n const problems: UseCaseProblem[] = [];\n const text = templateText(spec);\n const hay = text.map(([at, v]) => [at, v.toLowerCase()] as const);\n const all = hay.map(([, v]) => v).join(\"\\n\");\n const esc = (w: string) => w.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const find = (word: string) => {\n const lower = word.toLowerCase();\n if (!all.includes(lower)) return undefined; // cheap: most names are nowhere in this file\n const re = new RegExp(`(^|[^a-z0-9])${esc(lower)}($|[^a-z0-9])`);\n return hay.find(([, v]) => re.test(v));\n };\n const mine = proseOf(spec).map(([at, w]) => {\n const words = words8(w);\n const runs: string[] = [];\n for (let i = 0; i + 8 <= words.length; i += 1) runs.push(words.slice(i, i + 8).join(\" \"));\n return [at, runs] as const;\n });\n for (const other of library.specs) {\n if (!other || other.id === spec.id) continue;\n const { name, tokens, grams } = foreignIndexOf(other);\n for (const [word, what] of tokens) {\n const hit = find(word);\n if (hit) problems.push({ at: hit[0], says: `This still says \"${word}\", ${what} from the ${name} template. Write your own business's words.` });\n }\n for (const [at, runs] of mine) {\n const run = runs.find((r) => grams.has(r));\n if (run) problems.push({ at, says: `This copies \"${run}…\" word for word from the ${name} template. Write it in your own business's words.` });\n }\n }\n return problems;\n}\n\nexport const MAIN_TABLE_ROWS_MIN = 20;\nexport const MAIN_TABLE_ROWS_MAX = 50;\nexport const TABLES_MIN = 2;\nexport const TABLES_MAX = 8;\n/** At least this share of a table's rows carry a title nobody else has. */\nexport const TITLE_DISTINCT_SHARE = 0.9;\nconst SINGULAR_OWES = new Set([\"form\", \"pipeline\", \"dashboardQuestion\", \"documentTemplate\", \"notificationRule\"]);\nconst norm = (s: string) => s.toLowerCase().replace(/[^a-z0-9]+/g, \" \").trim();\n/** A field's label means one of `sameAs` when it is one, or carries one's distinctive word (\"Cell phone\" → cell). */\nconst SYNONYM_WORDS: Record<string, string[]> = {\n name: [\"name\"],\n role: [\"role\", \"title\", \"position\"],\n email: [\"email\", \"e-mail\", \"mail\"],\n phone: [\"phone\", \"mobile\", \"cell\"],\n // \"Service start\" or \"Start of season\" is not a hire date: only words that mean joining the team.\n start: [\"hired\", \"hire\", \"joined\"],\n};\nfunction labelMeans(f: { label: string }, sameAs: readonly string[]): boolean {\n const label = norm(f.label);\n if (sameAs.includes(label)) return true;\n const words = new Set(label.split(\" \"));\n return Object.values(SYNONYM_WORDS).some((group) => group.some((w) => words.has(w)) && sameAs.some((s) => group.some((w) => s.split(\" \").includes(w))));\n}\nconst sameJson = (a: unknown, b: unknown) => JSON.stringify(a) === JSON.stringify(b);\nconst sortedJson = (v: Record<string, unknown>) => JSON.stringify(Object.keys(v).sort().map((k) => [k, v[k]]));\nconst filled = (v: unknown) => storeText(v) !== null && storeText(v) !== \"\" && !(Array.isArray(v) && v.length === 0);\n\n/** Name columns that name a thing, never a person (the person-placeholder rule does not apply). */\nconst THING_NAME = /^(section|class|course|period|room|bay|item|job|role|team|pool|machine|program|plan|service|procedure|product|group|neighborhood|listing|grant|deal|bid|engagement|matter|account|company|route|site|location|project|event|campaign|unit|vehicle|truck|table|field|view|form)_name$/;\n\n/** Check one template. Every problem, not the first. */\nconst FILE_VALUE_RE = /^@file:([A-Za-z0-9_.-]+)$/;\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/** One platform picture as templates/ASSETS.json lists it (written by `pnpm templates:assets`). */\nexport interface TemplateAssetRow {\n key: string;\n fileId: string;\n name: string;\n mime: string;\n bytes: number;\n publishedToWeb: boolean;\n}\n\n/**\n * seed.attachments, as written: every `attachments` entry is whole, every attachment-field value is\n * \"@file:<key>\" naming one of them, and every listed picture is used. With `assets` (ASSETS.json),\n * each attachment must BE a library picture (same key and file id) that is published to the web —\n * a picture only its uploader can read would show members an empty card.\n */\nexport function attachmentProblems(\n raw: TemplateSpec & { attachments?: Array<Partial<TemplateAssetRow>> },\n assets?: TemplateAssetRow[],\n): UseCaseProblem[] {\n const out: UseCaseProblem[] = [];\n const say = (at: string, says: string) => out.push({ at, says });\n const listed = raw.attachments ?? [];\n if (raw.attachments !== undefined && !Array.isArray(raw.attachments)) {\n say(\"attachments\", \"attachments is a list of pictures from templates/ASSETS.json.\");\n return out;\n }\n const keys = new Set<string>();\n const library = assets ? new Map(assets.map((a) => [a.key, a])) : null;\n listed.forEach((a, i) => {\n const at = `attachments[${i}]`;\n if (!a.key || !/^[A-Za-z0-9_.-]+$/.test(a.key)) return say(`${at}.key`, \"Each picture has a key (letters, digits, _ . -).\");\n if (keys.has(a.key)) say(`${at}.key`, `\"${a.key}\" is listed twice.`);\n keys.add(a.key);\n if (!a.fileId || !UUID_RE.test(a.fileId)) say(`${at}.fileId`, `\"${a.key}\" needs the file id from templates/ASSETS.json.`);\n if (!a.name || !a.mime || typeof a.bytes !== \"number\") say(at, `\"${a.key}\" copies name, mime and bytes from templates/ASSETS.json.`);\n if (library) {\n const asset = library.get(a.key);\n if (!asset) say(`${at}.key`, `\"${a.key}\" is not a picture in templates/ASSETS.json.`);\n else if (asset.fileId !== a.fileId) say(`${at}.fileId`, `\"${a.key}\" names file ${a.fileId}, but templates/ASSETS.json has ${asset.fileId}.`);\n else if (asset.publishedToWeb !== true) say(`${at}.fileId`, `\"${a.key}\" is not published to the web, so members could not see it.`);\n }\n });\n const used = new Set<string>();\n for (const table of allTables(raw)) {\n const fileFields = new Set(table.fields.filter((f) => f.parityType === \"attachment\").map((f) => f.key));\n table.rows?.forEach((row, ri) => {\n for (const [key, rawValue] of Object.entries(row.values ?? {})) {\n const value = unwrap(rawValue);\n const items = Array.isArray(value) ? value : [value];\n for (const item of items) {\n if (typeof item !== \"string\") continue;\n const m = FILE_VALUE_RE.exec(item);\n const at = `tables (${table.token}).rows[${ri}].values.${key}`;\n if (!m) {\n if (fileFields.has(key) && item) say(at, `A file field holds \"@file:<key>\" from the template's attachments, not \"${item}\".`);\n continue;\n }\n if (!fileFields.has(key)) say(at, `\"${item}\" names a picture, but \"${key}\" is not a file field.`);\n else if (!keys.has(m[1]!)) say(at, `\"${item}\" names a picture the template's attachments do not list.`);\n used.add(m[1]!);\n }\n }\n });\n }\n for (const k of keys) if (!used.has(k)) say(\"attachments\", `\"${k}\" is listed but no row shows it.`);\n for (const view of raw.views ?? []) {\n if (view.kind !== \"gallery\") continue;\n const table = allTables(raw).find((t) => t.token === view.table);\n const seeded = (table?.rows ?? []).filter((r) => {\n const v = unwrap(r.values?.[view.coverField]);\n return (Array.isArray(v) ? v : [v]).some((x) => typeof x === \"string\" && FILE_VALUE_RE.test(x));\n }).length;\n if (table && seeded === 0) say(`views (${view.token})`, `The gallery \"${view.name}\" shows pictures, but no row has one in \"${view.coverField}\".`);\n }\n return out;\n}\n\nexport function validateTemplate(raw: TemplateSpec, options: ValidateOptions = {}): TemplateVerdict {\n const problems: UseCaseProblem[] = [];\n const say = (at: string, says: string) => problems.push({ at, says });\n // A rule about how the SEED looks on screen (charts with one bar, empty boards); a spec with no seed rows\n // under the describe profile does not owe it.\n const seedLooks = new WeakSet<UseCaseProblem>();\n const saySeed = (at: string, says: string) => {\n const p = { at, says };\n seedLooks.add(p);\n problems.push(p);\n };\n // A bar only a published gallery card owes (enough views, extras and cross-table reads to TEACH the store);\n // a one-off describe spec owes the person's own setup — \"one useful view\" (MANDATE-BRIEF-SENTENCE-TO-TEMPLATE).\n const galleryBar = new WeakSet<UseCaseProblem>();\n const sayGallery = (at: string, says: string) => {\n const p = { at, says };\n galleryBar.add(p);\n problems.push(p);\n };\n const tz = raw.business?.timezone || \"UTC\";\n const tablesRaw = allTables(raw);\n\n // ── relative dates (on the file as written; Value envelopes unwrapped) ─────\n const ISO_DAY = /\\b\\d{4}-\\d{2}-\\d{2}\\b/;\n // ── a checklist step is due a whole number of days from the checklist's start, 0 to ten years (the store refuses\n // a negative offset: T0615's pre-pour steps were \"due -3 days in\") ──\n for (const e of raw.extras ?? []) {\n if (e.kind !== \"checklist\") continue;\n for (const st of (e as { steps?: Array<{ ref?: string; dueDays?: number }> }).steps ?? []) {\n if (st.dueDays !== undefined && !(Number.isInteger(st.dueDays) && st.dueDays >= 0 && st.dueDays <= 3650)) {\n say(`extras (${(e as { token: string }).token}).steps (${st.ref ?? \"?\"}).dueDays`, `A step is due a whole number of days after the checklist starts, from 0 to 3650; ${st.dueDays} is not. Start the checklist earlier instead of counting backwards.`);\n }\n }\n }\n // ── a pattern rule's example passes its own pattern (the store refuses the field otherwise, FLD-3) ──\n for (const table of tablesRaw) {\n for (const f of table.fields) {\n for (const rule of (f.rules ?? []) as Array<{ kind?: string; value?: unknown; example?: unknown }>) {\n if (rule.kind !== \"pattern\" || typeof rule.value !== \"string\" || typeof rule.example !== \"string\") continue;\n let re: RegExp | null = null;\n try { re = new RegExp(rule.value); } catch { continue; }\n if (!re.test(rule.example)) say(`tables (${table.token}).fields (${f.key}).rules`, `\"${f.label}\" shows \"${rule.example}\" as the way to write it, and its own pattern refuses that. Make the example match the pattern.`);\n }\n }\n }\n // ── an email column holds an address the store's email rule accepts (one word, one @, a dotted domain) ──\n const EMAIL_SHAPE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n for (const table of tablesRaw) {\n for (const f of table.fields.filter((x) => x.parityType === \"email\" || x.format === \"email\")) {\n table.rows?.forEach((row) => {\n const v = unwrap(row.values?.[f.key]);\n if (typeof v === \"string\" && v !== \"\" && !EMAIL_SHAPE.test(v)) say(`tables (${table.token}).rows (${row.key}).${f.key}`, `\"${v}\" is not an email address the store will take (no spaces, one @, a dotted domain).`);\n });\n }\n }\n // ── a table's title column is made with the table (custom.table_from_example needs it there), and a column\n // with a default is declared later on its own (field_declare carries the default) — so a title takes none.\n for (const table of tablesRaw) {\n const tf = table.fields.find((f) => f.key === table.titleField);\n if (tf && tf.default !== undefined) say(`tables (${table.token}).fields (${tf.key})`, `\"${tf.label}\" names each ${table.labelSingular.toLowerCase()}, so it takes no default; ask it on the form instead.`);\n }\n // ── a link holds no more targets than the store lets it (custom._field_document_for: relation_max\n // defaults to 25 for a list, 1 for a single link; record_write refuses more — REC-51) ──\n for (const table of tablesRaw) {\n for (const f of table.fields.filter((x) => isRelation(x) && x.parityType !== \"attachment\")) {\n const max = f.relationMax ?? (f.multi ? STORE_LIST_RELATION_MAX : 1);\n table.rows?.forEach((row) => {\n const v = unwrap(row.values?.[f.key]);\n const n = Array.isArray(v) ? v.length : v === null || v === undefined || v === \"\" ? 0 : 1;\n if (n > max) say(`tables (${table.token}).rows (${row.key}).${f.key}`, `\"${f.label}\" links ${n} records, more than the ${max} it may hold. Set relationMax on the field (up to the real most), or link fewer.`);\n });\n }\n }\n for (const table of tablesRaw) {\n // Lane 10 FD: a table's own `foundation` is only an echo of the template's foundation list (the\n // one source the installers read): true or false, and saying what the list says.\n if (table.foundation !== undefined) {\n const listed = (raw.foundation ?? []).some((f) => f.table === table.token);\n if (typeof table.foundation !== \"boolean\") say(`tables (${table.token}).foundation`, \"foundation is true or false.\");\n else if (table.foundation !== listed) {\n say(\n `tables (${table.token}).foundation`,\n listed\n ? `\"${table.token}\" is in the foundation list; take foundation: false off the table.`\n : `\"${table.token}\" says foundation: true but is not in the foundation list; list it there.`,\n );\n }\n }\n const byKey = new Map(table.fields.map((f) => [f.key, f]));\n for (const f of table.fields) {\n if (f.absoluteDates && !isDate(f)) say(`tables (${table.token}).fields (${f.key})`, `absoluteDates belongs on a date field; \"${f.label}\" is ${f.parityType}.`);\n if (f.absoluteDates && !f.historicalReason?.trim()) say(`tables (${table.token}).fields (${f.key}).historicalReason`, `\"${f.label}\" holds absolute dates; say why they are history (\"date of birth\").`);\n }\n table.rows?.forEach((row, ri) => {\n for (const [key, rawValue] of Object.entries(row.values ?? {})) {\n const f = byKey.get(key);\n const value = unwrap(rawValue);\n if (!f || typeof value !== \"string\") continue;\n const at = `tables (${table.token}).rows[${ri}].values.${key}`;\n const relative = RELATIVE_DATE.test(value);\n if (isDate(f)) {\n const timed = relative ? relativeHasTime(value) : /T\\d{2}:\\d{2}/.test(value);\n if (timed && f.format !== \"datetime\") {\n say(at, `\"${f.label}\" holds a time of day (\"${value}\") but its format is ${f.format ? `\"${f.format}\"` : \"not set\"}, so the calendar would show it as all-day. Set the field's format to \"datetime\", or seed whole days.`);\n }\n if (f.absoluteDates) {\n if (relative) say(at, `\"${f.label}\" holds history (absoluteDates), so write the real date, not \"${value}\".`);\n else if (Number.isNaN(Date.parse(value))) say(at, `\"${value}\" is not a date.`);\n } else if (!relative) {\n say(at, `\"${value}\" is an absolute date. Write seed dates relative to install day (\"@today+3d\", \"@today-1w 09:30\"), or flag the field absoluteDates if it is history (a date of birth).`);\n }\n } else if (relative) say(at, `\"${value}\" is a relative date in \"${f.label}\", which is not a date field.`);\n else if (f.parityType === \"attachment\" && FILE_VALUE_RE.test(value)) continue;\n else if (value.startsWith(\"@\")) say(at, `\"${value}\" is not in the relative-date grammar (\"@today\", \"@today-3b 08:30\", \"@next-tue\", \"@today~b 10:00\").`);\n else if (ISO_DAY.test(value)) say(at, `\"${value}\" writes a calendar date into text, where it goes stale the day after install. Put the date in a date field (relative), or leave it out.`);\n }\n });\n }\n\n // ── seed.attachments: pictures come from the platform library, named by \"@file:<key>\" ──\n for (const p of attachmentProblems(raw)) say(p.at, p.says);\n\n const spec = resolveRelativeDates(raw, TEMPLATE_REFERENCE_DATE);\n\n // ── the shared law, shape and graph (validateUseCase over the derived use case) ──\n const derived = { ...spec, industry: spec.vertical, tables: allTables(spec), ...deriveSingulars(spec) } as unknown as UseCase;\n for (const p of validateUseCase(derived).problems) if (!SINGULAR_OWES.has(p.at)) problems.push(p);\n\n // ── lane 12 P7: Confidential tables and members-add-rows tables name real tables and fields ──\n for (const says of tableSettingsProblems(spec)) say(\"confidential\", says);\n\n // ── the catalogue keys ──────────────────────────────────────────────────────\n if (spec.specVersion !== TEMPLATE_SPEC_VERSION) say(\"specVersion\", `The file's schema version is ${TEMPLATE_SPEC_VERSION}; write \"specVersion\": ${TEMPLATE_SPEC_VERSION}.`);\n if (!/^T\\d{4}$/.test(spec.catalogueId ?? \"\")) say(\"catalogueId\", `\"${spec.catalogueId}\" should be the CATALOGUE.json row it realises, like \"T0042\".`);\n if (!(INDUSTRY_GROUPS as readonly string[]).includes(spec.industry)) say(\"industry\", `\"${spec.industry}\" is not one of the catalogue's industry groups: ${INDUSTRY_GROUPS.join(\", \")}.`);\n if (!spec.vertical?.trim()) say(\"vertical\", \"Name the practitioner's own vertical — 'Dental practice', 'Residential HVAC'.\");\n if (!(TEMPLATE_JOBS as readonly string[]).includes(spec.job)) say(\"job\", `\"${spec.job}\" is not one of the twelve jobs: ${TEMPLATE_JOBS.join(\", \")}.`);\n if (!(TEMPLATE_AUDIENCES as readonly string[]).includes(spec.audience)) say(\"audience\", `\"${spec.audience}\" is not one of: ${TEMPLATE_AUDIENCES.join(\", \")}.`);\n if (!(TEACHES_FEATURES as readonly string[]).includes(spec.teaches)) say(\"teaches\", `\"${spec.teaches}\" is not one of the sixteen features.`);\n if (!spec.strengths?.length) say(\"strengths\", \"Name at least one strength (S1–S5) this template leads with.\");\n for (const s of spec.strengths ?? []) if (!(STRENGTHS as readonly string[]).includes(s)) say(\"strengths\", `\"${s}\" is not one of: ${STRENGTHS.join(\", \")}.`);\n if (!Number.isInteger(spec.version) || spec.version < 1) say(\"version\", \"The content version is a whole number, 1 or more, bumped on every published change.\");\n if (!Array.isArray(spec.provenance?.sources)) say(\"provenance.sources\", \"List the sources the structure came from (an empty list says 'from domain knowledge').\");\n\n const own = spec.tables ?? [];\n const tables = allTables(spec);\n const byToken = new Map(tables.map((t) => [t.token, t]));\n const fieldOf = (table: string, key: string): TemplateField | undefined => byToken.get(table)?.fields.find((f) => f.key === key);\n const refWeek0 = [0, 1, 2, 3, 4, 5, 6].map((i) => shiftDays(TEMPLATE_REFERENCE_DATE, i));\n /** A lookup's or formula's value on one row, worked out the store's way, or why the gate cannot. */\n function computedOf(table: string, f: TemplateField, r: SeedRow, depth = 0): { ok: true; v: unknown } | { ok: false; why: string } {\n if (depth > 4) return { ok: false, why: \"it reads through too many computed fields\" };\n if (f.parityType === \"lookup\" && f.via && f.pick) {\n const target = fieldOf(table, f.via)?.relationTarget;\n const ref = r.values?.[f.via];\n const far = target ? byToken.get(target)?.rows.find((x) => x.key === (Array.isArray(ref) ? ref[0] : ref)) : undefined;\n const pf = target ? fieldOf(target, f.pick) : undefined;\n if (!far || !pf) return { ok: true, v: null };\n return isComputed(pf) ? computedOf(target!, pf, { key: far.key, values: far.values }, depth + 1) : { ok: true, v: far.values?.[f.pick] ?? null };\n }\n if (f.parityType === \"formula\" && f.formula) {\n const ast = parseFormula(f.formula);\n if (typeof ast === \"string\") return { ok: false, why: ast };\n let why: string | null = null;\n const r2 = evalFormula(ast, (label) => {\n const ff = byToken.get(table)?.fields.find((x) => x.label === label);\n if (!ff) return null;\n if (!isComputed(ff)) return r.values?.[ff.key];\n if (ff.parityType === \"lookup\" || ff.parityType === \"rollup\") {\n why = `it reads the ${ff.parityType} {${label}}, which the store currently reads as 0 in a formula`;\n return null;\n }\n const c = computedOf(table, ff, r, depth + 1);\n if (!c.ok) why = c.why;\n return c.ok ? c.v : null;\n });\n if (why) return { ok: false, why };\n if (!r2.ok) return r2;\n return { ok: true, v: r2.v === null ? null : (qToNumber(r2.v) ?? Number(r2.v.n) / Number(r2.v.d)) };\n }\n return { ok: false, why: `${f.parityType} is not worked out by the gate` };\n }\n /** Rows with several computed fields (a measure and its filter keys) filled in. */\n function withComputedKeys(table: string, keys: (string | undefined)[], rows: SeedRow[]): { rows: SeedRow[] } | { why: string } {\n let acc: { rows: SeedRow[] } | { why: string } = { rows };\n for (const k of keys) if (\"rows\" in acc) acc = withComputed(table, k, acc.rows);\n return acc;\n }\n /** A formula over STORED columns whose answer is a number (custom.formula_eval computes these correctly). */\n function isNumberish(table: string, f: TemplateField | undefined): boolean {\n if (!f) return false;\n if (isNumber(f)) return true;\n if (f.parityType !== \"formula\" || !f.formula) return false;\n const ast = parseFormula(f.formula);\n if (typeof ast === \"string\") return false;\n const refsStored = formulaRefs(ast).every((l) => {\n const rf = byToken.get(table)?.fields.find((x) => x.label === l);\n return !!rf && !isComputed(rf);\n });\n const NUMERIC = new Set([\"ABS\", \"ROUND\", \"SUM\", \"MIN\", \"MAX\", \"AVERAGE\", \"DATEDIFF\", \"YEAR\", \"MONTH\", \"DAY\", \"LEN\"]);\n const numeric = (n: typeof ast): boolean => n.k === \"num\" || n.k === \"bin\" || n.k === \"neg\" || (n.k === \"call\" && NUMERIC.has(n.f)) || (n.k === \"ref\" && isNumber(byToken.get(table)?.fields.find((x) => x.label === n.v) ?? { parityType: \"\" }));\n return refsStored && numeric(ast);\n }\n /** Rows with one computed field filled in, so custom.record_aggregate's answer over it can be mirrored. */\n function withComputed(table: string, key: string | undefined, rows: SeedRow[]): { rows: SeedRow[] } | { why: string } {\n const f = key ? fieldOf(table, key) : undefined;\n if (!f || !isComputed(f)) return { rows };\n const out: SeedRow[] = [];\n for (const r of rows) {\n const c = computedOf(table, f, r);\n if (!c.ok) return { why: `\"${f.label}\" is computed by the store and ${c.why}, so the gate cannot check the answer the store's way` };\n out.push({ ...r, values: { ...r.values, [f.key]: c.v } });\n }\n return { rows: out };\n }\n /**\n * What the seed itself says a stage carries: every seed row in stage X fills F and every row in\n * an earlier (unfinished) stage leaves it empty — at least two of each. Map stage → fields.\n */\n function inferredImplies(table: string, stageField: string): Map<string, string[]> {\n const out = new Map<string, string[]>();\n const t = byToken.get(table);\n const order = fieldOf(table, stageField)?.choices ?? [];\n if (!t) return out;\n order.forEach((x, ix) => {\n const inX = t.rows.filter((r) => storeText(r.values?.[stageField]) === x);\n const before = t.rows.filter((r) => {\n const j = order.indexOf(storeText(r.values?.[stageField]) ?? \"\");\n return j >= 0 && j < ix && !TERMINAL_STAGE.test(order[j]!);\n });\n if (inX.length < 2 || before.length < 2) return;\n const keys = t.fields.filter((f) => f.key !== stageField && !isComputed(f) && !f.required && !(isRelation(f) && (f.multi || (f.relationMax ?? 1) !== 1)) && inX.every((r) => filled(r.values?.[f.key])) && before.every((r) => !filled(r.values?.[f.key]))).map((f) => f.key);\n if (keys.length) out.set(x, keys);\n });\n return out;\n }\n /** A lookup is as sensitive as the strictest field it reads (its own declaration, or the far side's). */\n const effective = (table: string, f: TemplateField, depth = 0): { sensitivity: string; contextPolicy: string } => {\n let sens = f.sensitivity as string;\n let ctx = f.contextPolicy as string;\n if (f.parityType === \"lookup\" && f.via && f.pick && depth < 5) {\n const via = fieldOf(table, f.via);\n const far = via?.relationTarget ? fieldOf(via.relationTarget, f.pick) : undefined;\n if (via?.relationTarget && far) {\n const e = effective(via.relationTarget, far, depth + 1);\n if (SENSITIVITY_RANK.indexOf(e.sensitivity) > SENSITIVITY_RANK.indexOf(sens)) sens = e.sensitivity;\n if (CONTEXT_RANK.indexOf(e.contextPolicy) > CONTEXT_RANK.indexOf(ctx)) ctx = e.contextPolicy;\n }\n }\n return { sensitivity: sens, contextPolicy: ctx };\n };\n const agentReads = (table: string, f: TemplateField) => {\n const e = effective(table, f);\n return e.contextPolicy !== \"exclude\" && e.sensitivity !== \"restricted\";\n };\n\n // ── the floor ───────────────────────────────────────────────────────────────\n if (own.length < TABLES_MIN || own.length > TABLES_MAX) say(\"tables\", `A template installs ${TABLES_MIN}–${TABLES_MAX} related tables; this one has ${own.length}.`);\n const main = own[0];\n if (main && (main.rows.length < MAIN_TABLE_ROWS_MIN || main.rows.length > MAIN_TABLE_ROWS_MAX)) {\n say(`tables[0] (${main.token}).rows`, `The main table carries ${MAIN_TABLE_ROWS_MIN}–${MAIN_TABLE_ROWS_MAX} realistic rows; it has ${main.rows.length}.`);\n }\n\n // ── no two columns of one table share a label (the store refuses the second) ──\n for (const t of tables) {\n const seenLabels = new Map<string, string>();\n for (const f of t.fields) {\n const l = f.label.trim().toLowerCase();\n const twin = seenLabels.get(l);\n if (twin) say(`tables (${t.token}).fields (${f.key}).label`, `\"${f.label}\" is already the label of \"${twin}\" on \"${t.name}\"; the store refuses a second column with that name. Give each column its own label.`);\n else seenLabels.set(l, f.key);\n }\n }\n\n // ── fields and rows: colours, rules, distinctness, lookups ──────────────────\n let hasLookupOrRollup = false;\n tables.forEach((table) => {\n const tat = `tables (${table.token})`;\n table.fields.forEach((field) => {\n const at = `${tat}.fields (${field.key})`;\n if (isChoice(field) && field.choices?.length) {\n const colors = field.choices.map((c) => field.choiceColors?.[c]);\n field.choices.forEach((c, i) => {\n const color = colors[i];\n if (!color) say(`${at}.choiceColors`, `The choice \"${c}\" wears no colour. Give every choice one of: ${CHOICE_COLORS.join(\", \")}.`);\n else if (!(CHOICE_COLORS as readonly string[]).includes(color)) say(`${at}.choiceColors`, `\"${color}\" is not a colour the grid can paint.`);\n });\n for (const k of Object.keys(field.choiceColors ?? {})) if (!field.choices.includes(k)) say(`${at}.choiceColors`, `It colours \"${k}\", which is not one of the field's choices.`);\n // Distinct per choice up to the palette (7 colours today; the ruling's \"up to 8\"\n // is capped by what the grid can paint), every colour used above that.\n const distinct = new Set(colors.filter(Boolean)).size;\n const need = Math.min(field.choices.length, CHOICE_COLORS.length);\n if (distinct < need) say(`${at}.choiceColors`, `${field.choices.length} choices wear only ${distinct} distinct colour(s); each choice needs its own (${need}), so the board reads at a glance.`);\n }\n if (isNumber(field) && !isComputed(field)) {\n const kinds = new Set((field.rules ?? []).map((r) => r.kind));\n if (!kinds.has(\"min\") || !kinds.has(\"max\")) say(`${at}.rules`, `\"${field.label}\" is measured, so it declares the least and the most a real value can be (min and max rules).`);\n const seeds = table.rows.map((r) => parseNumeric(storeText(r.values?.[field.key]) ?? \"\")).filter((v): v is Q => !!v).map((v) => Number(v.n) / Number(v.d));\n if (seeds.length) {\n const hi = Math.max(...seeds);\n const lo = Math.min(...seeds);\n if (new Set(seeds).size < 2) say(`${at}`, `Every seed row holds the same ${field.label}; real records vary.`);\n for (const rule of field.rules ?? []) {\n const bound = Number(rule.value);\n if (rule.kind === \"max\" && hi > 0 && bound > 100 * hi) say(`${at}.rules`, `The most \"${field.label}\" allows (${rule.value}) is over 100× the largest real value (${hi}); write the real ceiling.`);\n if (rule.kind === \"min\" && bound < -1000 * Math.abs(lo)) say(`${at}.rules`, `The least \"${field.label}\" allows (${rule.value}) is far below any real value (${lo}); write the real floor.`);\n if (rule.kind === \"min\" && bound < 0 && lo >= 0) say(`${at}.rules`, `\"${field.label}\" allows negative values, and no real one is negative; the floor is 0 or above.`);\n }\n }\n }\n if (field.parityType === \"lookup\" || field.parityType === \"rollup\") {\n const via = field.via ? fieldOf(table.token, field.via) : undefined;\n if (!via || !isRelation(via) || !via.relationTarget) {\n say(`${at}.via`, `A ${field.parityType} reads THROUGH a relation field of this table; \"${field.via ?? \"(none)\"}\" is not one.`);\n } else {\n hasLookupOrRollup = true;\n if (!field.pick || !fieldOf(via.relationTarget, field.pick)) say(`${at}.pick`, `It reads \"${field.pick ?? \"(nothing)\"}\" on \"${via.relationTarget}\", which that table does not declare.`);\n if (field.parityType === \"rollup\" && !field.agg) say(`${at}.agg`, \"A rollup says how it adds up the far side.\");\n // custom.field_declare (FLD-11): a rollup aggregates MANY records, so its relation must be a list.\n if (field.parityType === \"rollup\" && !via.multi && (via.relationMax ?? 1) <= 1) say(`${at}.via`, `\"${field.label}\" adds up \"${via.label}\", which links one record. Make \"${via.label}\" a list (multi), or read its one value with a lookup.`);\n }\n }\n if (field.parityType === \"entity_reference\" && !field.allowedTypes?.length) say(`${at}.allowedTypes`, \"A column that points at the platform names the kinds it may point at.\");\n if (isRelation(field) && field.relationTarget && !byToken.has(field.relationTarget)) say(`${at}.relationTarget`, `It points at \"${field.relationTarget}\", which is neither a table nor a shared block of this template.`);\n });\n\n // seed rows obey their own rules\n const seen = new Map<string, string>();\n const titles = new Set<string>();\n table.rows.forEach((row, ri) => {\n const rat = `${tat}.rows[${ri}] (${row.key})`;\n const sig = sortedJson(row.values ?? {});\n const twin = seen.get(sig);\n if (twin) say(rat, `This row is identical to \"${twin}\" apart from its key. Every seed row is a different real record.`);\n seen.set(sig, row.key);\n for (const field of table.fields) {\n if (!isRelation(field) || !field.relationTarget || field.parityType === \"attachment\") continue;\n const target = byToken.get(field.relationTarget);\n const v = row.values?.[field.key];\n if (!target || v === undefined || v === null) continue;\n for (const ref of Array.isArray(v) ? v : [v]) {\n if (typeof ref === \"string\" && !target.rows.some((r) => r.key === ref)) say(`${rat}.values.${field.key}`, `It points at the row \"${ref}\", which does not exist in \"${field.relationTarget}\".`);\n }\n }\n const title = storeText(row.values?.[table.titleField]);\n if (title) titles.add(title.trim().toLowerCase());\n for (const field of table.fields) {\n const v = row.values?.[field.key];\n if (v === undefined || v === null || v === \"\") continue;\n for (const rule of field.rules ?? []) {\n const t = storeText(v) ?? \"\";\n if (rule.kind === \"min\" || rule.kind === \"max\") {\n const n = parseNumeric(t);\n const bound = parseNumeric(String(rule.value));\n if (n && bound && (rule.kind === \"min\" ? qCmp(n, bound) < 0 : qCmp(n, bound) > 0)) {\n say(`${rat}.values.${field.key}`, `${t} breaks its own rule: \"${field.label}\" is at ${rule.kind === \"min\" ? \"least\" : \"most\"} ${rule.value}.`);\n }\n } else if (rule.kind === \"length\") {\n if (rule.value !== undefined && t.length > Number(rule.value)) say(`${rat}.values.${field.key}`, `\"${t}\" is longer than \"${field.label}\" allows (${rule.value}).`);\n if (rule.min !== undefined && t.length < rule.min) say(`${rat}.values.${field.key}`, `\"${t}\" is shorter than \"${field.label}\" allows (${rule.min}).`);\n } else if (rule.kind === \"pattern\" && rule.value !== undefined) {\n let re: RegExp | null = null;\n try {\n re = new RegExp(String(rule.value));\n } catch {\n say(`${tat}.fields (${field.key}).rules`, `The pattern \"${rule.value}\" is not a pattern.`);\n }\n if (re && !re.test(t)) say(`${rat}.values.${field.key}`, `\"${t}\" does not match \"${field.label}\"'s own pattern.`);\n }\n }\n }\n });\n for (const field of table.fields) {\n if (!(field.rules ?? []).some((r) => r.kind === \"unique\")) continue;\n const vals = table.rows.map((r) => storeText(r.values?.[field.key])).filter((v): v is string => !!v).map((v) => v.trim().toLowerCase());\n if (new Set(vals).size !== vals.length) say(`${tat}.fields (${field.key})`, `\"${field.label}\" is unique, and two seed rows share a value.`);\n }\n if (table.rows.length >= 2 && titles.size < Math.ceil(table.rows.length * TITLE_DISTINCT_SHARE)) {\n say(`${tat}.rows`, `Only ${titles.size} of ${table.rows.length} rows have a title of their own; a list of look-alike names reads as generated.`);\n }\n });\n if (!hasLookupOrRollup) sayGallery(\"tables\", \"At least one relationship has to be read across: add a lookup or a rollup through a relation field.\");\n\n // ── the main table: every two rows are different records ────────────────────\n if (main) {\n const normTitle = (v: unknown) => (storeText(v) ?? \"\").toLowerCase().replace(/\\s+/g, \" \").trim();\n const rows = main.rows;\n const titleSeen = new Map<string, string>();\n for (let i = 0; i < rows.length; i += 1) {\n const a = rows[i]!;\n const nt = normTitle(a.values?.[main.titleField]);\n const twin = titleSeen.get(nt);\n const twinTitle = twin ? storeText(rows.find((r) => r.key === twin)?.values?.[main.titleField]) : null;\n const rosterTwin = (() => {\n if (!twin || !main.schedule) return false;\n const b0 = rows.find((r) => r.key === twin);\n const differs = (pred: (f: TemplateField) => boolean) => main.fields.some((f) => pred(f) && !sameJson(a.values?.[f.key] ?? null, b0?.values?.[f.key] ?? null));\n return differs(isDate) && differs(isRelation);\n })();\n if (twin && !rosterTwin) say(`tables[0] (${main.token}).rows[${i}] (${a.key})`, `Two ${main.labelPlural.toLowerCase()} are both called \"${storeText(a.values?.[main.titleField])}\" (the other reads \"${twinTitle}\"). Give each its own name.`);\n else titleSeen.set(nt, a.key);\n for (let j = i + 1; j < rows.length; j += 1) {\n const b = rows[j]!;\n const keys = new Set([...Object.keys(a.values ?? {}), ...Object.keys(b.values ?? {})]);\n let differ = 0;\n for (const k of keys) if (!sameJson(a.values?.[k] ?? null, b.values?.[k] ?? null)) differ += 1;\n if (differ < 3) say(`tables[0] (${main.token}).rows[${j}] (${b.key})`, `\"${storeText(b.values?.[main.titleField])}\" differs from \"${storeText(a.values?.[main.titleField])}\" in only ${differ} field(s); two real ${main.labelPlural.toLowerCase()} differ in at least three.`);\n }\n }\n }\n\n // ── governance ──────────────────────────────────────────────────────────────\n const fields = tables.flatMap((t) => t.fields);\n const ownFields = own.flatMap((t) => t.fields);\n if (!ownFields.some((f) => f.sensitivity !== \"internal\")) say(\"tables\", \"Every field says internal. Mark what is really confidential or restricted (a phone, a gate code, a diagnosis).\");\n else if (ownFields.filter((f) => f.sensitivity !== \"internal\").length < 0.2 * ownFields.length) {\n say(\"tables\", `Only ${ownFields.filter((f) => f.sensitivity !== \"internal\").length} of ${ownFields.length} fields say anything but internal; at least 20% of a real business's columns are public, confidential or restricted.`);\n }\n // S1 is shown by a governed field that holds real values and that a person meets on a view or a form.\n const governed = own.some((t) =>\n t.fields.some((f) => {\n if (!((f.sensitivity === \"restricted\" || f.sensitivity === \"confidential\") && f.contextPolicy === \"exclude\")) return false;\n const held = t.rows.filter((r) => filled(r.values?.[f.key])).length;\n const met =\n (spec.views ?? []).some((v) => v.table === t.token && !(v.hiddenFields ?? []).includes(f.key)) ||\n (spec.forms ?? []).some((fm) => fm.table === t.token && fm.fields.some((ff) => ff.fieldKey === f.key));\n return t.rows.length > 0 && held >= 0.8 * t.rows.length && met;\n }),\n );\n\n // ── shared blocks: seeded, referenced, never copied ─────────────────────────\n (spec.sharedBlocks ?? []).forEach((use, i) => {\n const at = `sharedBlocks[${i}]`;\n const block = SHARED_BLOCKS[use.block];\n if (!block) return say(`${at}.block`, `\"${use.block}\" is not a shared block: ${SHARED_BLOCK_IDS.join(\", \")}.`);\n if (own.some((t) => t.token === block.table)) say(at, `The template declares its own \"${block.table}\" table; the shared block is that table — drop the copy.`);\n if (!use.rows?.length) say(`${at}.rows`, \"Seed the block with this business's own people, so 'assigned to' columns are filled.\");\n if (!own.some((t) => t.fields.some((f) => isRelation(f) && f.relationTarget === block.table))) say(at, `Nothing points at \"${block.table}\"; reference the block with a relation field.`);\n });\n own.forEach((table, ti) => {\n for (const id of SHARED_BLOCK_IDS) {\n const block = SHARED_BLOCKS[id];\n // Similar by TYPE and by the words of the label: \"Cell phone\" is the block's Mobile,\n // \"Hired on\" its Start date, \"Technician name\" its Name.\n const hits = block.fields.filter((bf) => table.fields.some((f) => behaviorOf(f) === behaviorOf(bf) && labelMeans(f, bf.sameAs as readonly string[])));\n // A copy plays the TEAM's role: a hire/start date, pay, or staff roles on a table that is\n // nobody's contact list. A customer's contacts (name, role, email, phone on a table linked\n // to a client/customer/account) are the customer's people, not a copy of the team.\n const hired = hits.some((h) => h.key === \"start_date\");\n // \"Pay\" is what the business pays them (a wage, a pay rate) — never a candidate's asking salary.\n const paid = table.fields.some((f) => /(^|_)(pay|wage|wages|hourly_rate|pay_rate)($|_)/.test(f.key));\n // People who belong to some record of this business (a client, an account, a pool) are\n // that record's contacts; the team belongs to no record.\n const contactOfSomeone = table.fields.some((f) => isRelation(f) && f.relationTarget && f.relationTarget !== block.table && own.some((t) => t.token === f.relationTarget));\n const staffOnly = hired || (paid && hits.some((h) => h.key === \"role\")) || (hits.some((h) => h.key === \"role\") && !contactOfSomeone);\n if (hits.length >= block.copyThreshold && staffOnly) {\n say(`tables[${ti}] (${table.token})`, `This table copies the shared \"${id}\" block (${hits.map((h) => h.label).join(\", \")}). Seed the block in sharedBlocks and point a relation field at it.`);\n }\n }\n });\n\n // ── surface tokens are unique ───────────────────────────────────────────────\n const surfaces = new Map<string, { at: string; table?: string }>();\n const claim = (token: string, at: string, table?: string) => {\n if (surfaces.has(token)) say(at, `The token \"${token}\" is used by ${surfaces.get(token)?.at} too; every view, form and extra has its own.`);\n else surfaces.set(token, { at, ...(table ? { table } : {}) });\n };\n\n // ── views ───────────────────────────────────────────────────────────────────\n const views = spec.views ?? [];\n if (views.length < 3) sayGallery(\"views\", `A template shows at least three views; this one has ${views.length}.`);\n if (!views.some((v) => v.kind === \"grid\")) sayGallery(\"views\", \"One of the views is a grid — the table everyone recognises.\");\n views.forEach((view: TemplateView, i) => {\n const at = `views[${i}] (${view.token})`;\n claim(view.token, at, view.table);\n if (!(TEMPLATE_VIEW_KINDS as readonly string[]).includes(view.kind)) return say(`${at}.kind`, `\"${view.kind}\" is not a view kind.`);\n if (!byToken.has(view.table)) return say(`${at}.table`, `The view looks at \"${view.table}\", which this template does not declare.`);\n const need = (prop: string, key: string | undefined, ok: ((f: TemplateField) => boolean) | null, what: string) => {\n if (!key) return say(`${at}.${prop}`, `A ${view.kind} view needs ${what}.`);\n const f = fieldOf(view.table, key);\n if (!f) return say(`${at}.${prop}`, `\"${view.table}\" does not declare a field \"${key}\".`);\n if (ok && !ok(f)) say(`${at}.${prop}`, `\"${key}\" is a ${f.parityType} field; this needs ${what}.`);\n };\n if (view.kind === \"kanban\") {\n need(\"groupBy\", view.groupBy, isChoice, \"a choice field to make columns from\");\n if (view.swimlaneBy) {\n if (view.swimlaneBy === view.groupBy) say(`${at}.swimlaneBy`, \"Swimlanes cut across the columns, so they are never the column field itself.\");\n need(\"swimlaneBy\", view.swimlaneBy, null, \"a field to cut lanes by\");\n }\n if (view.measure) need(\"measure\", view.measure, (f) => isNumberish(view.table, f), \"a number field to total\");\n } else if (view.kind === \"calendar\") need(\"dateField\", view.dateField, isDate, \"a date field to place records by\");\n else if (view.kind === \"gallery\") need(\"coverField\", view.coverField, (f) => f.parityType === \"attachment\", \"a file field for each card's picture\");\n else if (view.kind === \"timeline\") {\n need(\"startField\", view.startField, isDate, \"a start date\");\n need(\"endField\", view.endField, isDate, \"an end date\");\n } else if (view.groupBy) need(\"groupBy\", view.groupBy, null, \"a field to group rows by\");\n for (const key of Object.keys(view.filters ?? {})) if (!fieldOf(view.table, key)) say(`${at}.filters.${key}`, `It filters on \"${key}\", which \"${view.table}\" does not declare.`);\n for (const [key, vals] of Object.entries(view.anyOf ?? {})) {\n const f = fieldOf(view.table, key);\n if (!f) {\n say(`${at}.anyOf.${key}`, `It filters on \"${key}\", which \"${view.table}\" does not declare.`);\n continue;\n }\n if (key in (view.filters ?? {})) say(`${at}.anyOf.${key}`, `\"${key}\" is in both filters and anyOf; keep it in one.`);\n if (!Array.isArray(vals) || vals.length < 2) say(`${at}.anyOf.${key}`, \"anyOf lists two or more values; one value is a plain filter.\");\n if (f.multi || f.parityType === \"multi_select\" || isRelation(f) || isComputed(f)) say(`${at}.anyOf.${key}`, `\"${f.label}\" is a list, a link or computed; anyOf compares one stored value.`);\n for (const v of vals ?? []) if (f.choices?.length && !f.choices.includes(v)) say(`${at}.anyOf.${key}`, `\"${v}\" is not one of \"${f.label}\"'s choices.`);\n }\n (view.sorts ?? []).forEach((s, si) => {\n if (!fieldOf(view.table, s.field)) say(`${at}.sorts[${si}]`, `It sorts by \"${s.field}\", which \"${view.table}\" does not declare.`);\n });\n for (const key of view.hiddenFields ?? []) if (!fieldOf(view.table, key)) say(`${at}.hiddenFields`, `It hides \"${key}\", which \"${view.table}\" does not declare.`);\n });\n for (const table of tables) {\n const defaults = views.filter((v) => v.table === table.token && v.isDefault).length;\n if (defaults > 1) say(\"views\", `\"${table.token}\" has ${defaults} default views; a table opens on one.`);\n }\n\n // ── forms ───────────────────────────────────────────────────────────────────\n const forms = spec.forms ?? [];\n if (!forms.length) say(\"forms\", \"A template carries at least one form with its questions written out.\");\n const checkQuestions = (at: string, table: string, questions: { fieldKey: string; ask: string }[] | undefined) => {\n if (!questions?.length) return say(at, \"It has to ask something.\");\n questions.forEach((qq, qi) => {\n if (!fieldOf(table, qq.fieldKey)) say(`${at}[${qi}]`, `It asks for \"${qq.fieldKey}\", which \"${table}\" does not declare.`);\n if (!qq.ask?.trim() || qq.ask.trim().length < 6) say(`${at}[${qi}].ask`, `Write the question as it is asked — \"What brings you in today?\" — not just the column name.`);\n });\n };\n forms.forEach((form, i) => {\n const at = `forms[${i}] (${form.token})`;\n claim(form.token, at, form.table);\n if (!byToken.has(form.table)) say(`${at}.table`, `The form collects into \"${form.table}\", which this template does not declare.`);\n else checkQuestions(`${at}.fields`, form.table, form.fields);\n if (!form.confirmation?.trim()) say(`${at}.confirmation`, \"Say what the person sees after they submit, in real words.\");\n });\n\n // ── dimensions, as custom._table_dimensions_check judges them ───────────────\n const pathsByTable = new Map<string, Set<string>>();\n (spec.dimensions ?? []).forEach((dim, i) => {\n const at = `dimensions[${i}] (${dim.table})`;\n const table = byToken.get(dim.table);\n if (!table) return say(`${at}.table`, `There is no table \"${dim.table}\" in this template.`);\n // custom._table_dimensions_infer(every field)\n const dimKeys = new Set<string>([\"created_at\", \"updated_at\"]);\n const inferredMeasures = new Set<string>([\"count\"]);\n for (const f of table.fields) {\n const b = behaviorOf(f);\n if (b === \"list\" && !f.multi && f.parityType !== \"multi_select\") dimKeys.add(f.key);\n else if (b === \"relation\" && f.parityType !== \"attachment\" && !f.multi && (f.relationMax ?? 1) === 1) dimKeys.add(f.key);\n else if (b === \"boolean\") dimKeys.add(f.key);\n else if (isDate(f)) dimKeys.add(f.key);\n else if (b === \"range\") {\n const ops = f.parityType === \"percent\" ? [\"avg\", \"min\", \"max\"] : [\"sum\", \"avg\", \"min\", \"max\"];\n for (const op of ops) inferredMeasures.add(`${op}_${f.key}`);\n inferredMeasures.add(`filled_${f.key}`);\n }\n }\n (dim.dimensions ?? []).forEach((d, di) => {\n if (!dimKeys.has(d.key)) say(`${at}.dimensions[${di}]`, `\"${d.key}\" is not a dimension of \"${dim.table}\". Its dimensions are: ${[...dimKeys].join(\", \")}.`);\n if (d.label !== undefined && (d.label.trim().length < 1 || d.label.trim().length > 80)) say(`${at}.dimensions[${di}]`, \"A dimension's name is 1 to 80 characters.\");\n });\n const newMeasures = new Set<string>();\n (dim.measures ?? []).forEach((m, mi) => {\n const mat = `${at}.measures[${mi}]`;\n if (!MEASURE_KEY.test(m.key)) say(mat, `\"${m.key}\" is not a measure key the store accepts.`);\n if (m.label !== undefined && (m.label.trim().length < 1 || m.label.trim().length > 80)) say(mat, \"A measure's name is 1 to 80 characters.\");\n if (inferredMeasures.has(m.key)) {\n if (m.op || m.of) say(mat, `\"${m.key}\" is worked out from the table's own column, so only its name can change, or it can be hidden.`);\n return;\n }\n if (!m.op || !AGG_OPERATIONS.includes(m.op) || (m.op as string) === \"count\") say(mat, `The measure \"${m.key}\" needs one of: ${AGG_OPERATIONS.filter((o) => o !== \"count\").join(\", \")}.`);\n const of = m.of ? fieldOf(dim.table, m.of) : undefined;\n if (!of) say(mat, `The measure \"${m.key}\" reads \"${m.of ?? \"(nothing)\"}\", which is not a column of \"${dim.table}\".`);\n // The store's dimension check (custom._table_dimensions_check) totals only a STORED number column\n // (type range, not a date): a formula, lookup or rollup is refused at install even when it is money.\n else if (m.op && [\"sum\", \"avg\", \"min\", \"max\", \"median\"].includes(m.op) && !(isNumber(of) && !isComputed(of))) say(mat, isComputed(of) ? `\"${m.of}\" is worked out, and a dimension totals only a number that is typed in; total the stored columns it is made from.` : `\"${m.of}\" is not a number, so it cannot be added up or averaged.`);\n if (newMeasures.has(m.key)) say(mat, `Two measures are both called \"${m.key}\".`);\n newMeasures.add(m.key);\n });\n const paths = new Set<string>(dimKeys.has(\"created_at\") ? [\"created_at\"] : []);\n for (const f of table.fields) if (isDate(f)) paths.add(f.key);\n (dim.paths ?? []).forEach((p, pi) => {\n if (!MEASURE_KEY.test(p.key) || !p.levels?.length) return say(`${at}.paths[${pi}]`, `A drill path has a key and at least one level, so \"${p.key}\" was not saved.`);\n for (const level of p.levels) {\n const [key, grain] = level.split(\":\");\n if (!key || !dimKeys.has(key) || (level.includes(\":\") && !BUCKETS.includes(grain ?? \"\"))) {\n say(`${at}.paths[${pi}]`, `The drill path \"${p.key}\" names \"${level}\", which is not a dimension of \"${dim.table}\" (a date takes :year, :quarter, :month, :week or :day).`);\n }\n }\n paths.add(p.key);\n });\n pathsByTable.set(dim.table, paths);\n for (const by of dim.default?.by ?? []) if (!dimKeys.has(by.split(\":\")[0] ?? \"\")) say(`${at}.default.by`, `The first screen groups by \"${by}\", which is not a dimension.`);\n for (const show of dim.default?.show ?? []) if (!inferredMeasures.has(show) && !newMeasures.has(show)) say(`${at}.default.show`, `The first screen shows \"${show}\", which is not a measure of this table.`);\n });\n\n // ── merge fields: only {{field_key}} of the one table (custom.doc_render_body) ──\n const checkMerge = (at: string, table: string, text: string) => {\n for (const m of text.matchAll(MERGE_TOKEN)) {\n const key = m[1] ?? \"\";\n const f = fieldOf(table, key);\n if (!f) say(at, `{{${key}}} does not resolve: the store merges only the fields of \"${table}\" (no today, no business details).`);\n else if (f.parityType === \"signature\") say(at, `{{${key}}} is a signature, and a signature never merges into the body.`);\n }\n };\n\n // ── extras ──────────────────────────────────────────────────────────────────\n const extras = spec.extras ?? [];\n if (extras.length < 2) sayGallery(\"extras\", `A template carries at least two extras; this one has ${extras.length}.`);\n const formTokens = new Set(forms.map((f) => f.token));\n const viewTokens = new Set(views.map((v) => v.token));\n const docTokens = new Set(extras.filter((e) => e.kind === \"document\").map((e) => e.token));\n const honestCharts = new Map<string, number>();\n const stageRules = new Map<string, Extract<TemplateSpec[\"extras\"][number], { kind: \"stage_rules\" }>>();\n extras.forEach((extra, i) => {\n const at = `extras[${i}] (${extra.kind}:${extra.token})`;\n const extraTable = \"table\" in extra ? extra.table : extra.kind === \"portal\" ? extra.clientTable : extra.kind === \"checklist\" ? extra.aboutTable : undefined;\n claim(extra.token, at, extraTable);\n const needTable = (table: string, prop = \"table\") => {\n if (byToken.has(table)) return true;\n say(`${at}.${prop}`, `It names \"${table}\", which this template does not declare.`);\n return false;\n };\n switch (extra.kind) {\n case \"booking\": {\n if (needTable(extra.table)) checkQuestions(`${at}.questions`, extra.table, extra.questions);\n const a = extra.availability;\n if (!a?.windows?.length) say(`${at}.availability`, \"A booking page offers at least one window of time.\");\n a?.windows?.forEach((w, wi) => {\n if (w.weekday < 0 || w.weekday > 6) say(`${at}.availability.windows[${wi}]`, \"A weekday is 0 (Sunday) to 6 (Saturday).\");\n if (!(w.from < w.to)) say(`${at}.availability.windows[${wi}]`, `\"${w.to}\" has to be later in the day than \"${w.from}\".`);\n });\n if (!a?.slotMinutes || a.slotMinutes < 5) say(`${at}.availability.slotMinutes`, \"Say how long one appointment is, in minutes.\");\n break;\n }\n case \"portal\": {\n needTable(extra.clientTable, \"clientTable\");\n if (!extra.tables?.length) say(`${at}.tables`, \"A portal shows its client at least one table.\");\n extra.tables?.forEach((pt, pi) => {\n const pat = `${at}.tables[${pi}]`;\n if (!needTable(pt.table, `tables[${pi}].table`)) return;\n const via = pt.namesVia ? fieldOf(pt.table, pt.namesVia) : undefined;\n if (!via || !isRelation(via) || via.relationTarget !== extra.clientTable) {\n say(pat, `namesVia must be the relation field of \"${pt.table}\" that points at the client table \"${extra.clientTable}\" — it is what makes \"only theirs\" answerable.`);\n }\n if (!pt.visibleFields?.length) say(pat, \"A portal table shows at least one field.\");\n for (const key of [...new Set([...(pt.visibleFields ?? []), ...(pt.editableFields ?? [])])]) {\n const f = fieldOf(pt.table, key);\n if (!f) {\n say(pat, `It shows \"${key}\", which \"${pt.table}\" does not declare.`);\n continue;\n }\n const e = effective(pt.table, f);\n // A portal shows a client only their own rows (namesVia), so their own confidential\n // details may go out; restricted fields and fields kept from the AI never do.\n if (e.sensitivity === \"restricted\" || e.contextPolicy === \"exclude\") {\n say(pat, `\"${f.label}\" is ${e.contextPolicy === \"exclude\" ? \"kept from the AI\" : \"restricted\"}${f.parityType === \"lookup\" ? \" (through what it looks up)\" : \"\"}; a portal shows a client fields up to confidential, never restricted or kept-from-AI ones.`);\n }\n }\n if (pt.namesVia && pt.editableFields?.includes(pt.namesVia)) say(pat, `\"${pt.namesVia}\" is what makes the records theirs, so a client can never edit it.`);\n for (const key of pt.editableFields ?? []) if (!pt.visibleFields?.includes(key)) say(pat, `\"${key}\" is editable in the portal but not visible there.`);\n });\n for (const f of extra.forms ?? []) if (!formTokens.has(f)) say(`${at}.forms`, `It offers the form \"${f}\", which this template does not declare.`);\n break;\n }\n case \"dashboard\": {\n needTable(extra.table);\n let charts = 0;\n extra.blocks?.forEach((b, bi) => {\n const table = b.table ?? extra.table;\n if (!byToken.has(table)) return say(`${at}.blocks[${bi}]`, `It reads \"${table}\", which this template does not declare.`);\n let honest = true;\n for (const m of b.measures ?? []) {\n const f = m.key ? fieldOf(table, m.key) : undefined;\n if (f && [\"sum\", \"avg\", \"min\", \"max\", \"median\"].includes(m.op) && !isNumberish(table, f)) {\n honest = false;\n say(`${at}.blocks[${bi}]`, `\"${b.title}\" takes the ${m.op} of \"${f.label}\", which is not a number.`);\n }\n }\n if (b.bucket) {\n const f = fieldOf(table, b.bucket.key);\n if (f && !isDate(f)) {\n honest = false;\n say(`${at}.blocks[${bi}]`, `\"${b.title}\" cuts time by \"${f.label}\", which is not a date.`);\n }\n }\n for (const g of b.groupBy ?? []) {\n const vals = new Set((byToken.get(table)?.rows ?? []).map((r) => storeText(r.values?.[g])).filter((v) => v !== null && v !== \"\"));\n if (fieldOf(table, g) && vals.size < 2) {\n honest = false;\n saySeed(`${at}.blocks[${bi}]`, `\"${b.title}\" groups by \"${g}\", which holds ${vals.size} distinct value(s) in the seed — a chart of one bar.`);\n }\n }\n if (honest && CHART_BLOCK_KINDS.has(b.kind)) charts += 1;\n for (const key of [\n ...(b.groupBy ?? []),\n ...(b.measures ?? []).map((m) => m.key).filter((k): k is string => !!k),\n ...(b.bucket ? [b.bucket.key] : []),\n ...(b.stateKey ? [b.stateKey] : []),\n ...Object.keys(b.filter ?? {}),\n ]) {\n if (!fieldOf(table, key)) say(`${at}.blocks[${bi}]`, `\"${b.title}\" reads \"${key}\", which \"${table}\" does not declare.`);\n }\n if (b.kind === \"stuck\" && !b.stateKey) say(`${at}.blocks[${bi}]`, \"A 'stuck' block names the field it watches.\");\n if (!b.title?.trim()) say(`${at}.blocks[${bi}]`, \"Every block has a title the owner reads.\");\n });\n honestCharts.set(extra.token, charts);\n const sigs = new Set<string>();\n for (const blk of extra.blocks ?? []) {\n const sig = JSON.stringify([blk.kind, blk.table ?? extra.table, blk.groupBy ?? [], blk.measures ?? [], blk.bucket ?? null, blk.filter ?? null]);\n if (sigs.has(sig)) say(`${at}.blocks`, `\"${blk.title}\" draws the same chart as another block on this dashboard.`);\n sigs.add(sig);\n }\n if (charts < 2) saySeed(`${at}.blocks`, `A dashboard here shows at least two honest charts (bar, column, line or donut over real numbers, dates and groups); this one has ${charts}.`);\n break;\n }\n case \"drill_down\":\n if (needTable(extra.table) && !pathsByTable.get(extra.table)?.has(extra.path)) say(`${at}.path`, `\"${extra.path}\" is not a drill path in the dimensions of \"${extra.table}\".`);\n break;\n case \"digest\":\n if (!viewTokens.has(extra.view)) say(`${at}.view`, `The digest sends the view \"${extra.view}\", which this template does not declare.`);\n if (![\"instant\", \"hourly\", \"daily\", \"weekly\"].includes(extra.cadence)) say(`${at}.cadence`, \"A digest is instant, hourly, daily or weekly.\");\n if (extra.cadence !== \"instant\" && !extra.schedule) say(`${at}.schedule`, \"Say when it goes out — 'monday 08:00'.\");\n break;\n case \"checklist\": {\n needTable(extra.aboutTable, \"aboutTable\");\n const roles = new Set((extra.roles ?? []).map((r) => r.role));\n const refs = new Set<string>();\n if (!extra.steps?.length) say(`${at}.steps`, \"A checklist has steps.\");\n extra.steps?.forEach((s, si) => {\n const sat = `${at}.steps[${si}] (${s.ref})`;\n if (refs.has(s.ref)) say(sat, `Two steps are both \"${s.ref}\".`);\n for (const dep of s.dependsOn ?? []) if (!refs.has(dep)) say(sat, `It waits for \"${dep}\", which is not a step above it.`);\n refs.add(s.ref);\n if (s.role && !roles.has(s.role)) say(sat, `It belongs to the role \"${s.role}\", which the checklist does not declare.`);\n const r = s.requires;\n if (r?.kind === \"form\" && !formTokens.has(r.form)) say(sat, `It is the form \"${r.form}\", which this template does not declare.`);\n if (r?.kind === \"document\" && !docTokens.has(r.document)) say(sat, `It is the document \"${r.document}\", which this template does not declare.`);\n if (r?.kind === \"record_field\" && !fieldOf(extra.aboutTable, r.key)) say(sat, `It needs \"${r.key}\" filled, which \"${extra.aboutTable}\" does not declare.`);\n });\n const t = extra.trigger;\n if (t && t.kind !== \"manual\" && needTable(t.table, \"trigger.table\") && t.kind === \"status_reached\") {\n if (!byToken.get(t.table)?.fields.some((f) => f.choices?.includes(t.status))) say(`${at}.trigger.status`, `No choice field of \"${t.table}\" has the status \"${t.status}\".`);\n }\n break;\n }\n case \"document\":\n if (!needTable(extra.table)) break;\n checkMerge(`${at}.title`, extra.table, extra.title ?? \"\");\n checkMerge(`${at}.body`, extra.table, extra.body ?? \"\");\n if ((extra.body ?? \"\").length < 80) say(`${at}.body`, \"Write the prose this business would really send, not a stub.\");\n if (!extra.describes?.trim()) say(`${at}.describes`, \"Say what the document is for.\");\n if (extra.signature && !fields.some((f) => f.parityType === \"signature\")) say(`${at}.signature`, \"A document sent for signature needs a signature field on its table.\");\n break;\n case \"notification\":\n if (!needTable(extra.when.table, \"when.table\")) break;\n if (extra.when.field && !fieldOf(extra.when.table, extra.when.field)) say(`${at}.when.field`, `\"${extra.when.table}\" does not declare a field \"${extra.when.field}\".`);\n if (extra.when.event === \"stage_entered\" && !byToken.get(extra.when.table)?.fields.some((f) => f.choices?.includes(extra.when.stage ?? \"\"))) {\n say(`${at}.when.stage`, `\"${extra.when.stage}\" is not a stage of \"${extra.when.table}\".`);\n }\n checkMerge(`${at}.message`, extra.when.table, extra.message ?? \"\");\n if (!extra.audience?.trim()) say(`${at}.audience`, \"Say who it reaches, in the business's own words.\");\n break;\n case \"stage_rules\": {\n if (!needTable(extra.table)) break;\n const stage = fieldOf(extra.table, extra.stageField);\n if (!stage?.choices?.length) {\n say(`${at}.stageField`, `\"${extra.stageField}\" has to be a choice field of \"${extra.table}\".`);\n break;\n }\n stageRules.set(`${extra.table}.${extra.stageField}`, extra);\n const stages = new Set(stage.choices);\n const known = (s: string, where: string) => {\n if (!stages.has(s)) say(`${at}.${where}`, `\"${s}\" is not one of \"${extra.stageField}\"'s choices.`);\n };\n for (const s of stage.choices) if (!extra.stages?.[s]?.trim()) say(`${at}.stages`, `Say what is true of a record sitting in \"${s}\".`);\n for (const s of Object.keys(extra.stages ?? {})) known(s, \"stages\");\n for (const t of extra.transitions ?? []) {\n known(t.from, \"transitions\");\n known(t.to, \"transitions\");\n }\n for (const [s, keys] of Object.entries(extra.requires ?? {})) {\n known(s, \"requires\");\n for (const k of keys) if (!fieldOf(extra.table, k)) say(`${at}.requires`, `Landing in \"${s}\" needs \"${k}\", which \"${extra.table}\" does not declare.`);\n }\n for (const s of Object.keys(extra.limits ?? {})) known(s, \"limits\");\n if (!extra.transitions?.length) say(`${at}.transitions`, \"List the moves the board allows (from → to); without them any card can jump to any stage.\");\n for (const [st, need] of Object.entries(extra.requiresChild ?? {})) {\n known(st, \"requiresChild\");\n const rel = fieldOf(need.table, need.relation);\n if (!rel || rel.relationTarget !== extra.table) say(`${at}.requiresChild`, `\"${need.table}.${need.relation}\" has to be a relation of \"${need.table}\" pointing at \"${extra.table}\".`);\n if (need.field && !fieldOf(need.table, need.field)) say(`${at}.requiresChild`, `\"${need.table}\" does not declare \"${need.field}\".`);\n }\n {\n const seedRows = (byToken.get(extra.table)?.rows ?? []).filter((r) => !(r as { archived?: boolean }).archived);\n for (const [st, keys] of Object.entries(extra.requires ?? {})) {\n for (const k of keys) {\n if (seedRows.length && seedRows.every((r) => filled(r.values?.[k]))) {\n say(`${at}.requires`, `\"${st}\" requires \"${k}\", but every seed row already has it, so the rule never refuses anything. Leave it empty on rows before \"${st}\".`);\n }\n }\n }\n for (const [x, keys] of inferredImplies(extra.table, extra.stageField)) {\n for (const k of keys) {\n const declared = (byToken.get(extra.table)?.statusImplies ?? []).some((r) => r.field === extra.stageField && r.when.includes(x) && (r.filled ?? []).includes(k));\n if (!declared) say(`${at}.stages`, `Every \"${x}\" row has \"${fieldOf(extra.table, k)?.label ?? k}\" and no earlier one does; declare it: statusImplies {field: \"${extra.stageField}\", when: [\"${x}\"], filled: [\"${k}\"]}.`);\n }\n }\n // A paid / done stage with its own date field: statusImplies keeps the two together.\n const implies = byToken.get(extra.table)?.statusImplies ?? [];\n for (const st of stage.choices) {\n for (const [stageWord, fieldWord] of [[/\\b(?:paid|settled)\\b/i, /^(?:paid|paid_on|paid_at|paid_date|date_paid|settled_on)$/], [/\\b(?:done|completed?|finished)\\b/i, /^(?:completed_on|completed_at|done_on|done_at|finished_on|finished_at|date_completed)$/]] as const) {\n if (!stageWord.test(st)) continue;\n for (const pf of byToken.get(extra.table)?.fields ?? []) {\n if (!fieldWord.test(pf.key)) continue;\n const covered = implies.some((r) => r.field === extra.stageField && r.when.includes(st) && (r.filled ?? []).includes(pf.key));\n if (!covered) say(`${at}.stages`, `\"${st}\" has its own \"${pf.label}\" field; add statusImplies {field: \"${extra.stageField}\", when: [\"${st}\"], filled: [\"${pf.key}\"]} so the two never disagree.`);\n }\n }\n }\n }\n for (const [st, rule] of Object.entries(extra.stageDates ?? {})) {\n const why = extra.anyBecause?.[st]?.trim() ?? \"\";\n if (rule === \"any\" && TIME_BOUND_STAGE.test(st) && why.split(/\\s+/).length < 6) {\n say(`${at}.anyBecause`, `\"${st}\" says when something happened, so its date is not \"any\" without a reason; say why in anyBecause (a sentence of six words or more), or give it past, today or future.`);\n }\n }\n for (const t of extra.transitions ?? []) {\n if (!TERMINAL_STAGE.test(t.from)) continue;\n const declared = (extra.reopen ?? []).find((r) => r.from === t.from && r.to === t.to);\n if (!declared || declared.because.trim().split(/\\s+/).length < 6) {\n say(`${at}.transitions`, `\"${t.from}\" → \"${t.to}\" moves a record out of a finished stage; declare it in reopen with the business reason (a rebooked guest, a revived deal), or drop it.`);\n }\n }\n break;\n }\n case \"row_action\":\n if (!needTable(extra.table)) break;\n if (!extra.name?.trim()) say(`${at}.name`, \"Name the button the way the staff would say it.\");\n if (extra.actionKind === \"update\") {\n if (!extra.steps?.length) say(`${at}.steps`, \"An update action writes at least one field.\");\n for (const step of extra.steps ?? []) {\n const f = fieldOf(extra.table, step.field);\n if (!f) say(`${at}.steps`, `It writes \"${step.field}\", which \"${extra.table}\" does not declare.`);\n else if (step.set === \"value\" && f.choices?.length && typeof step.value === \"string\" && !f.choices.includes(step.value)) say(`${at}.steps`, `\"${step.value}\" is not one of \"${step.field}\"'s choices.`);\n }\n } else if (!extra.prompt?.trim()) say(`${at}.prompt`, \"An agent action says what the record chat opens with.\");\n break;\n case \"automation\":\n if (needTable(extra.when.table, \"when.table\") && extra.when.field && !fieldOf(extra.when.table, extra.when.field)) say(`${at}.when.field`, `\"${extra.when.table}\" does not declare a field \"${extra.when.field}\".`);\n if (!extra.then?.trim()) say(`${at}.then`, \"Say what happens, in the business's words.\");\n break;\n default:\n say(at, `\"${(extra as { kind: string }).kind}\" is not an extra a template can carry.`);\n }\n });\n\n // ── the agent: snapshot, variables, and Q6 with the store's semantics ────────\n const agent = spec.agent;\n if (!agent) say(\"agent\", \"Every template ships one agent: a copy of a platform agent with its variables bound to these tables.\");\n else {\n const snap = options.agents;\n const row = snap?.find((a) => a.id === agent.platformAgent?.id);\n if (!snap) say(\"agent.platformAgent\", \"No agent catalogue snapshot was given, so the agent could not be checked (pass templates/AGENTS.snapshot.json).\");\n else if (!row) say(\"agent.platformAgent\", `\"${agent.platformAgent?.id}\" is not in the agent catalogue snapshot.`);\n else if (row.name !== agent.platformAgent.name) say(\"agent.platformAgent\", `The snapshot calls ${row.id} \"${row.name}\", not \"${agent.platformAgent.name}\".`);\n if (agent.platformAgent?.id !== DEFAULT_TEMPLATE_AGENT.id && (agent.agentReason?.trim().split(/\\s+/).length ?? 0) < 8) {\n say(\"agent.platformAgent\", `A template's agent is \"${DEFAULT_TEMPLATE_AGENT.name}\" (${DEFAULT_TEMPLATE_AGENT.id}); say in agentReason, in a full sentence of at least eight words, why this one needs \"${agent.platformAgent?.name}\" instead.`);\n }\n if (!agent.variables?.length) say(\"agent.variables\", \"An agent without variables is not an agent: bind at least one to a table.\");\n agent.variables?.forEach((v, vi) => {\n if (!byToken.has(v.table)) say(`agent.variables[${vi}]`, `It binds \"${v.name}\" to \"${v.table}\", which this template does not declare.`);\n if (row && !row.variables.includes(v.name)) say(`agent.variables[${vi}]`, `\"${row.name}\" has no variable \"${v.name}\"; its variables are: ${row.variables.join(\", \") || \"(none)\"}.`);\n });\n const qq = agent.question;\n if (!qq?.ask?.trim().endsWith(\"?\")) say(\"agent.question.ask\", \"Write the question a person would really type, ending in a question mark.\");\n if (!qq?.whyItMatters?.trim()) say(\"agent.question.whyItMatters\", \"Say what the owner does differently depending on the answer.\");\n const qt = qq?.expect ? byToken.get(qq.expect.table) : undefined;\n if (!qt) say(\"agent.question.expect.table\", `The answer is read from \"${qq?.expect?.table}\", which this template does not declare.`);\n else {\n const m = qq.expect.measure;\n if (![\"count\", \"sum\", \"avg\", \"min\", \"max\"].includes(m.op)) say(\"agent.question.expect.measure\", \"The scripted question is a count, sum, average, lowest or highest.\");\n if (m.op !== \"count\") {\n const f = m.key ? fieldOf(qt.token, m.key) : undefined;\n if (!f) say(\"agent.question.expect.measure\", `A ${m.op} names a field of \"${qt.token}\".`);\n else if (!agentReads(qt.token, f)) say(\"agent.question.expect.measure\", `The agent cannot read \"${f.label}\", so it can never answer a question about it.`);\n else if (isComputed(f)) {\n const w = withComputed(qt.token, f.key, qt.rows.map((r) => ({ key: r.key, values: r.values })));\n if (\"why\" in w) say(\"agent.question.expect.measure\", `${w.why}; ask about a stored field, a lookup, or + − × ÷ / DATEDIFF formula.`);\n }\n }\n const filter = qq.expect.filter;\n if (m.op === \"count\" && !Object.keys(filter ?? {}).length) say(\"agent.question.expect.filter\", \"\\\"How many rows are there\\\" teaches nothing; filter the count to a real question.\");\n for (const [key, want] of Object.entries(filter ?? {})) {\n const f = fieldOf(qt.token, key);\n if (!f) {\n say(\"agent.question.expect.filter\", `It filters on \"${key}\", which \"${qt.token}\" does not declare.`);\n continue;\n }\n if (!agentReads(qt.token, f)) say(\"agent.question.expect.filter\", `The agent cannot read \"${f.label}\", so it cannot filter by it.`);\n // custom.record_filter_sql reads a worked-out column the way the record read does\n // (agg_field_value_sql), so a lookup filters the store's way; the gate mirrors lookups.\n if (isComputed(f) && f.parityType !== \"lookup\") say(\"agent.question.expect.filter\", `\"${f.label}\" is computed by the store (${f.parityType}); filter on a stored field or a lookup.`);\n const rawWant = raw.agent?.question?.expect?.filter?.[key];\n if (rawWant !== null && typeof rawWant === \"object\") {\n for (const [k, bound] of Object.entries(rawWant as Record<string, unknown>)) {\n if (typeof bound !== \"string\" || !relativeHasTime(bound)) {\n say(\"agent.question.expect.filter\", `The window's ${k} is \"${String(bound)}\". Write it as a relative token with a time (\"@today-7d 00:00\"): an absolute bound goes stale, and a bare date is read in the server's zone, not the business's.`);\n }\n }\n }\n if (f.multi || f.parityType === \"multi_select\" || isRelation(f)) say(\"agent.question.expect.filter\", `\"${f.label}\" holds a list or a link; the store compares its whole stored text, so it cannot be a filter here.`);\n if (want !== null && typeof want === \"object\") {\n if (!isDate(f)) say(\"agent.question.expect.filter\", `A window filters a date; \"${f.label}\" is not one.`);\n for (const k of Object.keys(want)) if (k !== \"from\" && k !== \"to\") say(\"agent.question.expect.filter\", `\"${k}\" is not part of a window (from, to).`);\n }\n }\n const seed = qt.rows.map((r) => ({ key: r.key, values: r.values }));\n if (filter && Object.keys(filter).length && seed.length) {\n const share = (storeAggregate(seed, { op: \"count\" }, filter, tz) as { value: number }).value / seed.length;\n if (share >= 0.9) say(\"agent.question.expect.filter\", `The filter keeps ${Math.round(share * 100)}% of the rows, so the question is really \"how many are there\"; ask about a real slice.`);\n }\n const seedC = withComputedKeys(qt.token, [m.key, ...Object.keys(filter ?? {})], seed);\n if (\"why\" in seedC && Object.keys(filter ?? {}).some((k) => fieldOf(qt.token, k)?.parityType === \"lookup\")) say(\"agent.question.expect.filter\", `${seedC.why}.`);\n const outcome = storeAggregate(\"rows\" in seedC ? seedC.rows : seed, m, filter, tz);\n if (!outcome.ok) say(\"agent.question.expect.answer\", outcome.says);\n else if (outcome.value === null || outcome.value === 0) say(\"agent.question.expect.answer\", `The seed rows answer ${outcome.value === null ? \"nothing (null)\" : \"0\"}; ask a question whose answer is a real number.`);\n else if (!outcome.exact) say(\"agent.question.expect.answer\", \"The answer does not come out exact; ask a question whose answer is a whole decimal.\");\n else if (!sameNumber(qq.expect.answer, outcome.value)) {\n say(\"agent.question.expect.answer\", `The seed rows answer ${outcome.value}, but the file says ${qq.expect.answer}. The scripted answer must equal custom.record_aggregate exactly.`);\n }\n if (!qq.expect.unit?.trim()) say(\"agent.question.expect.unit\", \"Say what the number is: USD, visits, days.\");\n }\n }\n\n // ── Kits → Template merge: optional full bindings, extra agents, workflows, guide (./extras) ──\n for (const p of extrasProblems(raw, options.agents)) say(p.at, p.says);\n\n // ── the walk: simulated over the seed, every step non-vacuous ───────────────\n const state = new Map<string, SeedRow[]>(tables.map((t) => [t.token, t.rows.map((r) => ({ key: r.key, values: { ...r.values } }))]));\n const state0 = new Map<string, SeedRow[]>(tables.map((t) => [t.token, t.rows.map((r) => ({ key: r.key, values: r.values }))]));\n const rowIn = (table: string, key: string) => state.get(table)?.find((r) => r.key === key);\n const surfaceRows = (token: string): number | null => {\n const view = views.find((v) => v.token === token);\n if (view) return (state.get(view.table) ?? []).filter((r) => !r.archived && viewMatches(r, view, tz)).length;\n const s = surfaces.get(token);\n return s?.table ? (state.get(s.table) ?? []).filter((r) => !r.archived).length : null;\n };\n const walkLen = spec.walk?.length ?? 0;\n if (walkLen !== 3 && walkLen !== 4) say(\"walk\", \"The teaching card is three steps, plus an optional fourth that asks the agent.\");\n if (walkLen === 4 && spec.walk?.[3]?.action?.kind !== \"ask_agent\") say(\"walk[3]\", \"A fourth step is only ever the question to the agent (ask_agent).\");\n // ── status implies fields (statusImplies), on seed rows and after every walk change ──\n const coherent = (table: string, row: { key: string; values: Record<string, unknown> }, at: string) => {\n // A formula over stored columns is read the store's way; everything else is the stored value.\n const val = (k: string): unknown => {\n const f = fieldOf(table, k);\n if (f?.parityType === \"formula\") {\n const c = computedOf(table, f, row);\n return c.ok ? c.v : undefined;\n }\n return row.values?.[k];\n };\n for (const rule of byToken.get(table)?.statusImplies ?? []) {\n const st = storeText(row.values?.[rule.field]) ?? \"\";\n // A field a later stage reserves is empty while the row is still earlier and not finished.\n const order = fieldOf(table, rule.field)?.choices ?? [];\n const firstWhen = Math.min(...rule.when.map((w) => order.indexOf(w)).filter((n) => n >= 0));\n const here = order.indexOf(st);\n if (here >= 0 && Number.isFinite(firstWhen) && here < firstWhen && !TERMINAL_STAGE.test(st)) {\n for (const k of rule.filled ?? []) {\n // Only a date or a mark records that the stage happened; amounts and choices build up before it.\n if (!/^(?:datetime|date|checkbox|signature|attachment)$/.test(fieldOf(table, k)?.parityType ?? \"\")) continue;\n // An unticked box records nothing: only a ticked one says the stage happened.\n const v = row.values?.[k];\n if (fieldOf(table, k)?.parityType === \"checkbox\" ? v === true || v === \"true\" : filled(v)) say(at, `\"${row.key}\" is ${st}, but already has \"${fieldOf(table, k)?.label ?? k}\", which only a ${rule.when.join(\"/\")} record carries. Leave it empty until the record gets there.`);\n }\n }\n if (!rule.when.includes(st)) continue;\n for (const k of rule.filled ?? []) if (!filled(val(k))) say(at, `\"${row.key}\" is ${st}, so \"${fieldOf(table, k)?.label ?? k}\" is filled; it is empty.`);\n for (const [k, v] of Object.entries(rule.equals ?? {})) {\n const got = val(k) ?? null;\n const same = sameJson(got, v) || (typeof v === \"number\" && parseNumeric(storeText(got) ?? \"\") !== null && qCmp(parseNumeric(storeText(got) ?? \"\")!, parseNumeric(String(v))!) === 0);\n if (!same) say(at, `\"${row.key}\" is ${st}, so \"${fieldOf(table, k)?.label ?? k}\" is ${JSON.stringify(v)}; it is ${JSON.stringify(got)}.`);\n }\n }\n };\n const TERMINAL_STEMS: Array<[RegExp, RegExp]> = [\n [/^paid$/i, /(^|_)(paid|balance)(_|$)/],\n [/^signed$/i, /(^|_)(signed|signature)(_|$)/],\n [/^ordered$/i, /(^|_)ordered(_|$)/],\n [/^completed?$/i, /(^|_)completed?(_|$)/],\n [/^closed$/i, /(^|_)closed(_|$)/],\n [/^issued$/i, /(^|_)issued(_|$)/],\n [/^shipped$/i, /(^|_)shipped(_|$)/],\n [/^delivered$/i, /(^|_)delivered(_|$)/],\n [/^received$/i, /(^|_)received(_|$)/],\n [/^approved$/i, /(^|_)approved(_|$)/],\n [/^sent$/i, /(^|_)sent(_|$)/],\n ];\n for (const t of own) {\n for (const rule of t.statusImplies ?? []) {\n const sf = fieldOf(t.token, rule.field);\n if (!sf?.choices?.length) say(`tables (${t.token}).statusImplies`, `\"${rule.field}\" is not a choice field of \"${t.token}\".`);\n for (const w of rule.when) if (sf?.choices && !sf.choices.includes(w)) say(`tables (${t.token}).statusImplies`, `\"${w}\" is not one of \"${rule.field}\"'s choices.`);\n for (const k of [...(rule.filled ?? []), ...Object.keys(rule.equals ?? {})]) if (!fieldOf(t.token, k)) say(`tables (${t.token}).statusImplies`, `\"${k}\" is not a field of \"${t.token}\".`);\n }\n for (const r of t.rows) coherent(t.token, r, `tables (${t.token}).rows (${r.key})`);\n const statusField = t.fields.find((f) => isChoice(f) && /(^|_)(status|stage)$/.test(f.key));\n for (const c of statusField?.choices ?? []) {\n const stem = TERMINAL_STEMS.find(([word]) => word.test(c.trim()));\n if (!stem) continue;\n const named = t.fields.filter((f) => f.key !== statusField!.key && stem[1].test(f.key));\n const declared = (t.statusImplies ?? []).some((r) => r.field === statusField!.key && r.when.includes(c));\n if (named.length && !declared) say(`tables (${t.token}).statusImplies`, `\"${c}\" is a status and \"${t.token}\" has ${named.map((f) => `\"${f.label}\"`).join(\", \")}; say what \"${c}\" implies about ${named.length === 1 ? \"it\" : \"them\"} (statusImplies), so a ${c} row can never leave ${named.length === 1 ? \"it\" : \"them\"} empty or wrong.`);\n }\n }\n\n const refWeek = [0, 1, 2, 3, 4, 5, 6].map((i) => shiftDays(TEMPLATE_REFERENCE_DATE, i));\n /** The template's own cross-table rules (statusAgrees, withinParent, childDates) over the walk's current rows. */\n const crossBreaks = (): Map<string, string> => {\n const out = new Map<string, string>();\n const live = (token: string) => (state.get(token) ?? []).filter((r) => !r.archived);\n const day = (v: unknown) => {\n const t = storeText(v);\n return t?.startsWith(\"@\") ? (resolveDateToken(t, TEMPLATE_REFERENCE_DATE, tz) ?? \"\").slice(0, 10) || null : dayOfMoment(v);\n };\n const name = (token: string, r: SeedRow) => storeText(r.values?.[byToken.get(token)?.titleField ?? \"\"]) ?? r.key;\n for (const t of own) {\n const parent = (relation: string, r: SeedRow) => {\n const target = fieldOf(t.token, relation)?.relationTarget;\n const ref = r.values?.[relation];\n const pk = Array.isArray(ref) ? ref[0] : ref;\n return target ? { target, prow: live(target).find((x) => x.key === pk) } : { target: \"\", prow: undefined };\n };\n for (const r of live(t.token)) {\n for (const a of t.statusAgrees ?? []) {\n const st = storeText(r.values?.[a.field]) ?? \"\";\n if (!a.childStatus.includes(st)) continue;\n const { target, prow } = parent(a.relation, r);\n const ps = prow ? storeText(prow.values?.[a.parentField]) ?? \"\" : null;\n if (prow && ps !== null && !a.parentStatus.includes(ps)) out.set(`sa|${t.token}|${r.key}|${a.relation}|${st}|${ps}`, `\"${name(t.token, r)}\" is ${st}, so \"${name(target, prow)}\" should be ${a.parentStatus.join(\" or \")}, but it is \"${ps}\".`);\n }\n for (const w of t.withinParent ?? []) {\n if (w.unless && w.unless.values.includes(storeText(r.values?.[w.unless.field]) ?? \"\")) continue;\n const { target, prow } = parent(w.relation, r);\n const c = parseNumeric(storeText(r.values?.[w.field]) ?? \"\");\n const pv = prow ? parseNumeric(storeText(prow.values?.[w.parentField]) ?? \"\") : null;\n if (prow && c && pv && (w.op === \"<=\" ? qCmp(c, pv) > 0 : qCmp(c, pv) < 0)) out.set(`wp|${t.token}|${r.key}|${w.field}|${storeText(r.values?.[w.field])}|${storeText(prow.values?.[w.parentField])}`, `\"${name(t.token, r)}\" has ${w.field} ${storeText(r.values?.[w.field])}, ${w.op === \"<=\" ? \"above\" : \"below\"} \"${name(target, prow)}\"'s ${w.parentField} (${storeText(prow.values?.[w.parentField])}).`);\n }\n for (const d of t.childDates ?? []) {\n const { target, prow } = parent(d.relation, r);\n const c = day(r.values?.[d.field]);\n const pd = prow ? day(prow.values?.[d.parentField]) : null;\n if (prow && c && pd && c < pd) out.set(`cd|${t.token}|${r.key}|${d.field}|${c}|${pd}`, `\"${name(t.token, r)}\" has ${d.field} ${c}, before \"${name(target, prow)}\"'s ${d.parentField} ${pd}.`);\n }\n // A stage that needs a linked child has one.\n for (const rules of [...stageRules.values()].filter((x) => x.table === t.token)) {\n const st = storeText(r.values?.[rules.stageField]) ?? \"\";\n const need = rules.requiresChild?.[st];\n if (!need) continue;\n const kids = live(need.table).filter((c) => {\n const ref = c.values?.[need.relation];\n const linked = Array.isArray(ref) ? ref.includes(r.key) : ref === r.key;\n return linked && (!need.field || (need.in ?? []).includes(storeText(c.values?.[need.field]) ?? \"\"));\n });\n if (kids.length < (need.min ?? 1)) out.set(`rc|${t.token}|${r.key}|${st}|${kids.length}`, `\"${name(t.token, r)}\" is ${st}, which needs ${need.min ?? 1} linked ${byToken.get(need.table)?.labelSingular.toLowerCase() ?? need.table}${need.field ? ` in ${(need.in ?? []).join(\"/\")}` : \"\"}; it has ${kids.length}.`);\n }\n // A relation whose record must hold a valid credential on this row's date.\n for (const f of t.fields.filter((x) => x.eligible)) {\n const el = f.eligible!;\n const ref = r.values?.[f.key];\n const on = day(r.values?.[el.onDate]);\n for (const who of (Array.isArray(ref) ? ref : [ref]).filter((x) => x !== undefined && x !== null && x !== \"\")) {\n if (!on) continue;\n const ok = live(el.table).some(\n (c) =>\n (Array.isArray(c.values?.[el.relation]) ? (c.values?.[el.relation] as unknown[]).includes(who) : c.values?.[el.relation] === who) &&\n Object.entries(el.where ?? {}).every(([k, v]) => storeText(c.values?.[k]) === v) &&\n (day(c.values?.[el.until]) ?? \"\") >= on,\n );\n if (!ok) {\n const target = fieldOf(t.token, f.key)?.relationTarget ?? \"\";\n const prow = live(target).find((x) => x.key === who);\n out.set(`el|${t.token}|${r.key}|${f.key}|${String(who)}|${on}`, `\"${name(t.token, r)}\" (${on}) has ${f.label.toLowerCase()} \"${prow ? name(target, prow) : String(who)}\", who holds no ${byToken.get(el.table)?.labelSingular.toLowerCase() ?? el.table}${el.where ? ` (${Object.values(el.where).join(\", \")})` : \"\"} valid on that day.`);\n }\n }\n }\n }\n }\n return out;\n };\n const crossSeen = new Set(crossBreaks().keys());\n // The seed itself keeps the linked-child and eligibility rules (the walk is judged below).\n for (const [k, msg] of crossBreaks()) {\n const [kind, table, row] = k.split(\"|\");\n if (kind === \"rc\" || kind === \"el\") say(`tables (${table}).rows (${row})`, msg);\n }\n /** One row's stage move (a `move` step, or one row of a grouped `moves` step): its own table's rules. */\n /** `rawSet`: the step's `set` as WRITTEN (relative tokens), so the date rule resolves it per install weekday. */\n const moveOne = (a: WalkMove, at: string, rawSet?: Record<string, unknown>): boolean => {\n const row = rowIn(a.table, a.row);\n const f = fieldOf(a.table, a.field);\n if (!row || row.archived) say(`${at}.action`, `There is no live row \"${a.row}\" in \"${a.table}\".`);\n if (!f) say(`${at}.action`, `\"${a.table}\" does not declare a field \"${a.field}\".`);\n if (!row || !f) return false;\n if (!f.choices?.includes(a.to)) {\n say(`${at}.action`, `\"${a.to}\" is not one of \"${a.field}\"'s choices.`);\n return false;\n }\n const rules = stageRules.get(`${a.table}.${a.field}`);\n if (!rules) say(`${at}.action`, `\"${a.table}.${a.field}\" has no stage rules, so the store has no board to move it on (pipeline_move: \"no stage column\"). Move along a declared stage field, or edit the value.`);\n const from = storeText(row.values[a.field]);\n if (rules?.transitions?.length && !rules.transitions.some((t) => t.from === from && t.to === a.to)) {\n say(`${at}.action`, `The template's own stage rules do not allow \"${from}\" → \"${a.to}\".`);\n }\n // Fields that land with the move (pipeline_move's p_also): the same checks an edit gets.\n const landed: Record<string, unknown> = { ...row.values };\n for (const [key, value] of Object.entries(a.set ?? {})) {\n const sf = fieldOf(a.table, key);\n if (!sf) {\n say(`${at}.action`, `\"${a.table}\" does not declare a field \"${key}\".`);\n continue;\n }\n if (key === a.field) say(`${at}.action`, `\"${key}\" is the stage the move sets; leave it out of set.`);\n if (isComputed(sf)) say(`${at}.action`, `\"${sf.label}\" is computed by the store (${sf.parityType}); nobody types into it.`);\n const broken = ruleBreak(sf, value);\n if (broken) say(`${at}.action`, `${broken} The store would refuse this move.`);\n landed[key] = value;\n }\n for (const k of rules?.requires?.[a.to] ?? []) if (!filled(landed[k])) say(`${at}.action`, `Landing in \"${a.to}\" needs \"${k}\" filled, and \"${a.row}\" leaves it empty — set it in the move, or the store refuses it.`);\n const limit = rules?.limits?.[a.to];\n if (limit !== undefined) {\n const there = (state.get(a.table) ?? []).filter((r) => !r.archived && r.key !== a.row && storeText(r.values[a.field]) === a.to).length;\n if (there + 1 > limit) say(`${at}.action`, `\"${a.to}\" holds at most ${limit}; the move would make ${there + 1}.`);\n }\n // The stage's own date rule holds after the move, on every install weekday.\n const rule = rules?.dateField ? rules.stageDates?.[a.to] : undefined;\n if (rule === \"none\" && rules?.dateField) {\n const landedDate = a.set && rules.dateField in a.set ? a.set[rules.dateField] : row.values?.[rules.dateField];\n if (filled(landedDate)) say(`${at}.action`, `\"${a.to}\" is a stage with no date yet, and \"${a.row}\" carries a ${rules.dateField}. Move a row without one.`);\n } else if (rule && rule !== \"any\" && rules?.dateField) {\n const rawDate =\n a.set && rules.dateField in a.set\n ? (rawSet && rules.dateField in rawSet ? rawSet[rules.dateField] : a.set[rules.dateField])\n : tablesRaw.find((t) => t.token === a.table)?.rows.find((r) => r.key === a.row)?.values?.[rules.dateField];\n const off: string[] = [];\n for (const day of refWeek) {\n const d = typeof rawDate === \"string\" ? (resolveDateToken(rawDate, day, tz) ?? rawDate).slice(0, 10) : null;\n if (d && !(rule === \"past\" ? d <= day : rule === \"future\" ? d >= day : d === day)) off.push(WEEKDAY_NAMES[dayOfWeek(day)] ?? day);\n }\n if (off.length) say(`${at}.action`, `Moving \"${a.row}\" to \"${a.to}\" breaks that stage's date rule (its ${rules.dateField} must be ${rule === \"today\" ? \"today\" : `in the ${rule}`}) when installed on a ${off.join(\", \")}. Move a row whose date fits.`);\n }\n Object.assign(row.values, landed, { [a.field]: a.to });\n coherent(a.table, row, `${at}.action`);\n for (const pair of byToken.get(a.table)?.before ?? []) {\n const [x, y] = pair.map((k) => (k.includes(\".\") ? null : dayOfMoment(row.values[k])));\n if (x && y && x > y) say(`${at}.action`, `After this move ${pair[0]} (${x}) comes after ${pair[1]} (${y}).`);\n }\n for (const [k, needs] of inferredImplies(a.table, a.field)) {\n if (k === a.to) for (const fk of needs) if (!filled(row.values[fk])) say(`${at}.action`, `Every \"${a.to}\" row has \"${fieldOf(a.table, fk)?.label ?? fk}\", and no earlier one does; set it in the move.`);\n }\n return true;\n };\n\n const stepsSeen = new Set<string>();\n let showsS5 = false;\n const archivedRows = new Set<string>();\n (spec.walk ?? []).forEach((step, i) => {\n const at = `walk[${i}]`;\n if (!step.says?.trim()) say(`${at}.says`, \"Say the step in plain words — 'Drag Rosa to Scheduled'.\");\n const a: WalkAction | undefined = step.action;\n const sig = JSON.stringify(a);\n if (stepsSeen.has(sig)) say(`${at}.action`, \"This step repeats an earlier one; each step teaches something new.\");\n stepsSeen.add(sig);\n switch (a?.kind) {\n case \"open\":\n if (!surfaces.has(a.surface)) say(`${at}.action`, `It opens \"${a.surface}\", which is no view, form or extra of this template.`);\n break;\n case \"move\": {\n if (!moveOne(a, at, (raw.walk?.[i]?.action as { set?: Record<string, unknown> } | undefined)?.set)) break;\n const e = step.expect;\n if (!(e?.kind === \"value\" && e.table === a.table && e.row === a.row && e.field === a.field && sameJson(e.equals, a.to))) {\n say(`${at}.expect`, \"A move step asserts where the row it moved landed (a value on that row and field).\");\n }\n break;\n }\n case \"moves\": {\n const group = a.moves ?? [];\n if (group.length < 2 || group.length > 3) say(`${at}.action`, \"A grouped step moves 2 or 3 linked rows; one row is a plain move.\");\n if (new Set(group.map((m) => `${m.table}.${m.row}`)).size !== group.length) say(`${at}.action`, \"Each row moves once in a grouped step.\");\n group.forEach((m, mi) => moveOne(m, `${at}.moves[${mi}]`, (raw.walk?.[i]?.action as { moves?: WalkMove[] } | undefined)?.moves?.[mi]?.set));\n const e = step.expect;\n if (!(e?.kind === \"value\" && group.some((m) => e.table === m.table && e.row === m.row && e.field === m.field && sameJson(e.equals, m.to)))) {\n say(`${at}.expect`, \"A grouped step asserts where one of its rows landed (a value on that row and field).\");\n }\n break;\n }\n case \"edit\": {\n const row = rowIn(a.table, a.row);\n if (!row || row.archived) {\n say(`${at}.action`, `There is no live row \"${a.row}\" in \"${a.table}\".`);\n break;\n }\n const writes: Array<[string, unknown]> = a.set ? Object.entries(a.set) : a.field ? [[a.field, a.value]] : [];\n if (!writes.length) say(`${at}.action`, \"An edit names what it writes: field + value, or set: {field: value, …}.\");\n let changed = false;\n for (const [key, value] of writes) {\n const f = fieldOf(a.table, key);\n if (!f) {\n say(`${at}.action`, `\"${a.table}\" does not declare a field \"${key}\".`);\n continue;\n }\n if ([...stageRules.values()].some((r) => r.table === a.table && r.stageField === key)) {\n say(`${at}.action`, `\"${key}\" is the pipeline's stage; a record changes stage only by a move, which the stage rules check.`);\n }\n if (isComputed(f)) say(`${at}.action`, `\"${f.label}\" is computed by the store (${f.parityType}); nobody types into it.`);\n if (!sameJson(row.values[key], value)) changed = true;\n const broken = ruleBreak(f, value);\n if (broken) say(`${at}.action`, `${broken} The store would refuse this edit.`);\n row.values[key] = value;\n }\n coherent(a.table, row, `${at}.action`);\n if (writes.length && !changed) say(`${at}.action`, `\"${a.row}\" already holds what this edit writes; an edit that changes nothing teaches nothing.`);\n // The whole result stays coherent: every written choice is a choice, every date pair still holds.\n for (const pair of byToken.get(a.table)?.before ?? []) {\n const [x, y] = pair.map((k) => (k.includes(\".\") ? null : dayOfMoment(row.values[k])));\n if (x && y && x > y) say(`${at}.action`, `After this edit ${pair[0]} (${x}) comes after ${pair[1]} (${y}).`);\n }\n const e = step.expect;\n if (!(e?.kind === \"value\" && e.table === a.table && e.row === a.row && writes.some(([k, v]) => k === e.field && sameJson(e.equals, v)))) {\n say(`${at}.expect`, \"An edit step asserts a value it wrote, on the row it wrote it.\");\n }\n break;\n }\n case \"submit_form\": {\n const form = forms.find((f) => f.token === a.form);\n if (!form) {\n say(`${at}.action`, `It submits \"${a.form}\", which this template does not declare.`);\n break;\n }\n for (const key of Object.keys(a.values ?? {})) if (!form.fields.some((ff) => ff.fieldKey === key)) say(`${at}.action`, `The form \"${a.form}\" does not ask for \"${key}\".`);\n for (const ff of form.fields) if (ff.required && !filled(a.values?.[ff.fieldKey])) say(`${at}.action`, `The form requires \"${ff.fieldKey}\", and the step leaves it empty.`);\n // A stored row takes every column default the form did not ask (the store fills them on write — a new\n // request starts \"New\"), so the walk counts the submitted row the way the store will.\n const defaults: Record<string, unknown> = {};\n for (const f of byToken.get(form.table)?.fields ?? []) if (f.default !== undefined && !isComputed(f)) defaults[f.key] = f.default;\n const submitted = { key: `walk-${i}`, values: { ...defaults, ...a.values } };\n coherent(form.table, submitted, `${at}.action`);\n state.get(form.table)?.push(submitted);\n break;\n }\n case \"archive\":\n case \"restore\": {\n const row = rowIn(a.table, a.row);\n if (!row) say(`${at}.action`, `There is no row \"${a.row}\" in \"${a.table}\".`);\n else if (a.kind === \"archive\") {\n if (row.archived) say(`${at}.action`, `\"${a.row}\" is already archived.`);\n row.archived = true;\n archivedRows.add(`${a.table}.${a.row}`);\n } else {\n if (!row.archived) say(`${at}.action`, `\"${a.row}\" is not archived, so there is nothing to restore.`);\n if (archivedRows.has(`${a.table}.${a.row}`)) showsS5 = true;\n row.archived = false;\n }\n const e = step.expect;\n if (!(e?.kind === \"archived\" && e.table === a.table && e.row === a.row && e.equals === (a.kind === \"archive\"))) {\n say(`${at}.expect`, `An ${a.kind} step asserts that the row it acted on is ${a.kind === \"archive\" ? \"archived\" : \"back\"} ({kind: \"archived\", row: \"${a.row}\"}).`);\n }\n break;\n }\n case \"import\": {\n const table = byToken.get(a.table);\n if (!table) {\n say(`${at}.action`, `It imports into \"${a.table}\", which this template does not declare.`);\n break;\n }\n const key = fieldOf(a.table, a.dedupeKey);\n if (!key) say(`${at}.action.dedupeKey`, `This table has no column called \"${a.dedupeKey}\", so it cannot be what makes a row the same row.`);\n else if (!(key.rules ?? []).some((r) => r.kind === \"unique\")) say(`${at}.action.dedupeKey`, `\"${key.label}\" is the upsert key, so it carries a unique rule.`);\n if (!a.sourceName?.trim()) say(`${at}.action.sourceName`, \"Name the file as a person would: 'October customer list.csv'.\");\n if (!a.columns?.includes(a.dedupeKey)) say(`${at}.action.columns`, \"The file carries the upsert key as a column.\");\n for (const c of a.columns ?? []) if (!fieldOf(a.table, c)) say(`${at}.action.columns`, `The column \"${c}\" maps to no field of \"${a.table}\".`);\n let updates = 0;\n let adds = 0;\n const ki = a.columns?.indexOf(a.dedupeKey) ?? -1;\n (a.rows ?? []).forEach((cells, ri) => {\n if (cells.length !== a.columns.length) return say(`${at}.action.rows[${ri}]`, `The row has ${cells.length} cells under ${a.columns.length} columns.`);\n const values: Record<string, unknown> = {};\n a.columns.forEach((c, ci) => {\n const f = fieldOf(a.table, c);\n const cell = cells[ci] ?? \"\";\n // A person pastes the linked record's NAME; the store matches it to the record's title.\n if (f && isRelation(f) && f.relationTarget && cell) {\n const target = byToken.get(f.relationTarget);\n const byTitle = target?.rows.some((tr) => (storeText(tr.values?.[target.titleField]) ?? \"\").trim() === cell.trim());\n const isKey = target?.rows.some((tr) => tr.key === cell.trim());\n if (isKey && !byTitle) say(`${at}.action.rows[${ri}]`, `\"${cell}\" is a seed key; an import file holds what a person types — the ${target?.labelSingular.toLowerCase()}'s name (\"${storeText(target?.rows.find((tr) => tr.key === cell.trim())?.values?.[target.titleField])}\").`);\n else if (!byTitle) say(`${at}.action.rows[${ri}]`, `\"${cell}\" names no ${target?.labelSingular.toLowerCase() ?? \"record\"}; the store would refuse the row.`);\n }\n if (f?.choices?.length && cell && !f.choices.includes(cell)) say(`${at}.action.rows[${ri}]`, `\"${cell}\" is not one of \"${c}\"'s choices.`);\n // The store matches the pasted name to the record; the simulated row holds that record.\n const linked = f && isRelation(f) && f.relationTarget && cell ? byToken.get(f.relationTarget)?.rows.find((tr) => (storeText(tr.values?.[byToken.get(f.relationTarget!)!.titleField]) ?? \"\").trim() === cell.trim()) : undefined;\n values[c] = linked ? linked.key : f && isNumber(f) && parseNumeric(cell) ? Number(cell) : cell;\n });\n // custom.io_import_rows: the key matches a LIVE row's raw value, exactly, trimmed only.\n const keyValue = (cells[ki] ?? \"\").trim();\n const sameKey = (r: SeedRow) => (storeText(r.values[a.dedupeKey]) ?? \"\").trim() === keyValue;\n if ((state.get(a.table) ?? []).some((r) => r.archived && sameKey(r))) {\n say(`${at}.action.rows[${ri}]`, `\"${keyValue}\" belongs to an archived row; the store would add a second one beside it. Restore it first, or import a different key.`);\n }\n const existing = (state.get(a.table) ?? []).find((r) => !r.archived && sameKey(r));\n const rules = [...stageRules.values()].find((r) => r.table === a.table);\n if (existing) {\n updates += 1;\n // An update that changes the stage is a move: the same transitions, requires and statusImplies.\n const from = rules ? storeText(existing.values[rules.stageField]) : null;\n const to = rules && a.columns.includes(rules.stageField) ? storeText(values[rules.stageField]) : null;\n Object.assign(existing.values, values);\n if (rules && to && to !== from) {\n if (rules.transitions?.length && !rules.transitions.some((t) => t.from === from && t.to === to)) say(`${at}.action.rows[${ri}]`, `\"${keyValue}\" goes \"${from}\" → \"${to}\", a move the stage rules do not allow.`);\n for (const k of rules.requires?.[to] ?? []) if (!filled(existing.values[k])) say(`${at}.action.rows[${ri}]`, `\"${keyValue}\" lands in \"${to}\", which needs \"${k}\" filled; the file leaves it empty.`);\n for (const [x, needs] of inferredImplies(a.table, rules.stageField)) if (x === to) for (const k of needs) if (!filled(existing.values[k])) say(`${at}.action.rows[${ri}]`, `\"${keyValue}\" lands in \"${to}\" without \"${fieldOf(a.table, k)?.label ?? k}\", which every \"${to}\" row has.`);\n }\n coherent(a.table, existing, `${at}.action.rows[${ri}]`);\n } else {\n // A child table whose every seed row links a parent: a new row links one too.\n for (const rf of table.fields.filter((f) => isRelation(f) && f.relationTarget && f.parityType !== \"attachment\" && !f.multi && (f.relationMax ?? 1) === 1 && own.some((p) => p.token === f.relationTarget))) {\n if (table.rows.length && table.rows.every((r) => filled(r.values?.[rf.key])) && !filled(values[rf.key])) {\n say(`${at}.action.rows[${ri}]`, `The new row \"${keyValue}\" has no \"${rf.label}\", and every other ${table.labelSingular.toLowerCase()} has one; add the column.`);\n }\n }\n adds += 1;\n // A new imported row takes the columns' defaults the file leaves out, as the store writes it.\n for (const f of table.fields) if (f.default !== undefined && !isComputed(f) && values[f.key] === undefined) values[f.key] = f.default;\n const added = { key: `walk-${i}-${ri}`, values };\n // A new row passes the same door a person's would: the stage it lands in and its status rules.\n const landed = rules ? storeText(values[rules.stageField]) : null;\n for (const k of landed ? (rules?.requires?.[landed] ?? []) : []) if (!filled(values[k])) say(`${at}.action.rows[${ri}]`, `The new row \"${keyValue}\" lands in \"${landed}\", which needs \"${k}\" filled; the store would refuse it.`);\n coherent(a.table, added, `${at}.action.rows[${ri}]`);\n state.get(a.table)?.push(added);\n }\n });\n {\n const e = step.expect;\n if (!((e?.kind === \"count\" || e?.kind === \"value\" || e?.kind === \"aggregate\") && e.table === a.table)) {\n say(`${at}.expect`, `An import asserts what it did to \"${a.table}\" (a count, a value or a total on that table).`);\n }\n }\n if (!updates || !adds) say(`${at}.action.rows`, `An upsert import shows both halves: rows that update a record already there (${updates}) and rows that add a new one (${adds}).`);\n else showsS5 = true;\n break;\n }\n case \"ask_agent\": {\n // The answer the store would give NOW — after the steps before it changed the data.\n const qe = agent?.question?.expect;\n const nowRows = qe ? withComputedKeys(qe.table, [qe.measure.key, ...Object.keys(qe.filter ?? {})], state.get(qe.table) ?? []) : null;\n const now = qe ? storeAggregate(nowRows && \"rows\" in nowRows ? nowRows.rows : state.get(qe.table) ?? [], qe.measure, qe.filter, tz) : null;\n const want = now && now.ok ? now.value : null;\n if (!(step.expect?.kind === \"agent_answer\" && want !== null && sameNumber(step.expect.equals, want))) {\n say(`${at}.expect`, `Asking the agent asserts the exact answer it must give at this point of the walk (${want}).`);\n }\n const changedBefore = (spec.walk ?? []).slice(0, i).some((w) => [\"move\", \"moves\", \"edit\", \"import\", \"archive\", \"restore\", \"submit_form\"].includes(w?.action?.kind ?? \"\"));\n if (changedBefore && qe && want !== null && sameNumber(want, qe.answer)) {\n say(`${at}`, `The steps before this one change nothing the question reads (the answer is still ${want}); ask about what the walk just did, so the person sees the cause and the effect.`);\n }\n if (/\\b(today|tonight|yesterday|this (?:week|month|year|morning)|last (?:week|month))\\b/i.test(step.says ?? \"\") && !Object.values(qe?.filter ?? {}).some((v) => v !== null && typeof v === \"object\")) {\n say(`${at}.says`, `\"${step.says}\" names a time span the question does not have (it reads all time); drop the time words or give the question a date window.`);\n }\n break;\n }\n default:\n say(`${at}.action`, \"Each step does one thing: open, move, edit, submit_form, archive, restore, import or ask_agent.\");\n }\n const e = step.expect;\n switch (e?.kind) {\n case \"renders\": {\n const view = views.find((v) => v.token === e.surface);\n const dateKey = view?.kind === \"calendar\" ? view.dateField : view?.kind === \"timeline\" ? view.startField : undefined;\n const SPAN = /\\b(?:next|this|coming|past|last)\\s+(?:\\w+\\s+)?(?:days?|weeks?|months?)\\b|\\btoday\\b|\\btomorrow\\b/i;\n if (dateKey && !e.within && SPAN.test(step.says ?? \"\")) {\n say(`${at}.expect`, `\"${step.says}\" names a span of time; give the expectation the same window (\"within\": {\"from\": \"@today\", \"to\": \"@today+3w\"}) so it is checked on every install day.`);\n }\n if (e.within) {\n if (!dateKey) say(`${at}.expect.within`, `\"${e.surface}\" is not a calendar or timeline, so it has no date window.`);\n else {\n const short: string[] = [];\n for (const day of refWeek) {\n const rs = resolveRelativeDates(raw, day);\n const v = rs.views.find((x) => x.token === e.surface)!;\n const w = resolveRelativeDates({ business: raw.business, within: e.within } as never, day) as unknown as { within: { from?: string; to?: string } };\n const rows = (allTables(rs).find((t) => t.token === v.table)?.rows ?? []).map((r) => ({ key: r.key, values: r.values }));\n const n0 = rows.filter((r) => viewMatches(r, { anyOf: v.anyOf, filters: { ...(v.filters ?? {}), [dateKey]: w.within as AggregateFilter } }, tz)).length;\n if (n0 < e.minItems) short.push(`${WEEKDAY_NAMES[dayOfWeek(day)]} (${n0})`);\n }\n if (short.length) say(`${at}.expect`, `\"${step.says}\" expects at least ${e.minItems} records in that window, but installed on a ${short.join(\", \")} it holds fewer. Seed the window honestly or lower the expectation.`);\n }\n }\n const n = surfaceRows(e.surface);\n if (n === null) say(`${at}.expect`, `It expects \"${e.surface}\" to render, which is no view, form or extra of this template.`);\n else if (!(e.minItems >= 1)) say(`${at}.expect`, \"A render step expects at least one record on screen.\");\n else if (n < e.minItems) say(`${at}.expect`, `\"${e.surface}\" would show ${n} records, fewer than the ${e.minItems} expected.`);\n break;\n }\n case \"count\":\n case \"aggregate\": {\n const rows = state.get(e.table);\n if (!rows) {\n say(`${at}.expect`, `It counts \"${e.table}\", which this template does not declare.`);\n break;\n }\n for (const key of Object.keys(e.where ?? {})) if (!fieldOf(e.table, key)) say(`${at}.expect`, `\"${e.table}\" does not declare \"${key}\".`);\n const measure: AggregateMeasure = e.kind === \"count\" ? { op: \"count\" } : e.measure;\n const rowsC = withComputed(e.table, measure.key, rows);\n if (\"why\" in rowsC) say(`${at}.expect`, `${rowsC.why}.`);\n const got = storeAggregate(\"rows\" in rowsC ? rowsC.rows : rows, measure, e.where, tz);\n if (!got.ok) say(`${at}.expect`, got.says);\n else if (!e.equals) say(`${at}.expect`, \"A step that expects nothing (0) asserts nothing.\");\n else if (got.value === null || !sameNumber(e.equals, got.value)) say(`${at}.expect`, `After this step the store would give ${got.value}, but the step expects ${e.equals}.`);\n break;\n }\n case \"value\": {\n const row = rowIn(e.table, e.row);\n if (!row) say(`${at}.expect`, `There is no row \"${e.row}\" in \"${e.table}\".`);\n else if (!fieldOf(e.table, e.field)) say(`${at}.expect`, `\"${e.table}\" does not declare a field \"${e.field}\".`);\n else if (!sameJson(row.values[e.field], e.equals)) say(`${at}.expect`, `After this step \"${e.field}\" holds ${JSON.stringify(row.values[e.field])}, not ${JSON.stringify(e.equals)}.`);\n break;\n }\n case \"agent_answer\":\n if (a?.kind !== \"ask_agent\") say(`${at}.expect`, \"An agent answer is expected only after the step asks the agent.\");\n break;\n case \"archived\": {\n const row = rowIn(e.table, e.row);\n if (!row) say(`${at}.expect`, `There is no row \"${e.row}\" in \"${e.table}\".`);\n else if (!!row.archived !== e.equals) say(`${at}.expect`, `After this step \"${e.row}\" is ${row.archived ? \"\" : \"not \"}archived.`);\n break;\n }\n default:\n say(`${at}.expect`, \"Each step asserts one thing: renders, count, value, aggregate or agent_answer.\");\n }\n // The step's end state keeps the template's own cross-table rules, not just this row's.\n for (const [k, msg] of crossBreaks()) {\n if (crossSeen.has(k)) continue;\n crossSeen.add(k);\n say(`${at}.action`, `After this step ${msg} Pick a row whose linked record already agrees, or move that record first.`);\n }\n });\n\n // ── foundation ──────────────────────────────────────────────────────────────\n (spec.foundation ?? []).forEach((f, i) => {\n if (!own.some((t) => t.token === f.table)) say(`foundation[${i}]`, `\"${f.table}\" is not a table of this template.`);\n if (!f.keptFor?.trim()) say(`foundation[${i}].keptFor`, \"Say what this day-one table is kept for.\");\n });\n\n // ── strengths and the taught feature are SHOWN, not claimed ─────────────────\n const kinds = new Set(extras.map((e) => e.kind));\n const viewKinds = new Set(views.map((v) => v.kind));\n // S3: the most front doors any ONE table has (form, booking, portal, digest).\n const doors = new Map<string, number>();\n const door = (t: string | undefined) => t && doors.set(t, (doors.get(t) ?? 0) + 1);\n for (const f of forms) door(f.table);\n for (const e of extras) {\n if (e.kind === \"booking\") door(e.table);\n if (e.kind === \"portal\") for (const pt of e.tables ?? []) door(pt.table);\n if (e.kind === \"digest\") door(views.find((v) => v.token === e.view)?.table);\n }\n const stageFieldsOf = new Set([...stageRules.values()].map((r) => `${r.table}.${r.stageField}`));\n const distinctDays = (table: string, key: string) => new Set((byToken.get(table)?.rows ?? []).map((r) => dayOfMoment(r.values?.[key])).filter(Boolean)).size;\n const imports = (spec.walk ?? []).some((s) => s?.action?.kind === \"import\");\n const asks = (spec.walk ?? []).some((s) => s?.action?.kind === \"ask_agent\");\n const entityRefs = fields.filter((f) => f.parityType === \"entity_reference\");\n const shows: Record<string, boolean> = {\n S1: governed,\n S2: !!agent?.question && asks,\n S3: Math.max(0, ...doors.values()) >= 2,\n S4: entityRefs.length > 0 && entityRefs.every((f) => (f.allowedTypes ?? []).length > 0 && (f.allowedTypes ?? []).every((k) => (ENTITY_REFERENCE_KINDS as readonly string[]).includes(k))),\n S5: showsS5,\n relations_rollups: hasLookupOrRollup,\n dimensions: (spec.dimensions ?? []).length > 0,\n kanban: views.some((v) => v.kind === \"kanban\" && stageFieldsOf.has(`${v.table}.${v.groupBy}`)),\n calendar: views.some((v) => v.kind === \"calendar\" && fieldOf(v.table, v.dateField)?.parityType === \"datetime\" && distinctDays(v.table, v.dateField) >= 5),\n timeline: viewKinds.has(\"timeline\"),\n gallery: views.some((v) => v.kind === \"gallery\" && fieldOf(v.table, v.coverField)?.parityType === \"attachment\"),\n forms: forms.some((f) => f.audience === \"public\"),\n bookings: kinds.has(\"booking\"),\n portals: kinds.has(\"portal\"),\n dashboards: [...honestCharts.values()].some((n) => n >= 2),\n drill_down: kinds.has(\"drill_down\"),\n agents: !!agent?.question && asks,\n field_governance: governed,\n import_upsert: imports && showsS5,\n checklists: kinds.has(\"checklist\"),\n documents_esign: extras.some((e) => e.kind === \"document\" && (byToken.get(e.table)?.fields ?? []).some((f) => f.parityType === \"signature\" || f.format === \"signature\")),\n };\n const HOW: Record<string, string> = {\n S2: \"an agent question and a walk step that asks it\",\n S3: \"two front doors (form, booking, portal, digest) on the same table\",\n S4: \"an entity_reference column whose allowedTypes are platform kinds\",\n S5: \"an import walk step that updates and adds, or archive then restore\",\n kanban: \"a kanban grouped by the stage field\",\n calendar: \"a calendar on a datetime field with seed dates on at least five days\",\n gallery: \"a gallery view whose cover is a file field\",\n forms: \"a public form\",\n dashboards: \"a dashboard with two honest charts\",\n agents: \"an agent question and a walk step that asks it\",\n import_upsert: \"an import walk step that updates and adds\",\n documents_esign: \"a document on a table that has a signature field\",\n };\n for (const s of spec.strengths ?? []) if (shows[s] === false) say(\"strengths\", `It claims ${s} but nothing in it shows ${s}${HOW[s] ? ` (${s} needs ${HOW[s]})` : \"\"}. Build the thing that shows it, or drop the claim.`);\n if (spec.teaches && shows[spec.teaches] === false) say(\"teaches\", `It teaches \"${spec.teaches}\" but carries nothing that shows it${HOW[spec.teaches] ? ` (it needs ${HOW[spec.teaches]})` : \"\"}.`);\n for (const f of entityRefs) for (const k of f.allowedTypes ?? []) {\n if (!(ENTITY_REFERENCE_KINDS as readonly string[]).includes(k)) say(`fields (${f.key}).allowedTypes`, `\"${k}\" is not a kind of platform thing a column can point at. Use one of the store's kinds (agent, note, workbook, project, party …).`);\n }\n\n // ── absolute (historical) dates never drive schedule ────────────────────────\n const scheduleUses: Array<[string, string, string]> = [];\n const use = (table: string | undefined, key: string | undefined, where: string) => {\n if (table && key) scheduleUses.push([table, key, where]);\n };\n for (const v of views) {\n if (v.kind === \"calendar\") use(v.table, v.dateField, `the calendar \"${v.name}\"`);\n if (v.kind === \"timeline\") {\n use(v.table, v.startField, `the timeline \"${v.name}\"`);\n use(v.table, v.endField, `the timeline \"${v.name}\"`);\n }\n for (const k of [...Object.keys(v.filters ?? {}), ...Object.keys(v.anyOf ?? {})]) use(v.table, k, `the view \"${v.name}\"'s filter`);\n }\n for (const e of extras) {\n if (e.kind === \"digest\") {\n const v = views.find((x) => x.token === e.view);\n if (v?.kind === \"calendar\") use(v.table, v.dateField, `the digest \"${e.name}\"`);\n for (const k of Object.keys(v?.filters ?? {})) use(v?.table, k, `the digest \"${e.name}\"`);\n if (Object.keys(v?.anyOf ?? {}).length) say(`extras (${e.token})`, `The digest reads \"${v?.name}\", whose any-of filter digests never apply (they read only the flat filters); point it at a view without anyOf.`);\n }\n if (e.kind === \"booking\") for (const qq of e.questions ?? []) if (fieldOf(e.table, qq.fieldKey)?.parityType === \"datetime\" && /slot|appointment|visit|start/i.test(qq.fieldKey)) use(e.table, qq.fieldKey, `the booking \"${e.title}\"`);\n if (e.kind === \"stage_rules\") for (const keys of Object.values(e.requires ?? {})) for (const k of keys) use(e.table, k, `the stage rules \"${e.name}\"`);\n }\n if (agent?.question?.expect) for (const k of [...Object.keys(agent.question.expect.filter ?? {}), agent.question.expect.measure?.key]) use(agent.question.expect.table, k, \"the agent's scripted question\");\n for (const step of spec.walk ?? []) {\n const a = step?.action as Record<string, unknown> | undefined;\n const e = step?.expect as Record<string, unknown> | undefined;\n for (const x of [a, e]) {\n if (!x || typeof x.table !== \"string\") continue;\n use(x.table, typeof x.field === \"string\" ? x.field : undefined, \"a walk step\");\n for (const k of Object.keys((x.where as object) ?? {})) use(x.table, k, \"a walk step\");\n if (x.measure && typeof (x.measure as { key?: string }).key === \"string\") use(x.table, (x.measure as { key: string }).key, \"a walk step\");\n if (Array.isArray(x.columns)) for (const k of x.columns as string[]) use(x.table, k, \"a walk step\");\n }\n }\n for (const [table, key, where] of scheduleUses) {\n const f = fieldOf(table, key);\n if (f?.absoluteDates) say(`tables (${table}).fields (${key})`, `\"${f.label}\" holds history (absoluteDates), so it cannot drive ${where}: schedule dates are relative to install day.`);\n }\n\n // ── G6: fictional phones, domains and streets only ──────────────────────────\n const text = JSON.stringify(raw);\n const isPhoneField = (f: TemplateField) => f.parityType === \"phone\" || /(^|_)(phone|mobile|cell|fax|tel)(_|$)/.test(f.key) || /\\b(phone|mobile|cell|fax)\\b/.test(norm(f.label));\n const phoneHits = new Set<string>();\n for (const p of phonesOutsideFictionalRange(raw.business?.phone ?? \"\", true)) phoneHits.add(p);\n for (const t of tablesRaw) for (const r of t.rows) for (const f of t.fields) {\n const v = unwrap(r.values?.[f.key]);\n if (typeof v === \"string\") for (const p of phonesOutsideFictionalRange(v, isPhoneField(f))) phoneHits.add(p);\n }\n const rowless = JSON.stringify({ ...raw, tables: undefined, sharedBlocks: undefined, business: { ...raw.business, phone: undefined } });\n for (const p of phonesOutsideFictionalRange(rowless)) phoneHits.add(p);\n for (const phone of phoneHits) {\n say(\"phones\", `\"${phone}\" could reach a real phone. Use a fictional number: 555-0100 to 555-0199 in North America (e.g. \"(813) 555-0142\"), or a UK Ofcom drama number (e.g. \"020 7946 0123\").`);\n }\n const declaredDomains = new Set((raw.provenance?.fictionalDomains ?? []).map((d) => d.toLowerCase()));\n const websites = [raw.business?.website, ...tables.flatMap((t) => t.rows.flatMap((r) => t.fields.filter((f) => f.parityType === \"url\").map((f) => storeText(r.values?.[f.key]))))]\n .filter((w): w is string => !!w)\n .map((w) => w.toLowerCase().replace(/^https?:\\/\\//, \"\").replace(/^www\\./, \"\").split(\"/\")[0] ?? \"\");\n for (const d of raw.provenance?.fictionalDomains ?? []) {\n if ((PUBLIC_MAIL_DOMAINS as readonly string[]).includes(d.toLowerCase())) say(\"provenance.fictionalDomains\", `\"${d}\" is a public mail provider real people use, so it is never fictional. Give each person a mailbox on an invented domain.`);\n }\n for (const domain of new Set([...domainsIn(text), ...websites])) {\n if (!declaredDomains.has(domain)) say(\"provenance.fictionalDomains\", `\"${domain}\" is used but not declared fictional. List every invented domain in provenance.fictionalDomains (each is checked not to resolve).`);\n }\n const streets = new Set((raw.provenance?.fictionalStreets ?? []).map((s) => s.toLowerCase()));\n const addressLines = [raw.business?.address?.line1, ...tables.flatMap((t) => t.rows.flatMap((r) => t.fields.filter((f) => behaviorOf(f) === \"text\" && /address|street/i.test(`${f.key} ${f.label}`)).map((f) => storeText(r.values?.[f.key]))))];\n for (const line of addressLines) {\n const street = line ? numberedStreet(line) : null;\n if (street && !streets.has(street.toLowerCase())) say(\"provenance.fictionalStreets\", `\"${line}\" puts a house number on \"${street}\", which is not a declared fictional street. Invent the street and list it, or leave the number out.`);\n }\n\n // ═══ round 4: what a business would never ship ═══════════════════════════════\n\n // ── eligibility declarations name real fields ──\n for (const t of own) {\n for (const f of t.fields.filter((x) => x.eligible)) {\n const el = f.eligible!;\n const ok = isRelation(f) && byToken.has(el.table) && fieldOf(el.table, el.relation)?.relationTarget === f.relationTarget && isDate(fieldOf(el.table, el.until) ?? { parityType: \"\" }) && isDate(fieldOf(t.token, el.onDate) ?? { parityType: \"\" }) && Object.keys(el.where ?? {}).every((k) => !!fieldOf(el.table, k));\n if (!ok) say(`tables (${t.token}).fields (${f.key}).eligible`, `eligible needs: \"${f.key}\" a relation; \"${el.table}.${el.relation}\" pointing at the same table; \"${el.table}.${el.until}\" and \"${t.token}.${el.onDate}\" dates; every where key a field of \"${el.table}\".`);\n }\n }\n\n // ── formula fields: a formula the store can parse, over this table's own fields ──\n for (const t of own) {\n for (const f of t.fields.filter((x) => x.parityType === \"formula\")) {\n const fat = `tables (${t.token}).fields (${f.key})`;\n if (!f.formula?.trim()) {\n say(fat, `\"${f.label}\" is a formula; write it in formula, naming fields in braces: {Total} - {Paid}.`);\n continue;\n }\n const ast = parseFormula(f.formula);\n if (typeof ast === \"string\") {\n say(fat, `The formula \"${f.formula}\" cannot be read: ${ast}.`);\n continue;\n }\n for (const ref of formulaRefs(ast)) {\n const target = t.fields.find((x) => x.label === ref);\n if (!target) say(fat, `The formula reads {${ref}}, and \"${t.token}\" has no field labelled that.`);\n else if (target.key === f.key) say(fat, \"A formula never reads itself.\");\n // Store defect (clone proof, aidream c4b83fff07): a formula reads a lookup or rollup as 0.\n else if (target.parityType === \"lookup\" || target.parityType === \"rollup\") say(fat, `The formula reads {${ref}}, a ${target.parityType}, and the store currently reads that as 0 in a formula. Compute it from stored columns, or ask it as a dashboard or agent question.`);\n }\n }\n }\n\n // ── computed fields hold no seed values: the store computes them ──\n for (const t of tables) {\n for (const f of t.fields) {\n if (!isComputed(f)) continue;\n const seeded = t.rows.filter((r) => r.values?.[f.key] !== undefined).length;\n if (seeded) say(`tables (${t.token}).fields (${f.key})`, `\"${f.label}\" is computed by the store (${f.parityType}), and ${seeded} seed row(s) write a value into it; leave it to the store.`);\n }\n }\n\n // ── labels: no generic nouns, numbered options or placeholder people ──\n const label = (at: string, text: string | undefined, kind: Parameters<typeof findBannedLabel>[1]) => {\n if (!text) return;\n const hit = findBannedLabel(text, kind);\n if (hit) say(at, `\"${text}\" is ${hit.why}. Use the practitioner's own word.`);\n };\n for (const t of own) {\n label(`tables (${t.token}).name`, t.name, \"table\");\n label(`tables (${t.token}).labelSingular`, t.labelSingular, \"table\");\n label(`tables (${t.token}).labelPlural`, t.labelPlural, \"table\");\n for (const f of t.fields) {\n label(`tables (${t.token}).fields (${f.key}).label`, f.label, f.key === t.titleField ? \"title\" : \"field\");\n for (const c of f.choices ?? []) label(`tables (${t.token}).fields (${f.key}).choices`, c, \"choice\");\n }\n // A COLUMN OF COUNTERS: \"<word> 1, <word> 2, <word> 3…\" or numbers with leading zeros.\n for (const f of t.fields.filter((x) => behaviorOf(x) === \"text\")) {\n // Real-world numbered names are names, not counters (a closed list, not a hole).\n const REAL_NUMBERED = /^\\s*(?:period|grade|unit|week|floor|bay|court|lane)\\s+\\d+\\s*$/i;\n const nums = t.rows\n .map((r) => storeText(r.values?.[f.key]) ?? \"\")\n .filter((v) => !REAL_NUMBERED.test(v))\n .map((v) => /^\\s*[A-Za-z][A-Za-z ]*?[\\s#_-]+(\\d+)\\s*$/.exec(v)?.[1])\n .filter((x): x is string => !!x);\n if (nums.length < 3) continue;\n const sorted = nums.map(Number).sort((x, y) => x - y);\n const fromOne = sorted.every((n, i) => n === i + 1);\n const padded = nums.filter((n) => /^0\\d/.test(n)).length >= 3;\n if (fromOne || padded) say(`tables (${t.token}).fields (${f.key})`, `\"${f.label}\" counts ${fromOne ? \"1, 2, 3…\" : \"001, 002…\"} instead of naming each record. Use the business's own numbers (\"Job 2201\", \"INV-2041\") or names.`);\n }\n }\n for (const t of tables) {\n // A \"<thing>_name\" names a thing, not a person: \"Period 1\" is a class section, \"Bay 2\" a bay.\n const nameFields = t.fields.filter((f) => behaviorOf(f) === \"text\" && /(^|_)(full_)?name$|^(owner|patient|client|contact|person)_?name$/.test(f.key) && !THING_NAME.test(f.key));\n for (const f of nameFields) for (const r of t.rows) label(`tables (${t.token}).rows (${r.key}).${f.key}`, storeText(r.values?.[f.key]) ?? undefined, \"person\");\n }\n for (const e of extras) if (e.kind === \"document\") label(`extras (${e.token}).title`, e.title, \"title\");\n\n // ── stale words in seed text: weekdays, months, \"this week\" ──\n // Only words RELATIVE to the day they were written go stale: \"today\", \"tomorrow\", \"next week\",\n // \"last Monday\". A weekday or a month as a name or a recurring thing (\"Monday\", \"Sunday school\",\n // \"Tuesdays before noon\", \"May 2019 build\") is true on any day and passes.\n const WD = \"(?:mon|tues|wednes|thurs|fri|satur|sun)day\";\n const STALE = new RegExp(`\\\\b(?:today|tomorrow|yesterday|tonight)\\\\b|\\\\b(?:this|next|last|coming|past)\\\\s+(?:week|month|year|weekend|${WD})\\\\b`, \"i\");\n for (const t of tables) {\n const byKey = new Map(t.fields.map((f) => [f.key, f]));\n for (const r of t.rows) {\n for (const [k, v] of Object.entries(r.values ?? {})) {\n const f = byKey.get(k);\n if (!f || isRelation(f) || f.parityType === \"email\" || f.parityType === \"url\" || f.parityType === \"phone\") continue;\n const text = unwrap(v);\n if (typeof text === \"string\" && !RELATIVE_DATE.test(text) && STALE.test(text)) {\n say(`tables (${t.token}).rows (${r.key}).${k}`, `\"${text}\" says \"${STALE.exec(text)?.[0]}\", which is only true on the day it was written. Put the date in a date field written relative to install day (\"@today+1b 10:00\"), and keep the text free of \"today\" and \"next week\".`);\n }\n }\n }\n }\n\n // ── sensitivity floors by what a field holds (sensitivityFloorOf, below — one reading for the check and the describe box) ──\n for (const t of own) {\n for (const f of t.fields) {\n const at = `tables (${t.token}).fields (${f.key})`;\n const text = `${f.key} ${norm(f.label)}`;\n const e = effective(t.token, f);\n const floor = sensitivityFloorOf(t, f);\n if (floor === \"restricted\" && !(e.sensitivity === \"restricted\" && e.contextPolicy === \"exclude\")) {\n say(at, `\"${f.label}\" is the kind of value that is restricted and kept from the AI (restricted + exclude).`);\n } else if (floor === \"confidential\" && SENSITIVITY_RANK.indexOf(e.sensitivity) < 2) {\n say(at, `\"${f.label}\" reaches a person or a home, so it is at least confidential.`);\n } else if (/note/.test(text) && e.sensitivity === \"public\") {\n say(at, `\"${f.label}\" is somebody's notes; notes are never public.`);\n }\n }\n }\n\n // ── contact columns belong to different people ──\n for (const t of own) {\n for (const f of t.fields.filter((x) => x.parityType === \"phone\" || x.parityType === \"email\")) {\n const vals = t.rows.map((r) => storeText(r.values?.[f.key])).filter((v): v is string => !!v);\n if (vals.length >= 3 && new Set(vals.map((v) => v.toLowerCase())).size < 0.9 * vals.length) {\n say(`tables (${t.token}).fields (${f.key})`, `${vals.length - new Set(vals).size + 1} rows share one ${f.label}; real customers each have their own.`);\n }\n }\n }\n\n // ── one currency per template ──\n const currencies = new Set(fields.filter((f) => f.parityType === \"currency\").map((f) => (f.unit ?? \"\").toUpperCase()));\n if (currencies.size > 1) say(\"tables\", `Money is kept in ${[...currencies].join(\" and \")}; one business keeps its books in one currency.`);\n\n // ── choice colours mean something: done is never red, failed is never green ──\n const GOOD = /^(completed?|done|paid|approved|won|closed won|booked|confirmed|delivered|resolved|published|signed|passed|hired|accepted)$/i;\n const BAD = /^(cancell?ed|skipped|lost|closed lost|denied|rejected|no[- ]show|failed|overdue|declined|void(ed)?|refunded|churned|expired|blocked)$/i;\n for (const t of own) {\n for (const f of t.fields) {\n for (const [choice, color] of Object.entries(f.choiceColors ?? {})) {\n if (GOOD.test(choice) && color === \"red\") say(`tables (${t.token}).fields (${f.key}).choiceColors`, `\"${choice}\" is a good outcome painted red.`);\n if (BAD.test(choice) && color === \"green\") say(`tables (${t.token}).fields (${f.key}).choiceColors`, `\"${choice}\" is a bad outcome painted green.`);\n }\n }\n }\n\n // ── views tell the truth about their data ──\n for (const v of views) {\n const t = byToken.get(v.table);\n if (!t) continue;\n const vat = `views (${v.token})`;\n const filledShare = (key: string) => (t.rows.length ? t.rows.filter((r) => filled(r.values?.[key])).length / t.rows.length : 0);\n if (v.kind === \"kanban\") {\n const vals = new Set(t.rows.map((r) => storeText(r.values?.[v.groupBy])).filter((x) => x));\n if (vals.size < 2) saySeed(vat, `The board groups by \"${v.groupBy}\", and every row holds the same value — one column.`);\n }\n if (v.kind === \"calendar\" || v.kind === \"timeline\") {\n const keys = v.kind === \"calendar\" ? [v.dateField] : [v.startField, v.endField];\n for (const k of keys) {\n const f = fieldOf(v.table, k);\n if (!f) continue;\n if (f.parityType !== \"datetime\" && !(v.kind === \"calendar\" && v.allDay)) say(vat, `\"${f.label}\" is not a datetime; a ${v.kind} needs one (or declare allDay on a whole-day calendar).`);\n if (filledShare(k) < 0.5) saySeed(vat, `Only ${Math.round(filledShare(k) * 100)}% of rows fill \"${f.label}\"; the ${v.kind} would look empty.`);\n }\n for (const f of t.fields) {\n if (behaviorOf(f) === \"text\" && /(^|_)(start_|end_)?time$|(^|\\s)time$/.test(`${f.key} ${norm(f.label)}`)) {\n say(`tables (${t.token}).fields (${f.key})`, `\"${f.label}\" keeps a time as text beside a ${v.kind}; the time belongs in the datetime field.`);\n }\n }\n }\n if ((v.filters && Object.keys(v.filters).length) || Object.keys(v.anyOf ?? {}).length) {\n const n = t.rows.filter((r) => viewMatches({ key: r.key, values: r.values }, v, tz)).length;\n if (!n) saySeed(vat, `The view's filter matches no seed row; it opens empty.`);\n }\n }\n\n // ── stage ↔ date coherence, on every install weekday ──\n const resolvedFor = new Map(refWeek.map((d) => [d, allTables(resolveRelativeDates(raw, d))]));\n const dayOf = (v: unknown) => {\n const t = storeText(v);\n return t ? t.slice(0, 10) : null;\n };\n for (const e of extras) {\n if (e.kind !== \"stage_rules\") continue;\n const dateFields = (byToken.get(e.table)?.fields ?? []).filter((f) => isDate(f) && !f.absoluteDates);\n if (!e.dateField && dateFields.length) {\n say(`extras (${e.token}).dateField`, `\"${e.table}\" has a schedule date, so its stage rules say which date each stage agrees with: add \"dateField\": \"${dateFields[0]?.key}\" and \"stageDates\" (e.g. {\"${[...(byToken.get(e.table)?.fields.find((f) => f.key === e.stageField)?.choices ?? [\"Done\"])].pop()}\": \"past\"}).`);\n continue;\n }\n if (!e.dateField) continue;\n if (!fieldOf(e.table, e.dateField)) {\n say(`extras (${e.token}).dateField`, `\"${e.table}\" does not declare \"${e.dateField}\".`);\n continue;\n }\n const stageChoices = byToken.get(e.table)?.fields.find((f) => f.key === e.stageField)?.choices ?? [];\n const unlisted = stageChoices.filter((c) => !(c in (e.stageDates ?? {})));\n if (unlisted.length) say(`extras (${e.token}).stageDates`, `Say for every stage whether its date is past, today, future or any; ${unlisted.map((u) => `\"${u}\"`).join(\", \")} ${unlisted.length === 1 ? \"is\" : \"are\"} not listed, so a row could sit there with an impossible date.`);\n // A past/future/today rule on a stage whose every seed row has no date checks nothing: say \"none\".\n for (const [st, rule] of Object.entries(e.stageDates ?? {})) {\n if (rule !== \"past\" && rule !== \"future\" && rule !== \"today\") continue;\n const inSt = (byToken.get(e.table)?.rows ?? []).filter((r) => storeText(r.values?.[e.stageField]) === st);\n if (inSt.length && inSt.every((r) => !filled(r.values?.[e.dateField!]))) say(`extras (${e.token}).stageDates`, `Every \"${st}\" row has no ${e.dateField}, so \"${rule}\" checks nothing; write \"none\" (no date at this stage).`);\n }\n const offDays = new Map<string, { stage: string; rule: string; days: string[] }>();\n for (const [day, ts] of resolvedFor) {\n for (const r of ts.find((t) => t.token === e.table)?.rows ?? []) {\n const stage = storeText(r.values?.[e.stageField]);\n const rule = stage ? e.stageDates?.[stage] : undefined;\n const d = dayOf(r.values?.[e.dateField]);\n if (!stage || !rule || rule === \"any\") continue;\n if (rule === \"none\") {\n if (d) {\n const entry = offDays.get(r.key) ?? { stage, rule, days: [] };\n entry.days.push(WEEKDAY_NAMES[dayOfWeek(day)] ?? day);\n offDays.set(r.key, entry);\n }\n continue;\n }\n if (!d) continue;\n const ok = rule === \"past\" ? d <= day : rule === \"future\" ? d >= day : d === day;\n if (!ok) {\n const entry = offDays.get(r.key) ?? { stage, rule, days: [] };\n entry.days.push(WEEKDAY_NAMES[dayOfWeek(day)] ?? day);\n offDays.set(r.key, entry);\n }\n }\n }\n for (const [key, x] of offDays) {\n const row = byToken.get(e.table)?.rows.find((r) => r.key === key);\n const title = storeText(row?.values?.[byToken.get(e.table)?.titleField ?? \"\"]) ?? key;\n if (x.rule === \"none\") {\n say(`tables (${e.table}).rows (${key})`, `\"${title}\" is ${x.stage}, a stage with no date yet, but its ${e.dateField} is filled. Leave it empty.`);\n continue;\n }\n const when = x.rule === \"today\" ? \"today\" : x.rule === \"past\" ? \"on or before install day\" : \"on or after install day\";\n say(`tables (${e.table}).rows (${key})`, `\"${title}\" is ${x.stage}, so its ${e.dateField} must fall ${when}, but it does not when installed on a ${x.days.join(\", \")}. Write its date relative to install day so the two agree (\"@today-2b\" for done, \"@today+2b\" for coming).`);\n }\n }\n\n // ── business days, historical dates, ordered pairs ──\n for (const t of own) {\n for (const f of t.fields.filter((x) => isDate(x))) {\n if (f.businessDays) {\n const weekend = new Map<string, string[]>();\n for (const [day, ts] of resolvedFor) {\n for (const r of ts.find((x) => x.token === t.token)?.rows ?? []) {\n const d = dayOf(r.values?.[f.key]);\n if (d && [0, 6].includes(dayOfWeek(d))) weekend.set(r.key, [...(weekend.get(r.key) ?? []), WEEKDAY_NAMES[dayOfWeek(day)] ?? day]);\n }\n }\n for (const [key, days] of weekend) {\n const raw0 = tablesRaw.find((x) => x.token === t.token)?.rows.find((r) => r.key === key)?.values?.[f.key];\n say(`tables (${t.token}).rows (${key}).${f.key}`, `\"${f.label}\" is weekdays only, but \"${String(raw0)}\" lands on a Saturday or Sunday when installed on a ${days.join(\", \")}. Count in business days (\"@today+2b 10:00\") or add \"~b\" to move a weekend date to Monday.`);\n }\n }\n if (f.absoluteDates) {\n for (const r of t.rows) {\n const d = dayOf(r.values?.[f.key]);\n if (d && d > TEMPLATE_REFERENCE_DATE) say(`tables (${t.token}).rows (${r.key}).${f.key}`, `\"${f.label}\" is history and ${d} has not happened yet.`);\n }\n }\n }\n const schedule = t.fields.filter((f) => isDate(f) && !f.absoluteDates);\n if (schedule.length >= 2 && !t.before?.length && !t.datesIndependent?.trim()) {\n say(`tables (${t.token}).before`, `\"${t.token}\" has ${schedule.length} schedule dates (${schedule.map((f) => f.key).join(\", \")}); declare their order (before: [earlier, later]) or why they are independent.`);\n }\n const sideValue = (row: { values: Record<string, unknown> }, side: string): { at: string | null; ok: boolean } => {\n const [a, b] = side.split(\".\");\n if (!b) return { at: dayOfMoment(row.values?.[a ?? \"\"]), ok: !!fieldOf(t.token, a ?? \"\") };\n const via = fieldOf(t.token, a ?? \"\");\n if (!via?.relationTarget || !fieldOf(via.relationTarget, b)) return { at: null, ok: false };\n const target = byToken.get(via.relationTarget)?.rows.find((r) => r.key === row.values?.[a ?? \"\"]);\n return { at: target ? dayOfMoment(target.values?.[b]) : null, ok: true };\n };\n for (const [earlier, later] of t.before ?? []) {\n for (const r of t.rows) {\n const x = sideValue(r, earlier);\n const y = sideValue(r, later);\n if (!x.ok || !y.ok) {\n say(`tables (${t.token}).before`, `[${earlier}, ${later}] names a field this table cannot reach.`);\n break;\n }\n if (x.at && y.at && x.at > y.at) say(`tables (${t.token}).rows (${r.key})`, `${earlier} (${x.at}) comes after ${later} (${y.at}); the template says it never does.`);\n }\n }\n }\n\n // ── forms ask only what their audience may give ──\n const stageKeys = new Set([...stageRules.values()].map((r) => `${r.table}.${r.stageField}`));\n for (const form of forms) {\n const asked = new Set<string>();\n for (const ff of form.fields ?? []) {\n if (asked.has(ff.fieldKey)) say(`forms (${form.token}).fields (${ff.fieldKey})`, `The form asks for \"${ff.fieldKey}\" twice.`);\n asked.add(ff.fieldKey);\n const f = fieldOf(form.table, ff.fieldKey);\n if (!f) continue;\n const at = `forms (${form.token}).fields (${ff.fieldKey})`;\n if (isComputed(f)) say(at, `\"${f.label}\" is computed by the store; no form asks for it.`);\n if (stageKeys.has(`${form.table}.${f.key}`)) say(at, `\"${f.label}\" is the pipeline's stage; a form never sets it, a move does.`);\n if (form.audience === \"public\") {\n if (isRelation(f) && (f.parityType === \"member\" || f.relationTarget === SHARED_BLOCKS.team_member.table)) say(at, `A public form never asks a stranger to pick one of the staff (\"${f.label}\").`);\n const e = effective(form.table, f);\n if ((e.sensitivity === \"confidential\" || e.sensitivity === \"restricted\") && !f.askOfSubject && !f.askOfGuardian) {\n say(at, `\"${f.label}\" is ${e.sensitivity}; a public form asks it only of the person it belongs to (askOfSubject) or of a parent or guardian answering for a minor (askOfGuardian) — flag the field if that is who answers.`);\n }\n }\n }\n }\n\n // ── bookings: custom.booking_declare and custom._booking_availability, mirrored ──\n for (const e of extras) {\n if (e.kind !== \"booking\") continue;\n const at = `extras (${e.token})`;\n const status = fieldOf(e.table, \"status\");\n if (!status) say(at, `A booking table needs a choice field keyed \\`status\\` whose choices include \"booked\" and \"cancelled\"; \"${e.table}\" has none. Add it, so a held time can be confirmed and given back.`);\n else if (isChoice(status)) {\n const words = (status.choices ?? []).map((c) => c.trim().toLowerCase());\n const missing = [\"booked\", \"cancelled\"].filter((w) => !words.includes(w));\n if (missing.length) say(`${at}`, `This table's Status is a list of choices, and it has no choice called ${missing.join(\" or \")} — the booking page writes those words (custom.booking_declare refuses).`);\n }\n // The installer's own pre-check, word for word, so a writer sees at Q1 what the install\n // would refuse (the `slot` column the door writes, required and seeded on every row).\n const columns = bookingColumnsProblem(tables, e);\n if (columns && !(status && /writes \"booked\" and \"cancelled\"/.test(columns))) say(`${at}.table`, columns);\n for (const qq of e.questions ?? []) if ([\"slot\", \"status\", \"booked_with\"].includes(qq.fieldKey)) say(`${at}.questions`, `A booking page never asks for \"${qq.fieldKey}\": the store fills it in from the slot that was held.`);\n const a = e.availability ?? ({} as typeof e.availability);\n const rng = (v: number | undefined, lo: number, hi: number, what: string) => {\n if (v !== undefined && (v < lo || v > hi)) say(`${at}.availability`, `${what} is between ${lo} and ${hi}; this says ${v}.`);\n };\n rng(a.slotMinutes, 5, 480, \"Slot length (minutes)\");\n rng(a.bufferMinutes, 0, 480, \"The buffer (minutes)\");\n rng(a.leadMinutes, 0, 43200, \"Lead time (minutes)\");\n rng(a.maxPerDay, 1, 100, \"Appointments a day\");\n rng(a.days, 1, 90, \"Days ahead\");\n if (a.timezone) {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: a.timezone });\n } catch {\n say(`${at}.availability.timezone`, `There is no timezone called \"${a.timezone}\".`);\n }\n }\n const mins = (hhmm: string) => Number(hhmm.slice(0, 2)) * 60 + Number(hhmm.slice(3, 5));\n for (const w of a.windows ?? []) {\n if (/^\\d{2}:\\d{2}$/.test(w.from) && /^\\d{2}:\\d{2}$/.test(w.to) && mins(w.to) - mins(w.from) < (a.slotMinutes ?? 30)) {\n say(`${at}.availability.windows`, `The ${w.from}–${w.to} window on day ${w.weekday} is shorter than one ${a.slotMinutes ?? 30}-minute slot; nothing can be booked in it.`);\n }\n }\n // Seeded bookings sit inside the hours the page offers, on every install weekday.\n const len = a.slotMinutes ?? 30;\n const rawRows = tablesRaw.find((x) => x.token === e.table)?.rows ?? [];\n const cancelled = (r: { values?: Record<string, unknown> }) => /^(cancell?ed|no[- ]?show)$/i.test(storeText(r.values?.[\"status\"]) ?? \"\");\n const local = (v: unknown, d0: string) => {\n const t = typeof v === \"string\" ? resolveDateToken(v, d0, tz) ?? v : storeText(v) ?? \"\";\n const m = /^(\\d{4}-\\d{2}-\\d{2})T(\\d{2}):(\\d{2})/.exec(t);\n return m ? { date: m[1]!, mins: Number(m[2]) * 60 + Number(m[3]) } : null;\n };\n const sameZone = !a.timezone || a.timezone === tz;\n const fromPage = (r: { values?: Record<string, unknown> }) => {\n const st = storeText(r.values?.[\"status\"]) ?? \"\";\n return e.bookedStages ? e.bookedStages.includes(st) : /^(booked|confirmed|requested|held|pending|scheduled)$/i.test(st);\n };\n for (const st of e.bookedStages ?? []) if (status?.choices?.length && !status.choices.includes(st)) say(`${at}.bookedStages`, `\"${st}\" is not one of the status choices.`);\n for (const r of rawRows) {\n if (!sameZone || cancelled(r) || !fromPage(r)) continue;\n const off: string[] = [];\n for (const d0 of refWeek0) {\n const at0 = local(r.values?.[\"slot\"], d0);\n if (!at0) continue;\n const dow = dayOfWeek(at0.date);\n const inside = (a.windows ?? []).some((w) => w.weekday === dow && mins(w.from) <= at0.mins && at0.mins + len <= mins(w.to));\n if (!inside) off.push(WEEKDAY_NAMES[dayOfWeek(d0)] ?? d0);\n }\n if (off.length) say(`tables (${e.table}).rows (${r.key}).slot`, `\"${String(r.values?.[\"slot\"])}\" falls outside \"${e.title}\"'s hours when installed on a ${off.join(\", \")}; a booked time sits in an offered window.`);\n }\n // custom._booking_slots, mirrored: the times the page offers from the install moment (taken as\n // the END of install day, the fewest left), minus the seeded bookings already on those times.\n const freeSlots = (d0: string): number => {\n const now = 23 * 60 + 59;\n const floor = now + (a.leadMinutes ?? 120);\n const taken = new Set(rawRows.filter((r) => !cancelled(r)).map((r) => local(r.values?.[\"slot\"], d0)).filter((x): x is { date: string; mins: number } => !!x).map((x) => `${x.date} ${x.mins}`));\n let free = 0;\n for (let dd = 0; dd < Math.max(a.days ?? 14, 1); dd++) {\n const date = shiftDays(d0, dd);\n let n = 0;\n const wins = (a.windows ?? []).filter((w) => w.weekday === dayOfWeek(date)).sort((x, y) => (x.from === y.from ? (x.to < y.to ? -1 : 1) : x.from < y.from ? -1 : 1));\n for (const w of wins) {\n let m = mins(w.from);\n while (m + len <= mins(w.to)) {\n if (n >= (a.maxPerDay ?? 8)) break;\n if (dd * 1440 + m >= floor) {\n n += 1;\n if (!taken.has(`${date} ${m}`)) free += 1;\n }\n m += len + (a.bufferMinutes ?? 0);\n }\n }\n }\n return free;\n };\n (spec.walk ?? []).forEach((st, wi) => {\n if (st?.action?.kind !== \"open\" || st.action.surface !== e.token || st.expect?.kind !== \"renders\") return;\n const want = st.expect.minItems;\n const short = refWeek0.map((d0) => ({ d0, n: freeSlots(d0) })).filter((x) => x.n < want);\n if (short.length) say(`walk[${wi}].expect`, `\"${e.title}\" offers ${Math.min(...short.map((x) => x.n))} free times when installed on a ${short.map((x) => WEEKDAY_NAMES[dayOfWeek(x.d0)] ?? x.d0).join(\", \")}, fewer than the ${want} the step expects.`);\n });\n }\n\n // ── row actions that set the stage obey the stage rules ──\n for (const e of extras) {\n if (e.kind !== \"row_action\" || e.actionKind !== \"update\") continue;\n for (const st of e.steps ?? []) {\n const rules = stageRules.get(`${e.table}.${st.field}`);\n if (!rules || st.set !== \"value\" || typeof st.value !== \"string\") continue;\n const to = st.value;\n if (rules.transitions?.length && !rules.transitions.some((t) => t.to === to)) say(`extras (${e.token})`, `\"${e.name}\" puts a record in \"${to}\", which no stage rule lets anything move into.`);\n const sets = new Set((e.steps ?? []).filter((x) => x.set === \"value\").map((x) => x.field));\n for (const k of rules.requires?.[to] ?? []) if (!sets.has(k)) say(`extras (${e.token})`, `\"${e.name}\" puts a record in \"${to}\", which needs \"${k}\" filled; the action does not fill it, so the store would refuse it.`);\n }\n }\n for (const e of extras) {\n if (e.kind !== \"notification\" || e.when.event !== \"stage_entered\") continue;\n const rules = stageRules.get(`${e.when.table}.${[...stageRules.values()].find((r) => r.table === e.when.table)?.stageField}`);\n if (rules?.transitions?.length && e.when.stage && !rules.transitions.some((t) => t.to === e.when.stage)) say(`extras (${e.token})`, `It fires on entering \"${e.when.stage}\", which no stage rule lets anything move into.`);\n }\n\n // ── the documents say something ──\n for (const e of extras) {\n if (e.kind !== \"document\") continue;\n const tokens = new Set([...`${e.title}\\n${e.body}`.matchAll(MERGE_TOKEN)].map((m) => m[1]));\n if (tokens.size < 2) say(`extras (${e.token}).body`, \"A document this business sends carries the record's own facts — at least two merge fields.\");\n }\n\n // ── the agent's question is about what it says it is about ──\n if (agent?.question?.expect) {\n const qq = agent.question;\n const ask = norm(qq.ask);\n const words = (t: string) => norm(t).split(\" \").filter((w) => w.length >= 4);\n // A label of short words only (\"DJ pay\", \"Fee\") is named by its whole words, never unmatchable.\n const askWords = new Set(ask.split(\" \"));\n const mentions = (t: string) =>\n (!!norm(t) && ask.includes(norm(t))) ||\n words(t).some((w) => ask.includes(w.replace(/s$/, \"\"))) ||\n (words(t).length === 0 && norm(t).split(\" \").filter(Boolean).some((w) => w.length >= 3 && (askWords.has(w) || askWords.has(`${w}s`))));\n for (const [k, v] of Object.entries(qq.expect.filter ?? {})) {\n if (typeof v === \"string\" && !mentions(v) && !ask.includes(norm(v))) say(\"agent.question.ask\", `It filters on ${k} = \"${v}\", and the question never says so.`);\n }\n const qt = byToken.get(qq.expect.table);\n const mf = qq.expect.measure.key ? fieldOf(qq.expect.table, qq.expect.measure.key) : undefined;\n if (mf && !mentions(mf.label)) say(\"agent.question.ask\", `It adds up \"${mf.label}\", and the question never names it.`);\n if (qq.expect.measure.op === \"count\" && qt && !mentions(qt.labelPlural) && !mentions(qt.labelSingular)) say(\"agent.question.ask\", `It counts ${qt.labelPlural}, and the question never says what it counts.`);\n const why = qq.whyItMatters?.trim() ?? \"\";\n if (why.split(/\\s+/).length < 8 || /^(because|it matters|important|to know|for reporting|n\\/?a)\\.?$/i.test(why)) say(\"agent.question.whyItMatters\", \"Say in a full sentence what the owner does differently depending on the answer.\");\n const unit = (qq.expect.unit ?? \"\").trim().toLowerCase();\n if (mf?.unit && qq.expect.measure.op !== \"count\" && ![\"filled\", \"empty\", \"unique\"].includes(qq.expect.measure.op) && unit !== mf.unit.toLowerCase()) {\n say(\"agent.question.expect.unit\", `\"${mf.label}\" is kept in ${mf.unit}, so the answer is in ${mf.unit}, not \"${qq.expect.unit}\".`);\n }\n if (qq.expect.measure.op === \"count\" && qt && !mentions(unit) && !norm(qt.labelPlural).includes(unit.replace(/s$/, \"\"))) {\n say(\"agent.question.expect.unit\", `A count of ${qt.labelPlural} is in ${qt.labelPlural.toLowerCase()}, not \"${qq.expect.unit}\".`);\n }\n const readTables = new Set<string>([qq.expect.table]);\n for (const st of spec.walk ?? []) for (const x of [st?.action, st?.expect] as Array<{ table?: string } | undefined>) if (x?.table) readTables.add(x.table);\n if (agent.variables?.length && !agent.variables.some((v) => v.table === qq.expect.table)) {\n say(\"agent.variables\", `The question reads \"${qq.expect.table}\", and no variable gives the agent that table.`);\n }\n agent.variables?.forEach((v, vi) => {\n if (!readTables.has(v.table)) say(`agent.variables[${vi}]`, `\"${v.name}\" is bound to \"${v.table}\", which neither the question nor the walk reads.`);\n });\n }\n\n // ── the walk does something, and says what it does ──\n const walk = spec.walk ?? [];\n const opens = walk.filter((st) => st?.action?.kind === \"open\").length;\n if (opens > 1) say(\"walk\", `${opens} steps only open a screen; a teaching walk opens at most one and then does something.`);\n if (!walk.some((st) => [\"move\", \"moves\", \"edit\", \"import\", \"archive\", \"restore\"].includes(st?.action?.kind ?? \"\"))) say(\"walk\", \"No step changes anything; at least one moves, edits, imports or archives.\");\n const third = walk[2]?.action?.kind;\n if (walk.length === 3 && ![\"ask_agent\", \"submit_form\"].includes(third ?? \"\")) say(\"walk[2]\", \"The last step closes the loop: it asks the agent, or comes in through a front door (a form) — or add a fourth step that asks the agent.\");\n // At least one step exercises what the template teaches.\n const opened = (pred: (token: string) => boolean) => walk.some((st) => st?.action?.kind === \"open\" && pred(st.action.surface));\n const viewKind = (kind: string) => (token: string) => views.some((v) => v.token === token && v.kind === kind);\n const extraKind = (kind: string) => (token: string) => extras.some((e) => e.token === token && e.kind === kind);\n const touches = (pred: (table: string) => boolean) =>\n walk.some((st) => {\n const a = st?.action as { kind?: string; table?: string; surface?: string } | undefined;\n if (!a) return false;\n if (a.table) return pred(a.table);\n const v = views.find((x) => x.token === a.surface);\n return !!v && pred(v.table);\n });\n const lookupTables = (t: string) => !!byToken.get(t)?.fields.some((f) => f.parityType === \"lookup\" || f.parityType === \"rollup\");\n const governedShown = walk.some((st) => {\n const a = st?.action as { kind?: string; table?: string; surface?: string; field?: string; set?: Record<string, unknown> } | undefined;\n const isGoverned = (t: string, k: string) => {\n const f = fieldOf(t, k);\n return !!f && f.contextPolicy === \"exclude\" && (f.sensitivity === \"restricted\" || f.sensitivity === \"confidential\");\n };\n if (a?.kind === \"open\") {\n const v = views.find((x) => x.token === a.surface);\n return !!v && (byToken.get(v.table)?.fields ?? []).some((f) => isGoverned(v.table, f.key) && !(v.hiddenFields ?? []).includes(f.key));\n }\n if (a?.kind === \"edit\" && a.table) return [...Object.keys(a.set ?? {}), a.field ?? \"\"].some((k) => isGoverned(a.table!, k));\n return false;\n });\n const EXERCISED: Record<string, boolean> = {\n kanban: opened(viewKind(\"kanban\")) || walk.some((st) => st?.action?.kind === \"move\" || st?.action?.kind === \"moves\"),\n calendar: opened(viewKind(\"calendar\")),\n timeline: opened(viewKind(\"timeline\")),\n gallery: opened(viewKind(\"gallery\")),\n forms: walk.some((st) => st?.action?.kind === \"submit_form\"),\n bookings: opened(extraKind(\"booking\")),\n portals: opened(extraKind(\"portal\")),\n dashboards: opened(extraKind(\"dashboard\")),\n drill_down: opened(extraKind(\"drill_down\")),\n checklists: opened(extraKind(\"checklist\")),\n documents_esign: opened(extraKind(\"document\")) || touches((t) => extras.some((e) => e.kind === \"document\" && e.table === t)),\n relations_rollups: touches(lookupTables),\n dimensions: opened(extraKind(\"drill_down\")) || opened(extraKind(\"dashboard\")) || touches((t) => (spec.dimensions ?? []).some((d) => d.table === t)),\n agents: walk.some((st) => st?.action?.kind === \"ask_agent\"),\n field_governance: governedShown,\n import_upsert: walk.some((st) => st?.action?.kind === \"import\"),\n };\n if (spec.teaches && EXERCISED[spec.teaches] === false) say(\"walk\", `No step exercises \"${spec.teaches}\", the feature this template teaches; make one step open or use it.`);\n walk.forEach((st, i) => {\n const a = st?.action;\n const says = norm(st?.says ?? \"\");\n // Named = the whole name, or (for a long title) at least two of its distinctive words.\n const named = (t: string | undefined) => {\n if (!t) return false;\n if (says.includes(norm(t))) return true;\n const long = [...new Set(norm(t).split(\" \").filter((w) => w.length >= 4))];\n // A name of short words only is named by its whole words.\n const words = long.length ? long : [...new Set(norm(t).split(\" \").filter((w) => w.length >= 2))];\n const said = new Set(says.split(\" \"));\n return words.length > 0 && words.filter((w) => said.has(w) || said.has(`${w}s`)).length >= Math.min(2, words.length);\n };\n if (!a) return;\n if (a.kind === \"move\" || a.kind === \"edit\" || a.kind === \"archive\" || a.kind === \"restore\") {\n const t = byToken.get(a.table);\n const row = t?.rows.find((r) => r.key === a.row);\n const title = row ? storeText(row.values?.[t?.titleField ?? \"\"]) ?? undefined : undefined;\n if (!named(title)) say(`walk[${i}].says`, `Name the record it acts on (\"${title}\").`);\n if (a.kind === \"edit\") {\n const keys = a.set ? Object.keys(a.set) : a.field ? [a.field] : [];\n const labels = keys.map((k) => fieldOf(a.table, k)?.label).filter((l): l is string => !!l);\n if (labels.length && !labels.some((l) => named(l))) say(`walk[${i}].says`, `Name a field it changes (\"${labels[0]}\").`);\n }\n if (a.kind === \"move\" && !named(a.to)) say(`walk[${i}].says`, `Say where it moves the record (\"${a.to}\").`);\n }\n if (a.kind === \"moves\") {\n for (const m of a.moves ?? []) {\n const t = byToken.get(m.table);\n const title = storeText(t?.rows.find((r) => r.key === m.row)?.values?.[t?.titleField ?? \"\"]) ?? undefined;\n if (!named(title)) say(`walk[${i}].says`, `Name each record it moves (\"${title}\").`);\n }\n }\n if (a.kind === \"open\") {\n const v = views.find((x) => x.token === a.surface);\n const x = extras.find((e) => e.token === a.surface) as { name?: string; title?: string } | undefined;\n const name = v?.name ?? forms.find((f) => f.token === a.surface)?.name ?? x?.name ?? x?.title;\n if (!named(name)) say(`walk[${i}].says`, `Name the screen it opens (\"${name}\").`);\n }\n if (a.kind === \"import\" && !named(a.sourceName.replace(/\\.(csv|xlsx)$/i, \"\"))) say(`walk[${i}].says`, `Name the file it imports (\"${a.sourceName}\").`);\n if (a.kind === \"submit_form\") {\n const fm = forms.find((x) => x.token === a.form);\n if (!named(fm?.name)) say(`walk[${i}].says`, `Name the form it fills in (\"${fm?.name}\").`);\n }\n });\n\n // ═══ round 6: a template that installs cleanly and behaves like the business ═══\n\n // ── a new record can always be made: forms and imports carry every required field ──\n // The stage is set by moves, never asked. slot/status/booked_with are the BOOKING door's own\n // fields: exempt for a booking page, never for a plain form on the same table.\n const doorOwned = (table: string, key: string) => stageFieldsOf.has(`${table}.${key}`);\n const mustGive = (table: string) => (byToken.get(table)?.fields ?? []).filter((f) => f.required && !isComputed(f) && (f.source ?? \"manual\") === \"manual\" && f.default === undefined && !doorOwned(table, f.key));\n for (const form of forms) {\n const asked = new Set((form.fields ?? []).map((q) => q.fieldKey));\n for (const f of mustGive(form.table)) {\n if (!asked.has(f.key)) say(`forms (${form.token})`, `\"${form.name}\" never asks for \"${f.label}\", which every ${byToken.get(form.table)?.labelSingular.toLowerCase() ?? \"record\"} must have — the store would refuse each answer. Ask it, or give the field a default.`);\n }\n }\n (spec.walk ?? []).forEach((st, i) => {\n const a = st?.action;\n if (a?.kind !== \"import\") return;\n const cols = new Set(a.columns ?? []);\n const live = (state0.get(a.table) ?? []).map((r) => (storeText(r.values?.[a.dedupeKey]) ?? \"\").trim());\n (a.rows ?? []).forEach((cells, ri) => {\n const keyValue = (cells[a.columns.indexOf(a.dedupeKey)] ?? \"\").trim();\n if (live.includes(keyValue)) return;\n for (const f of mustGive(a.table)) {\n const ci = a.columns.indexOf(f.key);\n if (!cols.has(f.key) || !(cells[ci] ?? \"\").trim()) say(`walk[${i}].action.rows[${ri}]`, `The new row \"${keyValue}\" has no \"${f.label}\", which every ${byToken.get(a.table)?.labelSingular.toLowerCase() ?? \"record\"} must have; the import would refuse it.`);\n }\n });\n });\n\n // ── relationships[] and relation fields name each other ──\n for (const t of own) {\n for (const f of t.fields) {\n if (!isRelation(f) || !f.relationTarget || f.parityType === \"attachment\") continue;\n if (!(spec.relationships ?? []).some((r) => r.fromTable === t.token && r.fromField === f.key)) {\n say(`tables (${t.token}).fields (${f.key})`, `\"${f.label}\" points at \"${f.relationTarget}\" but relationships[] does not state it; add the sentence of domain truth with its flavour and what happens on delete.`);\n }\n }\n }\n\n // ── the agent's question is about a slice, not one row ──\n if (agent?.question?.expect) {\n const qe = agent.question.expect;\n const n = (byToken.get(qe.table)?.rows ?? []).filter((r) => storeFilterMatches({ key: r.key, values: r.values }, qe.filter, tz)).length;\n if (n < 3) say(\"agent.question.expect.filter\", `The question reads ${n} row(s); a question an owner asks an assistant adds up at least three (a single record is a look-up, not an answer).`);\n }\n\n // ── the seed is spread like a real business's ──\n for (const v of views) {\n if (v.kind !== \"calendar\" && v.kind !== \"timeline\") continue;\n const key = v.kind === \"calendar\" ? v.dateField : v.startField;\n const days = distinctDays(v.table, key);\n if (days < 5) saySeed(`views (${v.token})`, `The ${v.kind} \"${v.name}\" would show seed records on only ${days} day(s); spread them across at least five.`);\n }\n if (main) {\n // The spread applies to the template's MAIN board only: the main table's stage rules, when the\n // main table is also what its first board (kanban) shows. A secondary table that carries\n // stage rules so a grouped step can move it (supplies mostly \"In stock\") is exempt.\n // Only a BOARD (kanban) grouped by the stage field shows the spread; a grid grouped by stage does not.\n const board = views.find((v) => v.kind === \"kanban\") as (TemplateView & { groupBy?: string }) | undefined;\n const primary = board && board.table === main.token ? [...stageRules.values()].find((x) => x.table === main.token && (!board.groupBy || board.groupBy === x.stageField)) : undefined;\n const pt = primary ? own.find((x) => x.token === primary.table) : undefined;\n if (primary && pt) {\n const counts = new Map<string, number>();\n for (const row of pt.rows) {\n const st = storeText(row.values?.[primary.stageField]);\n if (st) counts.set(st, (counts.get(st) ?? 0) + 1);\n }\n for (const [st, c] of counts) if (c > 0.6 * pt.rows.length) say(`tables (${pt.token})`, `${c} of ${pt.rows.length} ${pt.labelPlural.toLowerCase()} sit in \"${st}\"; a working board spreads across its stages (at most 60% in one).`);\n }\n if ((spec.foundation ?? []).some((f) => f.table === main.token)) say(\"foundation\", `\"${main.token}\" is the main table — the day-to-day work — so it is never foundation data.`);\n }\n const viewSigs = new Map<string, string>();\n for (const v of views) {\n const { token: _t, name: _n, isDefault: _d, ...shape } = v as TemplateView & { token: string; name: string; isDefault?: boolean };\n const sig = JSON.stringify(Object.keys(shape).sort().map((k) => [k, (shape as Record<string, unknown>)[k]]));\n const twin = viewSigs.get(sig);\n if (twin) say(`views (${v.token})`, `\"${v.name}\" shows exactly what \"${twin}\" shows; drop it or give it its own question (a filter, a sort, a grouping).`);\n else viewSigs.set(sig, v.name);\n }\n\n // ═══ on-screen text is layout (common-docs/policies/interface-text-is-layout.md) ═══\n // Budgets from the policy: a label is a few words; secondary text (field help, a form\n // question's help) ≤ 60, one line; a tooltip or description ≤ 140, one sentence; a dialog,\n // confirmation or teaching step ≤ 140, two sentences at most. Who may see a value and whether\n // the AI reads it is sensitivity/contextPolicy — never words on the screen.\n // Sentences, not abbreviations: \"Mr. Ibáñez\", \"Dr. Achebe\", \"e.g.\" and \"a.m.\" end nothing.\n const sentences = (t: string) =>\n t\n .trim()\n .replace(/\\b(?:Mr|Mrs|Ms|Dr|St|Jr|Sr|Mt|No|vs|etc|Inc|Ltd|Co)\\./g, (m) => m.slice(0, -1))\n .replace(/\\b(?:e\\.g|i\\.e|a\\.m|p\\.m)\\./gi, \"x\")\n .split(/[.!?](?:\\s+|$)/)\n .filter((x) => x.trim()).length;\n const LABEL_MAX = 40;\n const IMPLEMENTATION =\n /\\b(?:the\\s+)?(?:ai|a\\.i\\.|agent|assistant|llm|model)\\b[^.]*\\b(?:reads?|sees?|never|cannot|can't|won't|doesn't|does not|is kept)\\b|\\b(?:never|not)\\b[^.]*\\b(?:ai|agent)\\b|\\bthe store\\b|\\bthis field\\b|\\bthis column\\b|\\bthe booking page writes\\b|\\bwrites? (?:a |the )?(?:booked )?time here\\b|\\bcustom\\.[a-z_]+|\\{\\{|\\b[a-z]+_[a-z0-9_]+\\b|\\b(?:sum|avg|count|min|max)\\s*\\(|\\s=\\s/i;\n const STAFF_VOICE = /\\bwe\\b|\\bour system\\b/i;\n const screen = (at: string, text: string | undefined, slot: \"label\" | \"secondary\" | \"tooltip\" | \"dialog\", opts: { publicVoice?: boolean } = {}) => {\n if (!text?.trim()) return;\n const t = text.trim();\n if (slot === \"label\" && (t.length > LABEL_MAX || t.split(/\\s+/).length > 6)) say(at, `\"${t}\" is a label (${t.length} characters); keep it to a few words — the name of the thing, no explanation.`);\n if (slot === \"secondary\" && (t.length > 60 || sentences(t) > 1)) say(at, `\"${t}\" is ${t.length} characters; help text is one line of at most 60, one sentence.`);\n if (slot === \"tooltip\" && (t.length > 140 || sentences(t) > 1)) say(at, `\"${t.slice(0, 60)}…\" is ${t.length} characters; a description is one sentence of at most 140.`);\n if (slot === \"dialog\" && (t.length > 140 || sentences(t) > 2)) say(at, `\"${t.slice(0, 60)}…\" is ${t.length} characters; this slot holds at most 140, two sentences: what happened and what to do.`);\n const impl = IMPLEMENTATION.exec(t);\n if (impl) say(at, `\"${t.slice(0, 70)}\" explains how the system works (\"${impl[0].trim()}\"); that belongs in sensitivity, contextPolicy or the commit, not on screen. Say only what the person needs.`);\n else if (!opts.publicVoice && slot !== \"label\" && STAFF_VOICE.test(t) && !/\\?\\s*$/.test(t)) say(at, `\"${t.slice(0, 70)}\" speaks as \"we\"; on the staff's own screen, name the thing instead.`);\n };\n for (const t of own) {\n screen(`tables (${t.token}).name`, t.name, \"label\");\n screen(`tables (${t.token}).labelPlural`, t.labelPlural, \"label\");\n screen(`tables (${t.token}).labelSingular`, t.labelSingular, \"label\");\n screen(`tables (${t.token}).describes`, t.describes, \"tooltip\");\n for (const f of t.fields) {\n screen(`tables (${t.token}).fields (${f.key}).label`, f.label, \"label\");\n screen(`tables (${t.token}).fields (${f.key}).help`, f.help, \"secondary\");\n for (const c of f.choices ?? []) screen(`tables (${t.token}).fields (${f.key}).choices`, c, \"label\");\n }\n }\n for (const v of views) screen(`views (${v.token}).name`, v.name, \"label\");\n for (const f of forms) {\n const pub = f.audience === \"public\";\n screen(`forms (${f.token}).name`, f.name, \"label\");\n screen(`forms (${f.token}).describes`, f.describes, \"tooltip\");\n screen(`forms (${f.token}).submitLabel`, f.submitLabel, \"label\");\n screen(`forms (${f.token}).confirmation`, f.confirmation, \"dialog\", { publicVoice: pub });\n for (const q of f.fields ?? []) {\n screen(`forms (${f.token}).fields (${q.fieldKey}).ask`, q.ask, \"tooltip\", { publicVoice: pub });\n screen(`forms (${f.token}).fields (${q.fieldKey}).help`, q.help, \"secondary\", { publicVoice: pub });\n }\n }\n for (const e of extras) {\n const at = `extras (${e.token})`;\n if (\"name\" in e) screen(`${at}.name`, e.name, \"label\");\n if (e.kind === \"booking\") {\n screen(`${at}.title`, e.title, \"label\");\n for (const q of e.questions ?? []) {\n screen(`${at}.questions (${q.fieldKey}).ask`, q.ask, \"tooltip\", { publicVoice: true });\n screen(`${at}.questions (${q.fieldKey}).help`, q.help, \"secondary\", { publicVoice: true });\n }\n }\n if (e.kind === \"portal\") screen(`${at}.title`, e.title, \"label\");\n if (e.kind === \"dashboard\") for (const b of e.blocks ?? []) screen(`${at}.blocks (${b.title})`, b.title, \"label\");\n const described = (e as { describes?: unknown }).describes;\n if (typeof described === \"string\") screen(`${at}.describes`, described, \"tooltip\");\n if (e.kind === \"stage_rules\") {\n for (const [st, d] of Object.entries(e.stages ?? {})) screen(`${at}.stages (${st})`, d, \"tooltip\");\n screen(`${at}.movesMessage`, e.movesMessage, \"dialog\");\n }\n }\n (spec.walk ?? []).forEach((w, i) => screen(`walk[${i}].says`, w?.says, \"dialog\", { publicVoice: true }));\n for (const f of spec.foundation ?? []) screen(`foundation (${f.table}).keptFor`, f.keptFor, \"tooltip\");\n\n // ═══ dates agree across relations (parent → child) ═══\n const sideDay = (table: string, row: { values: Record<string, unknown> }, side: string): { at: string | null; ok: boolean } => {\n const [a, b] = side.split(\".\");\n if (!b) {\n const f = fieldOf(table, a ?? \"\");\n return { at: dayOfMoment(row.values?.[a ?? \"\"]), ok: !!f && isDate(f) };\n }\n const via = fieldOf(table, a ?? \"\");\n const far = via?.relationTarget ? fieldOf(via.relationTarget, b) : undefined;\n if (!via?.relationTarget || !far || !isDate(far)) return { at: null, ok: false };\n const target = byToken.get(via.relationTarget)?.rows.find((r) => r.key === row.values?.[a ?? \"\"]);\n return { at: target ? dayOfMoment(target.values?.[b]) : null, ok: true };\n };\n for (const t of own) {\n for (const pair of t.datePairs ?? []) {\n const pat = `tables (${t.token}).datePairs`;\n if (pair.onlyWhen && !fieldOf(t.token, pair.onlyWhen.field)) say(pat, `onlyWhen names \"${pair.onlyWhen.field}\", which \"${t.token}\" does not declare.`);\n for (const r of t.rows) {\n const x = sideDay(t.token, r, pair.earlier);\n const y = sideDay(t.token, r, pair.later);\n if (!x.ok || !y.ok) {\n say(pat, `[${pair.earlier} → ${pair.later}] names something that is not a date \"${t.token}\" can reach.`);\n break;\n }\n const applies = !pair.onlyWhen || pair.onlyWhen.values.includes(storeText(r.values?.[pair.onlyWhen.field]) ?? \"\");\n const title = storeText(r.values?.[t.titleField]) ?? r.key;\n if (!applies && x.at === null && y.at !== null && pair.onlyWhen) {\n say(`tables (${t.token}).rows (${r.key})`, `\"${title}\" has ${pair.later} but is \"${storeText(r.values?.[pair.onlyWhen.field])}\"; it only has one when ${pair.onlyWhen.field} is ${pair.onlyWhen.values.join(\" or \")}.`);\n }\n if (applies && x.at && y.at && x.at > y.at) say(`tables (${t.token}).rows (${r.key})`, `\"${title}\": ${pair.later} (${y.at}) comes before ${pair.earlier} (${x.at}); the template says it never does.`);\n }\n }\n // Conventional pairs nobody has to remember: a bill is issued after the work it bills began;\n // a report is due only on a grant that was awarded.\n for (const f of t.fields.filter((x) => isDate(x) && !x.absoluteDates)) {\n // Only a bill: a certificate's or license's \"issued\" date rightly predates a person's start.\n const billing = /(invoice|bill|statement|receipt|payment|charge|fee)/i.test(`${t.token} ${t.labelSingular}`);\n if (billing && /(issued|billed|invoice)/.test(f.key)) {\n for (const rel of t.fields.filter((x) => isRelation(x) && x.relationTarget && x.parityType !== \"attachment\")) {\n const start = byToken.get(rel.relationTarget ?? \"\")?.fields.find((x) => isDate(x) && /(start|engag|opened|began|work_from|kickoff)/.test(x.key));\n if (!start) continue;\n for (const r of t.rows) {\n const x = sideDay(t.token, r, `${rel.key}.${start.key}`);\n const y = sideDay(t.token, r, f.key);\n if (x.at && y.at && y.at < x.at) say(`tables (${t.token}).rows (${r.key})`, `\"${storeText(r.values?.[t.titleField]) ?? r.key}\" is ${f.label.toLowerCase()} ${y.at}, before its ${rel.label.toLowerCase()} began (${x.at}).`);\n }\n }\n }\n // Only on a grant table: an appraisal, an inspection or an audit has a \"report due\" that has nothing to do\n // with an award (two writers renamed honest fields to get past this).\n if (/report_due|reporting_due/.test(f.key) && /grant|award|funder|funding/i.test(`${t.token} ${t.name} ${t.labelSingular}`)) {\n const st = t.fields.find((x) => isChoice(x) && /status|stage/.test(x.key));\n if (!st) continue;\n for (const r of t.rows) {\n const v = storeText(r.values?.[st.key]) ?? \"\";\n if (filled(r.values?.[f.key]) && !/award|active|funded|report|closed|complete/i.test(v)) {\n say(`tables (${t.token}).rows (${r.key})`, `\"${storeText(r.values?.[t.titleField]) ?? r.key}\" has a ${f.label.toLowerCase()} but is \"${v}\"; a report is due only once the grant is awarded.`);\n }\n }\n }\n }\n }\n const crossesRelation = own.some((t) => [...(t.datePairs ?? []).flatMap((p) => [p.earlier, p.later]), ...(t.before ?? []).flat()].some((side) => side.includes(\".\")));\n const grants = own.some((t) => /grant/i.test(`${t.token} ${t.name}`));\n const parentChildDates = own.some((t) =>\n t.fields.some((f) => isDate(f) && !f.absoluteDates) &&\n t.fields.some((rf) => isRelation(rf) && rf.relationTarget && own.find((p) => p.token === rf.relationTarget)?.fields.some((pf) => isDate(pf) && !pf.absoluteDates)),\n );\n if ((spec.job === \"billing\" || grants) && parentChildDates && !crossesRelation) {\n say(\"tables\", `A ${grants ? \"grants\" : \"billing\"} template dates records against the records they hang off; declare at least one datePairs entry across a relation (e.g. {\"earlier\": \"engagement.start_date\", \"later\": \"issued_on\"}).`);\n }\n\n // ═══ every seed value is one of its field's choices (single and multi) ═══\n for (const t of tables) {\n for (const f of t.fields.filter((x) => isChoice(x) && x.choices?.length)) {\n for (const r of t.rows) {\n const v = unwrap(r.values?.[f.key]);\n for (const one of Array.isArray(v) ? v : v === undefined || v === null || v === \"\" ? [] : [v]) {\n if (typeof one !== \"string\" || !f.choices!.includes(one)) {\n say(`tables (${t.token}).rows (${r.key}).${f.key}`, `\"${String(one)}\" is not one of \"${f.label}\"'s choices (${f.choices!.join(\", \")}). Use one of them, or add it to the list.`);\n }\n }\n }\n }\n }\n\n // ═══ moments that already happened, and stored copies the store would compute ═══\n for (const t of own) {\n const raw = tablesRaw.find((x) => x.token === t.token);\n // Date-driven status: the band the date falls in, on every install weekday.\n const sbd = t.statusByDate;\n if (sbd) {\n const sf = fieldOf(t.token, sbd.field);\n const df = fieldOf(t.token, sbd.dateField);\n if (!sf || !df || !isDate(df)) say(`tables (${t.token}).statusByDate`, `It reads \"${sbd.dateField}\" into \"${sbd.field}\"; both have to be fields of \"${t.token}\", the first a date.`);\n for (const b of sbd.bands ?? []) if (sf?.choices?.length && !sf.choices.includes(b.status)) say(`tables (${t.token}).statusByDate`, `\"${b.status}\" is not one of \"${sf.label}\"'s choices.`);\n const banded = new Set((sbd.bands ?? []).map((b) => b.status));\n for (const r of raw?.rows ?? []) {\n const st = storeText(r.values?.[sbd.field]) ?? \"\";\n const v = r.values?.[sbd.dateField];\n if (!banded.has(st) || typeof v !== \"string\") continue;\n const off: string[] = [];\n for (const d0 of refWeek0) {\n const dd = (resolveDateToken(v, d0, tz) ?? v).slice(0, 10);\n const diff = Math.round((Date.parse(`${dd}T00:00:00Z`) - Date.parse(`${d0}T00:00:00Z`)) / 86_400_000);\n const band = (sbd.bands ?? []).find((b) => (b.from === undefined || diff >= b.from) && (b.to === undefined || diff < b.to));\n if (band && band.status !== st) off.push(`${WEEKDAY_NAMES[dayOfWeek(d0)] ?? d0} (${band.status})`);\n }\n if (off.length) say(`tables (${t.token}).rows (${r.key}).${sbd.field}`, `\"${st}\" disagrees with its ${df?.label.toLowerCase() ?? sbd.dateField} ${v} when installed on a ${off.join(\", \")}.`);\n }\n }\n // An UNFILTERED rollup adds every linked record, so a status or time word in its name is a promise it\n // cannot keep. A rollup with a `filter` (live since 2026-10-03, custom.field_declare) adds only what the\n // filter picks, and may be named for it (\"Copay owed\").\n const ROLLUP_WORDS = /\\b(open|booked|upcoming|unpaid|outstanding|active|monthly|weekly|yearly|annual|on the books|lined up|ordered|pending|overdue|scheduled|confirmed|paid|completed|current|remaining|this (?:week|month|year|season)|ytd|mtd)\\b/i;\n for (const f of t.fields.filter((x) => x.parityType === \"rollup\" && !(x.filter && Object.keys(x.filter).length))) {\n const said = `${f.label} ${f.key.replace(/_/g, \" \")}`;\n const hit = ROLLUP_WORDS.exec(said);\n if (hit) say(`tables (${t.token}).fields (${f.key})`, `\"${f.label}\" says \"${hit[1]}\", but this rollup adds every linked record, whatever its status or date. Give it a filter that picks those records, or name it for all of them.`);\n }\n // A stored parent number that just repeats its children's amounts: a rollup computes it.\n for (const child of own) {\n for (const rel of child.fields.filter((f) => isRelation(f) && f.relationTarget === t.token && !f.multi && (f.relationMax ?? 1) === 1)) {\n const byParent = new Map<unknown, SeedRow[]>();\n for (const c of child.rows) byParent.set(c.values?.[rel.key], [...(byParent.get(c.values?.[rel.key]) ?? []), c]);\n // Money only, and never a bound (a budget, a cap, a pay range): a bound SHOULD sit near what it bounds.\n const money = (f: TemplateField) => f.parityType === \"currency\" && !isComputed(f) && !/(^|_| )(low|high|min|max|range|budget|limit|cap|ceiling|floor|expect\\w*)( |_|$)/i.test(`${f.key} ${f.label}`);\n for (const pf of t.fields.filter(money)) {\n for (const cf of child.fields.filter(money)) {\n const judged = t.rows\n .map((pr) => {\n const pv = Number(storeText(pr.values?.[pf.key]));\n const kids = (byParent.get(pr.key) ?? []).filter((c) => filled(c.values?.[cf.key])).map((c) => Number(storeText(c.values?.[cf.key]))).filter((n) => Number.isFinite(n));\n return filled(pr.values?.[pf.key]) && Number.isFinite(pv) && pv !== 0 && kids.length ? { pv, kids } : null;\n })\n .filter((x): x is { pv: number; kids: number[] } => !!x);\n if (judged.length < 3) continue;\n const near = (a: number, b: number) => Math.abs(a - b) <= 0.1 * Math.abs(a);\n // \"One of its children's amounts\" only where it HAS one child (then the sum is that amount): a\n // service's usual length matching one of its many tickets is a default, not a copy.\n const copies = judged.filter(({ pv, kids }) => near(pv, kids.reduce((a, b) => a + b, 0))).length;\n if (copies / judged.length >= 0.75) say(`tables (${t.token}).fields (${pf.key})`, `\"${pf.label}\" repeats its ${child.labelPlural.toLowerCase()}' \"${cf.label}\" on ${copies} of ${judged.length} rows; make it a rollup (via the ${child.labelPlural.toLowerCase()}, sum of \"${cf.label}\") so it never drifts.`);\n }\n }\n }\n }\n // \"Requested on\", \"Received at\", \"Date filed\": the moment is past (or now) on every install day.\n for (const f of t.fields.filter((ff) => isDate(ff) && /^(?:date_)?(?:requested|received|submitted|created|opened|reported|filed)(?:_(?:on|at|date))?$/.test(ff.key))) {\n for (const r of raw?.rows ?? []) {\n const v = r.values?.[f.key];\n if (typeof v !== \"string\") continue;\n const late = refWeek0.filter((day) => (resolveDateToken(v, day, tz) ?? v).slice(0, 10) > day);\n if (late.length) say(`tables (${t.token}).rows (${r.key}).${f.key}`, `\"${f.label}\" is ${v}, after the install day on a ${late.map((d) => WEEKDAY_NAMES[dayOfWeek(d)] ?? d).join(\", \")}; something requested or received has already happened.`);\n }\n }\n const rows = t.rows;\n const same = (x: unknown, y: unknown) => {\n const a = storeText(x);\n const b = storeText(y);\n if (a === null || b === null) return false;\n const qa = parseNumeric(a);\n const qb = parseNumeric(b);\n return qa && qb ? qCmp(qa, qb) === 0 : a.trim() === b.trim();\n };\n // A stored copy of a lookup the table already has.\n for (const l of t.fields.filter((ff) => ff.parityType === \"lookup\" && ff.via && ff.pick)) {\n const via = fieldOf(t.token, l.via!);\n const target = via?.relationTarget ? byToken.get(via.relationTarget) : undefined;\n if (!target) continue;\n const far = (r: SeedRow) => {\n const ref = r.values?.[l.via!];\n return target.rows.find((x) => x.key === (Array.isArray(ref) ? ref[0] : ref))?.values?.[l.pick!];\n };\n for (const sf of t.fields.filter((ff) => !isComputed(ff) && !isRelation(ff) && ff.key !== l.key)) {\n const have = rows.filter((r) => filled(r.values?.[sf.key]));\n if (have.length >= 3 && have.every((r) => same(r.values?.[sf.key], far(r)))) {\n say(`tables (${t.token}).fields (${sf.key})`, `\"${sf.label}\" repeats \"${l.label}\" on every row; drop it and use the lookup, which follows the linked record.`);\n }\n }\n }\n // A stored number that is just end − start.\n const moments = t.fields.filter((ff) => isDate(ff));\n for (const nf of t.fields.filter((ff) => isNumber(ff) && !isComputed(ff))) {\n for (const a of moments) {\n for (const b of moments) {\n if (a === b) continue;\n const have = rows.filter((r) => filled(r.values?.[nf.key]) && filled(r.values?.[a.key]) && filled(r.values?.[b.key]));\n if (have.length < 3) continue;\n const diffOk = (unit: number) =>\n have.every((r) => {\n const x = Date.parse(storeText(r.values?.[a.key]) ?? \"\");\n const y = Date.parse(storeText(r.values?.[b.key]) ?? \"\");\n const n = Number(storeText(r.values?.[nf.key]));\n return Number.isFinite(x) && Number.isFinite(y) && y > x && Math.abs((y - x) / unit - n) < 0.01;\n });\n const hours = diffOk(3_600_000);\n if (hours || diffOk(86_400_000)) {\n const whole = have.every((r) => Number.isInteger(Number(storeText(r.values?.[nf.key]))));\n const fx = hours ? (whole ? `DATEDIFF({${a.label}}, {${b.label}}, 'hours')` : `DATEDIFF({${a.label}}, {${b.label}}, 'minutes') / 60`) : `DATEDIFF({${a.label}}, {${b.label}}, 'days')`;\n say(`tables (${t.token}).fields (${nf.key})`, `\"${nf.label}\" is \"${b.label}\" minus \"${a.label}\" on every row; make it a formula field (parityType \"formula\", formula \"${fx}\") so it never drifts.`);\n }\n }\n }\n }\n }\n\n // ═══ cross-table realism, declared on the child table ═══\n const parentOf = (t: TemplateTable, relation: string, row: { values: Record<string, unknown> }) => {\n const rel = fieldOf(t.token, relation);\n const ptab = rel?.relationTarget ? byToken.get(rel.relationTarget) : undefined;\n const ref = row.values?.[relation];\n return { rel, ptab, prow: ptab?.rows.find((x) => x.key === (Array.isArray(ref) ? ref[0] : ref)) };\n };\n const titleOf = (t: TemplateTable | undefined, r: { key: string; values: Record<string, unknown> } | undefined) => (r ? storeText(r.values?.[t?.titleField ?? \"\"]) ?? r.key : \"\");\n const statusOf = (t: TemplateTable) => t.fields.find((f) => isChoice(f) && /(^|_)(status|stage)$/.test(f.key));\n for (const t of own) {\n const at = `tables (${t.token})`;\n // Single relations only: a list held on the parent (\"time_entries\") is the same link seen from the other side.\n const rels = t.fields.filter((f) => isRelation(f) && f.relationTarget && f.parityType !== \"attachment\" && !f.multi && (f.relationMax ?? 1) === 1 && own.some((p) => p.token === f.relationTarget));\n for (const d of t.childDates ?? []) {\n const rel = fieldOf(t.token, d.relation);\n const pf = rel?.relationTarget ? fieldOf(rel.relationTarget, d.parentField) : undefined;\n const cf = fieldOf(t.token, d.field);\n if (!rel?.relationTarget || !pf || !cf || !isDate(pf) || !isDate(cf)) {\n say(`${at}.childDates`, `[${d.relation}.${d.parentField} → ${d.field}] needs a relation of \"${t.token}\" and a date on each side.`);\n continue;\n }\n for (const r of t.rows) {\n const { ptab, prow } = parentOf(t, d.relation, r);\n const c = dayOfMoment(r.values?.[d.field]);\n const pd = prow ? dayOfMoment(prow.values?.[d.parentField]) : null;\n if (c && pd && c < pd) say(`${at}.rows (${r.key})`, `\"${titleOf(t, r)}\" has ${cf.label.toLowerCase()} ${c}, before its ${rel.label.toLowerCase()} \"${titleOf(ptab, prow)}\" ${pf.label.toLowerCase()} ${pd}.`);\n }\n }\n for (const w of t.withinParent ?? []) {\n const rel = fieldOf(t.token, w.relation);\n const pf = rel?.relationTarget ? fieldOf(rel.relationTarget, w.parentField) : undefined;\n const cf = fieldOf(t.token, w.field);\n if (!rel?.relationTarget || !pf || !cf || !isNumber(pf) || !isNumber(cf)) {\n say(`${at}.withinParent`, `[${w.field} ${w.op} ${w.relation}.${w.parentField}] needs a relation of \"${t.token}\" and a number on each side.`);\n continue;\n }\n for (const r of t.rows) {\n if (w.unless && w.unless.values.includes(storeText(r.values?.[w.unless.field]) ?? \"\")) continue;\n const { ptab, prow } = parentOf(t, w.relation, r);\n const c = parseNumeric(storeText(r.values?.[w.field]) ?? \"\");\n const pv = prow ? parseNumeric(storeText(prow.values?.[w.parentField]) ?? \"\") : null;\n if (c && pv && (w.op === \"<=\" ? qCmp(c, pv) > 0 : qCmp(c, pv) < 0)) {\n say(`${at}.rows (${r.key})`, `\"${titleOf(t, r)}\" has ${cf.label.toLowerCase()} ${storeText(r.values?.[w.field])}, ${w.op === \"<=\" ? \"above\" : \"below\"} \"${titleOf(ptab, prow)}\"'s ${pf.label.toLowerCase()} (${storeText(prow?.values?.[w.parentField])}).`);\n }\n }\n }\n for (const a of t.statusAgrees ?? []) {\n const rel = fieldOf(t.token, a.relation);\n const ptab = rel?.relationTarget ? byToken.get(rel.relationTarget) : undefined;\n if (!rel?.relationTarget || !ptab || !fieldOf(t.token, a.field) || !fieldOf(ptab.token, a.parentField)) {\n say(`${at}.statusAgrees`, `[${a.field} → ${a.relation}.${a.parentField}] needs a relation of \"${t.token}\" and a status field on each side.`);\n continue;\n }\n const perParent = new Map<string, string[]>();\n for (const r of t.rows) {\n const st = storeText(r.values?.[a.field]) ?? \"\";\n if (!a.childStatus.includes(st)) continue;\n const { prow } = parentOf(t, a.relation, r);\n if (!prow) continue;\n perParent.set(prow.key, [...(perParent.get(prow.key) ?? []), titleOf(t, r)]);\n const ps = storeText(prow.values?.[a.parentField]) ?? \"\";\n if (!a.parentStatus.includes(ps)) say(`${at}.rows (${r.key})`, `\"${titleOf(t, r)}\" is ${st}, so \"${titleOf(ptab, prow)}\" should be ${a.parentStatus.join(\" or \")}, but it is \"${ps}\".`);\n }\n if (a.maxPerParent !== undefined) {\n for (const [pk, kids] of perParent) {\n if (kids.length > a.maxPerParent) say(`${at}.statusAgrees`, `\"${titleOf(ptab, ptab.rows.find((x) => x.key === pk))}\" has ${kids.length} ${t.labelPlural.toLowerCase()} in ${a.childStatus.join(\"/\")} (${kids.join(\", \")}); at most ${a.maxPerParent}.`);\n }\n }\n }\n // A relation whose two sides both carry a schedule date, or both a status, states how they agree.\n for (const rel of rels) {\n const parent = own.find((p) => p.token === rel.relationTarget)!;\n const bothDates = t.fields.some((f) => isDate(f) && !f.absoluteDates) && parent.fields.some((f) => isDate(f) && !f.absoluteDates);\n const bothStatus = !!statusOf(t) && !!statusOf(parent);\n const datesStated = (t.childDates ?? []).some((d) => d.relation === rel.key) || [...(t.datePairs ?? []).flatMap((p) => [p.earlier, p.later]), ...(t.before ?? []).flat()].some((side) => side.startsWith(`${rel.key}.`));\n const statusStated = (t.statusAgrees ?? []).some((a) => a.relation === rel.key);\n const independent = (t.independentOf?.[rel.key] ?? \"\").trim().split(/\\s+/).length >= 3;\n if (independent) continue;\n if (bothDates && !datesStated) say(`${at}.childDates`, `\"${t.token}\" and its ${rel.label.toLowerCase()} (\"${parent.token}\") both carry dates; say how they agree, e.g. {\"relation\": \"${rel.key}\", \"field\": \"<this table's date>\", \"parentField\": \"<${parent.token}'s date>\"} or say why they are independent in independentOf {\"${rel.key}\": \"<reason>\"}.`);\n if (bothStatus && !statusStated) say(`${at}.statusAgrees`, `\"${t.token}\" and its ${rel.label.toLowerCase()} (\"${parent.token}\") both carry a status; say which child statuses need which parent status (statusAgrees), e.g. a Closed deal means a Sold listing.`);\n }\n // A stored count of linked rows is a rollup the store can compute. A bare \"size\" (a party of 4, a 12-inch\n // pipe) is a typed fact, not a count of anything linked, so only a roster/team/class size counts.\n for (const f of t.fields.filter((x) => isNumber(x) && !isComputed(x) && /(^|_)(count|roster_size|team_size|class_size|number_of|enrolled|headcount|players|members)($|_)/.test(x.key))) {\n const linked = own.find((c) => c.fields.some((cf) => isRelation(cf) && cf.relationTarget === t.token));\n const declared = (t.countMatches ?? []).find((c) => c.field === f.key);\n const linkers = own.filter((c) => c.fields.some((cf) => isRelation(cf) && cf.relationTarget === t.token)).map((c) => c.labelPlural.toLowerCase());\n if (linked && !declared) say(`${at}.fields (${f.key})`, `\"${f.label}\" stores a number the linked records already hold (${linkers.join(\", \")}); make it a rollup counting through the relation, so it can never disagree.`);\n if (declared) {\n const child = byToken.get(declared.childTable);\n for (const r of t.rows) {\n const n = (child?.rows ?? []).filter((c) => {\n const v = c.values?.[declared.childRelation];\n return Array.isArray(v) ? v.includes(r.key) : v === r.key;\n }).length;\n const stored = Number(storeText(r.values?.[f.key]) ?? NaN);\n if (!Number.isNaN(stored) && stored !== n) say(`${at}.rows (${r.key})`, `\"${titleOf(t, r)}\" says ${f.label.toLowerCase()} ${stored}, but ${n} ${child?.labelPlural.toLowerCase() ?? \"rows\"} link to it.`);\n }\n }\n }\n }\n const declaresRealism = own.some((t) => (t.childDates ?? []).length + (t.withinParent ?? []).length + (t.statusAgrees ?? []).length + (t.countMatches ?? []).length + (t.datePairs ?? []).length > 0);\n if ((spec.job === \"billing\" || spec.job === \"crm_pipeline\") && own.some((t) => t.fields.some((f) => isRelation(f) && own.some((p) => p.token === f.relationTarget))) && !declaresRealism) {\n say(\"tables\", `A ${spec.job === \"billing\" ? \"billing\" : \"pipeline\"} template states how its linked records agree (childDates, withinParent, statusAgrees or countMatches); this one states none.`);\n }\n\n // ── foreign text (cross-file) ──\n if (options.library) problems.push(...foreignTextProblems(raw, options.library));\n\n // ── Q2: capability present, declared exactly ────────────────────────────────\n const requires = spec.requires ?? [];\n const used = capabilitiesUsed(spec);\n for (const word of requires) {\n if (!(CAPABILITY_WORDS as readonly string[]).includes(word)) say(\"requires\", `\"${word}\" is not a capability word.`);\n else if (!used.has(word)) say(\"requires\", `It requires \"${word}\" but uses nothing that needs it.`);\n }\n for (const word of used) if (!requires.includes(word)) say(\"requires\", `The template uses \"${word}\" but does not declare it in requires.`);\n const waiting = [...new Set(requires)].map(capabilityStatus).filter((c) => !c.provided);\n\n if (options.profile === \"describe\") {\n const describeOwes = (p: UseCaseProblem) => {\n const root = p.at.split(/[.\\s[(]/)[0]!;\n if (GALLERY_ONLY_ROOTS.includes(root)) return false;\n if (seedLooks.has(p) || galleryBar.has(p)) return false;\n // Seed rows are a gallery card's; a describe spec may carry none.\n if (/^tables\\[\\d+\\] \\([^)]*\\)\\.rows$/.test(p.at)) return false;\n return true;\n };\n const kept = problems.filter(describeOwes);\n const waitingNow = [...used].map(capabilityStatus).filter((c) => !c.provided);\n return {\n ok: kept.length === 0,\n status: kept.length ? \"fail\" : waitingNow.length ? `waiting on ${[...new Set(waitingNow.map((w) => w.by))].sort().join(\", \")}` : \"pass\",\n problems: kept,\n waiting: waitingNow,\n };\n }\n const status: TemplateStatus = problems.length ? \"fail\" : waiting.length ? `waiting on ${[...new Set(waiting.map((w) => w.by))].sort().join(\", \")}` : \"pass\";\n return { ok: problems.length === 0, status, problems, waiting };\n}\n\n/** Validate and throw with every problem. A waiting template does not throw — it is held, not broken. */\nexport function assertTemplate(spec: TemplateSpec, options: ValidateOptions = {}): TemplateVerdict {\n const verdict = validateTemplate(spec, options);\n if (verdict.ok) return verdict;\n throw new Error(`The template \"${spec.id}\" is not ready — ${verdict.problems.length} problem(s):\\n${verdict.problems.map((p) => ` · ${p.at}: ${p.says}`).join(\"\\n\")}`);\n}\n\nconst RESTRICTED_KEY =\n /(^|_)(member_id|ssn|social_security|dob|date_of_birth|birth_date|allerg(y|ies)|diagnos(is|es)|medical_conditions?|conditions|medications?|current_medications|gate_code|access_code|door_code|alarm_code|password|passcode|pin|clinical_notes?|visit_notes?|progress_notes?|soap_notes?|case_notes?|legal_notes?|privileged_notes?|bank(_\\w+)?|routing(_number)?|account_number|iban|swift(_code)?|card(_number|_on_file)?|credit_card|cvv|cvc)($|_)/;\nconst RESTRICTED_LABEL = /\\b(bank|routing number|iban|card on file|credit card|card number|cvv|medical conditions?|medications?|diagnos[ie]s|case notes|legal notes|privileged)\\b/;\n// Personal health and identity floors bind PEOPLE tables only: a dog's date of birth is not\n// personal data. A table says what it holds (`subject`); undeclared, it holds people when it\n// has a name and a phone or email.\nconst PERSONAL_ONLY = /(^|_)(dob|date_of_birth|birth_date|allerg(y|ies)|diagnos(is|es)|medical_conditions?|conditions|medications?|current_medications|clinical_notes?|visit_notes?|progress_notes?|soap_notes?|member_id|ssn|social_security)($|_)/;\nconst holdsPeople = (t: Pick<TemplateTable, \"subject\" | \"fields\">) =>\n t.subject ? t.subject === \"person\" : t.fields.some((f) => /name/.test(f.key)) && t.fields.some((f) => f.parityType === \"phone\" || f.parityType === \"email\");\n\n/**\n * The lowest sensitivity the store accepts for a field, by what it holds: \"restricted\" (kept from the AI:\n * an identity or health fact about a person, a code, a card or bank number, privileged notes),\n * \"confidential\" (it reaches a person or a home: a phone, an email, an address), or null (no floor).\n * The template check refuses anything below it; the describe box fills an omitted sensitivity up to it.\n */\nexport function sensitivityFloorOf(\n table: Pick<TemplateTable, \"token\" | \"labelSingular\" | \"subject\" | \"fields\">,\n f: Pick<TemplateField, \"key\" | \"label\" | \"parityType\">,\n): \"restricted\" | \"confidential\" | null {\n const text = `${f.key} ${norm(f.label)}`;\n // \"Charges\" on a case or a person is a criminal record; on a bill, invoice or charge table it is money owed.\n const billingTable = /(invoice|bill|statement|receipt|payment|charge|fee|order|account)/i.test(`${table.token} ${table.labelSingular ?? \"\"}`);\n const criminalCharges = /(^|_)charges?($|_)/.test(f.key) && behaviorOf(f) === \"text\" && !billingTable;\n const phoneLike = behaviorOf(f) === \"text\" && /\\b(cell|mobile|phone)\\b/.test(norm(f.label));\n const personal = PERSONAL_ONLY.test(f.key) || /\\b(medical conditions?|medications?|diagnos[ie]s)\\b/.test(norm(f.label));\n const floored = (RESTRICTED_KEY.test(f.key) || RESTRICTED_LABEL.test(norm(f.label)) || criminalCharges) && (!personal || holdsPeople(table));\n if (floored) return \"restricted\";\n if (f.parityType === \"phone\" || phoneLike || f.parityType === \"email\" || /address|street/.test(text)) return \"confidential\";\n return null;\n}\n","// src/templates/plan.ts — @ai-matrx/records (templates)\n//\n// THE INSTALL PLAN: a TemplateSpec compiled into the ordered store-door calls that\n// `custom.template_install` runs AS THE PERSON, and the declaration `custom.template_declare`\n// takes. Chair (Unified Data System v6): one custom.template family, one install door.\n//\n// The plan compiles the same payloads (./payloads.ts) the retired browser installer walked — the same\n// translators (tableShellPayload, relationFieldSpec, rowsFor, derivedFieldSpec, viewSpec, formArgs,\n// bookingArgs, dashboardBlocks, stageRulesSpec, documentBody, rowActionList, notificationParts,\n// portalArgs), in the same order — with every id the store will mint written as a TOKEN the door\n// resolves at install time:\n//\n// ${org} the organization being installed into\n// ${ref:NAME} an id an earlier step saved as NAME (\"tables.patient\", \"fields.patient.dob\")\n// ${new:NAME} an id minted once per install (\"row.patient.rosa\")\n// ${date:TOKEN} an install-relative seed date (\"@today+1d 09:30\"), resolved in the business's\n// time zone on install day — so a calendar installed in March shows this week\n//\n// Each step may `save` ids out of its answer, `saveEach` a list of them, and say what it `made`\n// (kind + ref), which is the footprint uninstall archives. The door list is CLOSED on the server\n// (custom._template_doors); a step naming any other function is refused at declare time.\n//\n// seed.attachments: a template may carry `attachments` — files already in the file store (a\n// platform asset's `file_id`, name, mime, bytes). Each becomes a File record (custom.record_write\n// into the File kernel, the same door a file cell's attach uses) BEFORE the rows, and a row value\n// \"@file:<key>\" points at it.\n\nimport type { RecordsDataSource } from \"../ports\";\nimport {\n automationHeld,\n bookingArgs,\n bookingColumnsProblem,\n checklistSpec,\n dashboardBlocks,\n deferredRelations,\n derivedFieldSpec,\n formulaFieldSpec,\n formulaOrder,\n digestSpec,\n documentBody,\n drillDownDashboard,\n formArgs,\n isSelfDeclaredField,\n notificationParts,\n portalArgs,\n relationFieldSpec,\n relationPatches,\n rowActionList,\n rowLevels,\n rowsFor,\n selfDeclaredFieldSpec,\n stageFieldOf,\n stageRulesSpec,\n tableShellPayload,\n viewSpec,\n} from \"./payloads\";\nimport { RELATIVE_DATE, footprintOf, type TemplateBooking, type TemplateFootprint, type TemplateRowAction, type TemplateSpec } from \"./types\";\nimport { allTables } from \"./validate\";\nimport { membersAddRowsSteps } from \"./confidential\";\nimport { compileHostExtras, type TemplateHostExtras, type TemplatePlanBinding, type TemplatePlanExtraAgent } from \"./extras\";\nimport type { TemplateWorkflow as TemplateWorkflowSpec } from \"./types\";\n\nexport const INSTALL_PLAN_VERSION = 1 as const;\n\n/**\n * The seed-date grammar the server's `${date:…}` resolver (custom._template_date) must speak: the\n * whole client grammar (RELATIVE_DATE — business days `b`, the `~b` weekend snap, weekday anchors\n * `@mon` / `@next-tue`). Business days and anchors depend on the install day's weekday, so they\n * cannot be compiled away here; the server resolves them. The plan test holds every committed\n * template's tokens to this, and this to RELATIVE_DATE, so the two can never drift apart.\n */\nexport const SERVER_DATE_GRAMMAR: RegExp = RELATIVE_DATE;\n\n/** The store doors a plan may call — the server's custom._template_doors(), mirrored. */\nexport const TEMPLATE_PLAN_DOORS = [\n \"person_kernel_id\",\n \"file_kernel_id\",\n \"record_write\",\n \"record_write_many\",\n \"record_change_many\",\n \"table_from_example\",\n \"table_declare\",\n \"field_declare\",\n \"applicable_fields\",\n \"table_dimensions_set\",\n \"view_declare\",\n \"form_declare\",\n \"booking_declare\",\n \"dashboard_declare\",\n \"pipeline_declare\",\n \"doc_template_save\",\n \"action_declare\",\n \"subscription_declare\",\n \"rule_declare\",\n \"checklist_declare\",\n \"portal_declare\",\n \"query_table_homes\",\n] as const;\nexport type TemplatePlanDoor = (typeof TEMPLATE_PLAN_DOORS)[number];\n\n/** What uninstall archives for a step, by kind (custom.template_uninstall). */\nexport type TemplateMadeKind = \"table\" | \"field\" | \"view\" | \"form\" | \"dashboard\" | \"document\" | \"portal\" | \"record\" | \"rule\";\n\nexport interface TemplatePlanStep {\n /** Where in the walk this is, for a refusal a person can read (\"tables.patient\"). */\n label: string;\n door: TemplatePlanDoor;\n args: Record<string, unknown>;\n /** NAME → a path into the door's JSON answer ([] = the whole answer). */\n save?: Record<string, string[]>;\n /** Every element of the array at `array` saves `prefix + element[key]` = element[value]. */\n saveEach?: { array: string[]; key: string[]; value: string[]; prefix: string };\n made?: Array<{ kind: TemplateMadeKind; ref: string; title?: string; table?: string }>;\n}\n\nexport interface TemplatePlanAgent {\n platformAgent: { id: string; name: string };\n name: string;\n /**\n * Each variable bound to an installed table; the door answers each with its `table_id`.\n * `binding` (optional, Kits → Template merge): the full merge-field binding (./extras).\n */\n bindings: Array<{ variable: string; tableToken: string; describes: string; binding?: TemplatePlanBinding }>;\n}\n\nexport interface TemplateInstallPlan {\n planVersion: typeof INSTALL_PLAN_VERSION;\n /** The business's IANA zone: install-relative dates resolve in it. */\n timezone: string;\n steps: TemplatePlanStep[];\n /**\n * The host's step (the kit path's agent copy), answered by custom.template_install once installed.\n * Absent for a spec with no agent (a describe one-off): the door answers no agent step.\n */\n agent?: TemplatePlanAgent;\n /**\n * Ids known before the first step (`ref:tables.<token>` → an existing table's id, for each table that\n * `bindsTo` one): custom.template_install starts its id map with these, so every later step and every\n * `made` entry resolves the bound table exactly as if the install had made it.\n */\n ids?: Record<string, string>;\n /** Kits → Template merge (optional): more agent copies, then workflows — host steps too (./extras). */\n extraAgents?: TemplateHostExtras[\"extraAgents\"];\n workflows?: TemplateHostExtras[\"workflows\"];\n}\n\n/** The gallery card (lane 2 / lane 8): what custom.templates returns, and nothing else. */\nexport interface TemplateCard {\n name: string;\n persona: string;\n business: string;\n vertical: string;\n industry: string;\n job: string;\n audience: string;\n teaches: string;\n strengths: string[];\n requires: string[];\n footprint: TemplateFootprint;\n previewImage: string | null;\n}\n\n/** A file already in the file store, seeded as a File record at install (seed.attachments). */\nexport interface TemplateAttachment {\n key: string;\n fileId: string;\n name: string;\n mime: string;\n bytes: number;\n}\n\nexport type TemplateSpecWithAttachments = TemplateSpec & { attachments?: TemplateAttachment[] };\n\n/** `custom.template_declare`'s p_spec: the spec, its card and its compiled plan. */\nexport type TemplateDeclaration = TemplateSpecWithAttachments & {\n card: TemplateCard;\n installPlan: TemplateInstallPlan;\n organizationId?: string;\n};\n\nconst ROW_BATCH = 10;\nconst DERIVED = new Set([\"lookup\", \"rollup\"]);\nconst FILE_VALUE = /^@file:([A-Za-z0-9_.-]+)$/;\nconst TOKEN_NAME = /^[A-Za-z0-9_.:-]+$/;\n\nconst ref = (name: string): string => {\n if (!TOKEN_NAME.test(name)) throw new Error(`\"${name}\" cannot be an id name in an install plan (letters, digits, _ . : - only).`);\n return `\\${ref:${name}}`;\n};\nconst minted = (name: string): string => {\n if (!TOKEN_NAME.test(name)) throw new Error(`\"${name}\" cannot be an id name in an install plan (letters, digits, _ . : - only).`);\n return `\\${new:${name}}`;\n};\n\n/**\n * Every relative seed date becomes a `${date:…}` token (resolved by the door on install day), and\n * every \"@file:<key>\" a reference to the File record the attachments step made.\n */\nfunction tokenizeValues<T>(value: T, attachments: Set<string>): T {\n const walk = (v: unknown): unknown => {\n if (typeof v === \"string\") {\n if (RELATIVE_DATE.test(v)) return `\\${date:${v}}`;\n const f = FILE_VALUE.exec(v);\n if (f) {\n if (!attachments.has(f[1]!)) throw new Error(`A row points at the file \"${f[1]}\", which the template's attachments do not list.`);\n return ref(`files.${f[1]}`);\n }\n return v;\n }\n if (Array.isArray(v)) return v.map(walk);\n if (v && typeof v === \"object\") return Object.fromEntries(Object.entries(v).map(([k, x]) => [k, walk(x)]));\n return v;\n };\n return walk(value) as T;\n}\n\nexport function templateCard(spec: TemplateSpec): TemplateCard {\n return {\n name: spec.vertical,\n persona: spec.useCase,\n business: spec.business.name,\n vertical: spec.vertical,\n industry: spec.industry,\n job: spec.job,\n audience: spec.audience,\n teaches: spec.teaches,\n strengths: [...spec.strengths],\n requires: [...spec.requires],\n footprint: footprintOf(spec),\n previewImage: spec.previewImage ?? null,\n };\n}\n\n/** Compile `spec` into the plan custom.template_install runs. Throws, by name, on a spec it cannot install. */\nexport function compileInstallPlan(written: TemplateSpecWithAttachments): TemplateInstallPlan {\n const attachments = written.attachments ?? [];\n const attachmentKeys = new Set(attachments.map((a) => a.key));\n const spec = tokenizeValues({ ...written, attachments: undefined }, attachmentKeys) as TemplateSpec;\n // A table that binds to an existing one seeds none of its rows; a new table's row value that points\n // at one of those rows is dropped (the person's real rows are hers, not the template's sample).\n const bound = new Map(allTables(spec).filter((t) => t.bindsTo?.tableId).map((t) => [t.token, t.bindsTo!]));\n const has = (token: string, key: string) => bound.get(token)?.fields.includes(key) ?? false;\n const tables = allTables(spec).map((t) => {\n if (bound.has(t.token)) return { ...t, rows: [] };\n const toBound = t.fields.filter((f) => f.parityType === \"relation\" && f.relationTarget && bound.has(f.relationTarget)).map((f) => f.key);\n if (!toBound.length) return t;\n return { ...t, rows: t.rows.map((r) => ({ ...r, values: Object.fromEntries(Object.entries(r.values ?? {}).filter(([k]) => !toBound.includes(k))) })) };\n });\n const steps: TemplatePlanStep[] = [];\n const tableRef = (token: string): string => {\n if (!tables.some((t) => t.token === token)) throw new Error(`The template names a table \"${token}\" it does not have.`);\n return ref(`tables.${token}`);\n };\n const tableTokens: Record<string, string> = Object.fromEntries(tables.map((t) => [t.token, ref(`tables.${t.token}`)]));\n // A booking page writes its own `slot` (required) and booked/cancelled `status`; a template that\n // does not declare and seed them is refused here, before any step is planned (install.ts preflight).\n const bookingProblem = spec.extras\n .filter((e): e is TemplateBooking => e.kind === \"booking\")\n .map((b) => bookingColumnsProblem(tables, b))\n .find((p) => p);\n if (bookingProblem) throw new Error(bookingProblem);\n\n // 1 — the Home (a Person-kernel record, the same path records-ui's ExampleTables takes).\n steps.push({ label: \"home.kernel\", door: \"person_kernel_id\", args: {}, save: { \"kernel.person\": [] } });\n steps.push({\n label: \"home\",\n door: \"record_write\",\n args: { p_organization_id: \"${org}\", p_table_id: ref(\"kernel.person\"), p_data: { name: `${spec.business.name} Home` } },\n save: { home: [] },\n made: [{ kind: \"record\", ref: \"home\", title: `${spec.business.name} Home` }],\n });\n\n // 1a — seed.attachments: each file becomes a File record before any row points at it.\n if (attachments.length) {\n steps.push({ label: \"files.kernel\", door: \"file_kernel_id\", args: {}, save: { \"kernel.file\": [] } });\n for (const a of attachments) {\n steps.push({\n label: `files.${a.key}`,\n door: \"record_write\",\n args: { p_organization_id: \"${org}\", p_table_id: ref(\"kernel.file\"), p_data: { file_id: a.fileId, name: a.name, mime: a.mime, bytes: a.bytes } },\n save: { [`files.${a.key}`]: [] },\n made: [{ kind: \"record\", ref: `files.${a.key}`, title: a.name }],\n });\n }\n }\n\n // 1b — the tables, one per call (each changes the organization's shape). A bound table is not made:\n // only the plain columns it lacks are declared on it (relations and the rest follow below, as for any table).\n for (const t of tables) {\n if (bound.has(t.token)) {\n for (const f of t.fields.filter((x) => !DERIVED.has(x.parityType) && x.parityType !== \"formula\" && x.parityType !== \"relation\" && !isSelfDeclaredField(x) && !has(t.token, x.key))) {\n steps.push({\n label: `bound.${t.token}.${f.key}`,\n door: \"field_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(t.token), p_spec: selfDeclaredFieldSpec(f) },\n save: { [`fields.${t.token}.${f.key}`]: [] },\n made: [{ kind: \"field\", ref: `fields.${t.token}.${f.key}`, table: `tables.${t.token}` }],\n });\n }\n continue;\n }\n steps.push({\n label: `tables.${t.token}`,\n door: \"table_from_example\",\n args: { p_organization_id: \"${org}\", p_home_id: ref(\"home\"), p_example: tableShellPayload(spec, t) },\n saveEach: { array: [\"tables\"], key: [\"token\"], value: [\"table_id\"], prefix: \"tables.\" },\n made: [{ kind: \"table\", ref: `tables.${t.token}`, title: t.name }],\n });\n }\n\n // 1b' — lane 12 P7: tables whose members add their own rows (members_add_rows on the Table document,\n // custom.record_change_many on the Table kernel, as the person who just made them).\n steps.push(...membersAddRowsSteps(spec, tableRef));\n\n // 1c — the relation columns.\n for (const t of tables) {\n for (const f of t.fields.filter((x) => x.parityType === \"relation\" && x.relationTarget && !has(t.token, x.key))) {\n steps.push({\n label: `relations.${t.token}.${f.key}`,\n door: \"field_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(t.token), p_spec: relationFieldSpec(f, tableRef(f.relationTarget!)) },\n save: { [`fields.${t.token}.${f.key}`]: [] },\n made: [{ kind: \"field\", ref: `fields.${t.token}.${f.key}`, table: `tables.${t.token}` }],\n });\n }\n }\n\n // 1c' — the columns table_from_example cannot make as declared (a date AND a time; a column\n // with a default), before any row needs them.\n for (const t of tables) {\n for (const f of t.fields.filter((x) => isSelfDeclaredField(x) && !has(t.token, x.key))) {\n steps.push({\n label: `self_declared.${t.token}.${f.key}`,\n door: \"field_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(t.token), p_spec: selfDeclaredFieldSpec(f) },\n save: { [`fields.${t.token}.${f.key}`]: [] },\n made: [{ kind: \"field\", ref: `fields.${t.token}.${f.key}`, table: `tables.${t.token}` }],\n });\n }\n }\n\n // 1d — the rows, a table only after the tables it points at, ids minted per install. Links that\n // cannot travel with their row (a circle, a link to its own table) are set once every row exists.\n const rowIds = new Map<string, string>();\n for (const t of tables) for (const r of t.rows) rowIds.set(`${t.token}.${r.key}`, minted(`row.${t.token}.${r.key}`));\n const deferred = deferredRelations(tables);\n for (const level of rowLevels(tables)) {\n for (const t of level) {\n const { rows, ids } = rowsFor(t, rowIds, deferred.get(t.token));\n for (let i = 0; i < rows.length; i += ROW_BATCH) {\n steps.push({\n label: `rows.${t.token}.${i / ROW_BATCH + 1}`,\n door: \"record_write_many\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(t.token), p_rows: rows.slice(i, i + ROW_BATCH), p_ids: ids.slice(i, i + ROW_BATCH) },\n });\n }\n }\n }\n\n for (const t of tables) {\n const changes = relationPatches(t, rowIds, deferred.get(t.token));\n for (let i = 0; i < changes.length; i += ROW_BATCH) {\n steps.push({\n label: `links.${t.token}.${i / ROW_BATCH + 1}`,\n door: \"record_change_many\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(t.token), p_changes: changes.slice(i, i + ROW_BATCH) },\n });\n }\n }\n\n // 2 — lookups and rollups.\n for (const t of tables) {\n for (const f of t.fields.filter((x) => DERIVED.has(x.parityType) && !has(t.token, x.key))) {\n steps.push({\n label: `derived.${t.token}.${f.key}`,\n door: \"field_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(t.token), p_spec: derivedFieldSpec(f) },\n save: { [`fields.${t.token}.${f.key}`]: [] },\n made: [{ kind: \"field\", ref: `fields.${t.token}.${f.key}`, table: `tables.${t.token}` }],\n });\n }\n }\n\n // 2b — formulas, after every column they read; never seeded (install.ts formula_fields).\n for (const t of tables) {\n for (const f of formulaOrder(t).filter((x) => !has(t.token, x.key))) {\n steps.push({\n label: `formula.${t.token}.${f.key}`,\n door: \"field_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(t.token), p_spec: formulaFieldSpec(f) },\n save: { [`fields.${t.token}.${f.key}`]: [] },\n made: [{ kind: \"field\", ref: `fields.${t.token}.${f.key}`, table: `tables.${t.token}` }],\n });\n }\n }\n\n // 3 — field ids for the parts that name a Field by id (documents, row actions, any-of views).\n const needIds = new Set<string>([\n ...spec.extras.filter((e) => e.kind === \"document\" || e.kind === \"row_action\").map((e) => (e as { table: string }).table),\n ...spec.views.filter((v) => v.anyOf && Object.keys(v.anyOf).length).map((v) => v.table),\n ]);\n const fieldRefs = (token: string): Record<string, string> => {\n const t = tables.find((x) => x.token === token);\n return Object.fromEntries((t?.fields ?? []).map((f) => [f.key, ref(`fields.${token}.${f.key}`)]));\n };\n for (const token of needIds) {\n steps.push({\n label: `field_ids.${token}`,\n door: \"applicable_fields\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(token), p_record_type: null },\n saveEach: { array: [], key: [\"data\", \"key\"], value: [\"id\"], prefix: `fields.${token}.` },\n });\n }\n\n // 4 — Dimensions.\n // A bound table keeps the Dimensions its organization already set.\n for (const d of spec.dimensions.filter((x) => !bound.has(x.table))) {\n const overrides: Record<string, unknown> = {};\n if (d.dimensions) overrides[\"dimensions\"] = d.dimensions;\n if (d.measures) overrides[\"measures\"] = d.measures;\n if (d.paths) overrides[\"paths\"] = d.paths;\n if (d.default) overrides[\"default\"] = d.default;\n steps.push({\n label: `dimensions.${d.table}`,\n door: \"table_dimensions_set\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(d.table), p_overrides: overrides },\n });\n }\n\n // 5 — views.\n for (const v of spec.views) {\n steps.push({\n label: `views.${v.token}`,\n door: \"view_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(v.table), p_spec: viewSpec(v, fieldRefs(v.table)) },\n save: { [`views.${v.token}`]: [] },\n made: [{ kind: \"view\", ref: `views.${v.token}`, title: v.name, table: `tables.${v.table}` }],\n });\n }\n\n // 6 — forms.\n for (const f of spec.forms) {\n steps.push({\n label: `forms.${f.token}`,\n door: \"form_declare\",\n args: formArgs(\"${org}\", tableRef(f.table), f),\n save: { [`forms.${f.token}`]: [] },\n made: [{ kind: \"form\", ref: `forms.${f.token}`, title: f.name, table: `tables.${f.table}` }],\n });\n }\n\n // 7 — extras, in the order the spec lists them, except that documents come first: a checklist step may hand\n // over a document, so the document must exist before the checklist that names it, wherever the writer listed\n // it (T0554 listed its renewal letter after its renewal checklist). A table's row actions are one list, last.\n const actionsByTable = new Map<string, TemplateRowAction[]>();\n const formRefs = Object.fromEntries(spec.forms.map((f) => [f.token, ref(`forms.${f.token}`)]));\n const documentRefs = Object.fromEntries(\n spec.extras.filter((e) => e.kind === \"document\").map((e) => [(e as { token: string }).token, ref(`documents.${(e as { token: string }).token}`)]),\n );\n const extrasInOrder = [...spec.extras.filter((e) => e.kind === \"document\"), ...spec.extras.filter((e) => e.kind !== \"document\")];\n for (const e of extrasInOrder) {\n switch (e.kind) {\n case \"booking\":\n steps.push({\n label: `bookings.${e.token}`,\n door: \"booking_declare\",\n args: bookingArgs(\"${org}\", tableRef(e.table), e),\n save: { [`bookings.${e.token}.form`]: [\"form_id\"], [`bookings.${e.token}.slots`]: [\"slot_table_id\"] },\n made: [\n { kind: \"form\", ref: `bookings.${e.token}.form`, title: e.title, table: `tables.${e.table}` },\n { kind: \"table\", ref: `bookings.${e.token}.slots`, title: `${e.title} slots` },\n ],\n });\n break;\n case \"dashboard\":\n steps.push({\n label: `dashboards.${e.token}`,\n door: \"dashboard_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(e.table), p_name: e.name, p_blocks: dashboardBlocks(e, tableTokens), p_presentation: {}, p_dashboard_id: null },\n save: { [`dashboards.${e.token}`]: [] },\n made: [{ kind: \"dashboard\", ref: `dashboards.${e.token}`, title: e.name, table: `tables.${e.table}` }],\n });\n break;\n case \"drill_down\": {\n // The drill path is the table's own Dimensions (step 4); its entry point is a dashboard.\n const d = drillDownDashboard(e, spec.dimensions);\n steps.push({\n label: `dashboards.${e.token}`,\n door: \"dashboard_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(e.table), p_name: d.name, p_blocks: d.blocks, p_presentation: {}, p_dashboard_id: null },\n save: { [`dashboards.${e.token}`]: [] },\n made: [{ kind: \"dashboard\", ref: `dashboards.${e.token}`, title: e.name, table: `tables.${e.table}` }],\n });\n break;\n }\n case \"digest\": {\n const view = spec.views.find((v) => v.token === e.view);\n if (!view) throw new Error(`The digest \"${e.name}\" sends the view \"${e.view}\", which this template does not declare.`);\n steps.push({\n label: `digests.${e.token}`,\n door: \"subscription_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(view.table), p_spec: digestSpec(e, ref(`views.${e.view}`)) },\n save: { [`digests.${e.token}`]: [] },\n made: [{ kind: \"rule\", ref: `digests.${e.token}`, title: e.name, table: `tables.${view.table}` }],\n });\n break;\n }\n case \"stage_rules\":\n steps.push({\n label: `stage_rules.${e.token}`,\n door: \"pipeline_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(e.table), p_spec: stageRulesSpec(e) },\n });\n break;\n case \"document\":\n steps.push({\n label: `documents.${e.token}`,\n door: \"doc_template_save\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(e.table), p_name: e.name, p_body: documentBody(e, fieldRefs(e.table), spec.business.name), p_template_id: null },\n save: { [`documents.${e.token}`]: [] },\n made: [{ kind: \"document\", ref: `documents.${e.token}`, title: e.name, table: `tables.${e.table}` }],\n });\n break;\n case \"row_action\":\n actionsByTable.set(e.table, [...(actionsByTable.get(e.table) ?? []), e]);\n break;\n case \"notification\": {\n const n = notificationParts(e, stageFieldOf(tables, e.when.table, e.when.stage));\n steps.push({\n label: `notifications.${e.token}.view`,\n door: \"view_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(e.when.table), p_spec: n.view },\n save: { [`notifications.${e.token}.view`]: [] },\n made: [{ kind: \"view\", ref: `notifications.${e.token}.view`, title: e.name, table: `tables.${e.when.table}` }],\n });\n steps.push({\n label: `notifications.${e.token}`,\n door: \"subscription_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(e.when.table), p_spec: { ...n.subscription, saved_view_id: ref(`notifications.${e.token}.view`) } },\n save: { [`notifications.${e.token}`]: [] },\n made: [{ kind: \"rule\", ref: `notifications.${e.token}`, title: e.name, table: `tables.${e.when.table}` }],\n });\n break;\n }\n case \"portal\":\n steps.push({\n label: `portals.${e.token}`,\n door: \"portal_declare\",\n args: portalArgs(\"${org}\", e, tableTokens),\n save: { [`portals.${e.token}`]: [] },\n made: [{ kind: \"portal\", ref: `portals.${e.token}`, title: e.title, table: `tables.${e.clientTable}` }],\n });\n break;\n case \"checklist\":\n // A checklist template is a record: uninstall archives it like one.\n for (const t of [e.aboutTable, ...(e.trigger && e.trigger.kind !== \"manual\" ? [e.trigger.table] : [])]) tableRef(t);\n for (const st of e.steps) {\n const r = st.requires;\n if (r?.kind === \"form\" && !formRefs[r.form]) throw new Error(`The checklist \"${e.name}\" asks for the form \"${r.form}\", which this template does not declare.`);\n if (r?.kind === \"document\" && !documentRefs[r.document]) throw new Error(`The checklist \"${e.name}\" asks for the document \"${r.document}\", which this template does not declare.`);\n }\n steps.push({\n label: `checklists.${e.token}`,\n door: \"checklist_declare\",\n args: { p_organization_id: \"${org}\", p_spec: checklistSpec(e, tableTokens, formRefs, documentRefs), p_template_id: null },\n save: { [`checklists.${e.token}`]: [\"template_id\"] },\n made: [{ kind: \"record\", ref: `checklists.${e.token}`, title: e.name }],\n });\n break;\n case \"automation\":\n throw new Error(automationHeld(e));\n default:\n throw new Error(`The install plan has no door for a ${(e as { kind: string }).kind} yet (\"${(e as { token?: string }).token ?? \"?\"}\"), so this template cannot be declared until it does.`);\n }\n }\n for (const [token, actions] of actionsByTable) {\n steps.push({\n label: `row_actions.${token}`,\n door: \"action_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(token), p_actions: rowActionList(actions, fieldRefs(token)) },\n });\n }\n\n const host = compileHostExtras(spec);\n const agent = spec.agent as TemplateSpec[\"agent\"] | undefined;\n return {\n planVersion: INSTALL_PLAN_VERSION,\n timezone: spec.business.timezone || \"UTC\",\n steps,\n ...(agent?.platformAgent\n ? {\n agent: {\n platformAgent: agent.platformAgent,\n name: agent.name,\n bindings: (agent.variables ?? []).map((v) => {\n const binding = host.agentBindings.get(v.name);\n return { variable: v.name, tableToken: v.table, describes: v.describes, ...(binding ? { binding } : {}) };\n }),\n },\n }\n : {}),\n ...(bound.size ? { ids: Object.fromEntries([...bound].map(([token, b]) => [`ref:tables.${token}`, b.tableId])) } : {}),\n ...host.extras,\n };\n}\n\n/** `custom.template_declare`'s p_spec for one template: the spec, its card and its plan. */\nexport function templateDeclaration(spec: TemplateSpecWithAttachments, organizationId?: string): TemplateDeclaration {\n return {\n ...spec,\n card: templateCard(spec),\n installPlan: compileInstallPlan(spec),\n ...(organizationId ? { organizationId } : {}),\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The client loop every host calls (lane 2's gallery, lane 8's publisher, lane 9's scopes)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** The family's budgeted doors: each call does what fits in its budget and says `done`. */\nexport type TemplateFamilyDoor = \"template_install\" | \"template_uninstall\" | \"template_restore\";\n\n/** What the three doors answer (custom._template_answer). */\nexport interface TemplateDoorAnswer {\n install_id?: string;\n state?: \"installing\" | \"installed\" | \"refused\" | \"uninstalling\" | \"uninstalled\";\n ok?: boolean;\n done?: boolean;\n already?: boolean;\n next_step?: number;\n steps?: number;\n made?: Array<{ kind: string; id: string | null; ref: string; title: string | null; table_id: string | null }>;\n archived?: unknown[];\n left?: unknown[];\n refusal?: Record<string, unknown> | null;\n agent?: { platform_agent: { id: string; name: string }; name: string; bindings: Array<Record<string, unknown>>; copied: boolean } | null;\n /**\n * Kits → Template merge (custom._template_answer, only for a template that carries them): the plan's\n * extra agents and workflows, and the ids the host resolves them with — `tables.<token>` → table\n * id, `row.<token>.<rowKey>` → seed row id.\n */\n host?: { extra_agents?: TemplatePlanExtraAgent[] | null; workflows?: TemplateWorkflowSpec[] | null; ids?: Record<string, string> } | null;\n [key: string]: unknown;\n}\n\nexport interface TemplateDoorRun {\n ok: boolean;\n answer: TemplateDoorAnswer | null;\n /** The transport's own error (the 8 s ceiling, a lock wait), after the retries ran out. */\n error?: { code: string | null; message: string; hint: string | null };\n calls: number;\n}\n\nconst TRANSIENT = new Set([\"57014\", \"55P03\", \"40P01\", \"40001\"]);\n\n/**\n * Call one of the family's budgeted doors until it says done: install (p_template_id), uninstall\n * or restore (p_install_id). A refusal comes back verbatim (`ok: false`, answer.refusal); a lock\n * wait or a statement timeout is retried, because a call that times out changed nothing.\n */\nexport async function runTemplateDoor(\n source: RecordsDataSource,\n door: TemplateFamilyDoor,\n organizationId: string,\n id: string,\n options: { maxCalls?: number; onCall?: (answer: TemplateDoorAnswer) => void } = {},\n): Promise<TemplateDoorRun> {\n const max = options.maxCalls ?? 40;\n const key = door === \"template_install\" ? \"p_template_id\" : \"p_install_id\";\n let answer: TemplateDoorAnswer | null = null;\n let error: TemplateDoorRun[\"error\"];\n let calls = 0;\n while (calls < max) {\n calls++;\n const { data, error: e } = await source.rpc(door, { p_organization_id: organizationId, [key]: id }, { schema: \"custom\" });\n if (e) {\n error = { code: e.code ?? null, message: e.message, hint: e.hint ?? null };\n if (e.code && TRANSIENT.has(e.code)) continue;\n return { ok: false, answer, error, calls };\n }\n answer = (data ?? null) as TemplateDoorAnswer | null;\n if (answer) options.onCall?.(answer);\n if (!answer) return { ok: false, answer, calls };\n if (answer.done) return { ok: true, answer, calls };\n if (answer.state === \"refused\") {\n const code = typeof answer.refusal?.[\"code\"] === \"string\" ? (answer.refusal[\"code\"] as string) : \"\";\n if (TRANSIENT.has(code)) continue;\n return { ok: false, answer, calls };\n }\n }\n return { ok: false, answer, ...(error ? { error } : {}), calls };\n}\n\n/** Tables a plan makes (for a suite): the `tables.*` refs its steps save. */\nexport function planTables(plan: TemplateInstallPlan): string[] {\n return plan.steps.flatMap((s) => (s.made ?? []).filter((m) => m.kind === \"table\").map((m) => m.ref));\n}\n\n","// src/choice.ts — @ai-matrx/records\n//\n// WHAT A CHOICE VALUE IS, in one place, for every screen and every caller.\n//\n// A pick-list is a Table and an option is a Record of it (FLD-5 / FLD-6) — that part is\n// unchanged and is the store being right. What a CELL holds is not the option record's id: it\n// is the option's own stable key, a short word derived from its title when the option is born,\n// unique within its list and never rewritten. So renaming \"Circle\" to \"Round\" rewrites no row,\n// and nothing — no person, no agent, no import — is ever asked to know a uuid for a word the\n// product showed them.\n//\n// The read doors hand back the LABEL in the cell and name the key beside it in `_choices`:\n//\n// { \"kind\": \"Circle\",\n// \"_choices\": { \"kind\": { \"key\": \"circle\", \"label\": \"Circle\", \"id\": \"…\",\n// \"retired\": false, \"reason\": null } } }\n//\n// A multi-choice cell reads as an array of labels and its `_choices` entry is an array in the\n// same order. A RETIRED option is in there too, with `retired: true` and the reason — a value\n// whose choice was retired reads as its label and says what happened rather than vanishing.\n//\n// WRITING takes the label, the key, or (so nothing that worked yesterday breaks) the option\n// record's id. The store normalises all three to the key on the way in and refuses a word that\n// names no choice, naming the choices themselves.\n\nimport type { RecordDocument, StoredRecord } from \"./record\";\nimport { isUuidShape } from \"@ai-matrx/kit/uuid\";\n\n/** One option, as `_choices` names it and as `optionsOf` returns it. */\nexport interface ChoiceOption {\n /** The stable key the cell actually holds. */\n key: string;\n /** What a person reads. */\n label: string;\n /** The option RECORD's id, for a caller that needs the row itself. */\n id?: string;\n /** True when the option was retired: still readable, no longer pickable. */\n retired?: boolean;\n /** Why it is no longer offered, in a sentence, when it is retired. */\n reason?: string | null;\n}\n\n/**\n * The stable key of an option RECORD as `custom.field_options` returns it.\n *\n * It lives in `metadata.option_key`, not in the document: FLD-5 keeps a category to one title\n * field, and the key is the store's own bookkeeping rather than a column anybody declared.\n * The fallback is the same slug the store derives, so an option written by something that has\n * not caught up still answers.\n */\nexport function optionKey(option: StoredRecord): string {\n const stored = option.metadata?.[\"option_key\"];\n if (typeof stored === \"string\" && stored.trim() !== \"\") return stored;\n return choiceSlug(optionLabel(option));\n}\n\n/** What a person reads on an option record. */\nexport function optionLabel(option: StoredRecord): string {\n const doc = option.data as RecordDocument | undefined;\n const title = doc?.[\"title\"] ?? doc?.[\"name\"];\n if (typeof title === \"string\" && title.trim() !== \"\") return title;\n return \"Unnamed choice\";\n}\n\n/**\n * The store's own slug, mirrored so a client can predict a key without a round trip.\n * `custom.choice_slug` is the original; a title with nothing a-z0-9 in it gets a short hash of\n * itself there, and this returns the empty-ish fallback rather than guessing a hash — a caller\n * that needs the real key for such a title reads it off the option.\n */\nexport function choiceSlug(word: string): string {\n const slug = word\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 55);\n return slug === \"\" ? \"choice\" : slug;\n}\n\n/**\n * Does this stored (or typed) value name this option? The key, the label and the option's own\n * id all name the same choice, and a control has to recognise every one of them: what the read\n * door hands it is the LABEL, what the store holds is the KEY, and what a screen written before\n * this contract sends is the ID.\n */\nexport function isTheChosen(option: StoredRecord, value: unknown): boolean {\n if (typeof value !== \"string\") return false;\n const asked = value.trim().toLowerCase();\n if (asked === \"\") return false;\n return (\n asked === optionKey(option).toLowerCase() ||\n asked === optionLabel(option).toLowerCase() ||\n asked === option.id.toLowerCase()\n );\n}\n\n/** Every value of one cell, as strings, whether the Field is multi or not. */\nexport function choiceValuesOf(value: unknown): string[] {\n if (Array.isArray(value)) return value.filter((v): v is string => typeof v === \"string\");\n if (typeof value === \"string\" && value !== \"\") return [value];\n return [];\n}\n\n/**\n * What the read door said about one column's choices: the key behind the label, and whether the\n * option was retired and why. Returns an empty array when the document carries no `_choices`\n * entry for that column, which is also what a document written before this contract looks like.\n */\nexport function choicesOf(document: RecordDocument | undefined, fieldKeyOrId: string): ChoiceOption[] {\n const block = document?.[\"_choices\"];\n if (!block || typeof block !== \"object\") return [];\n const entry = (block as Record<string, unknown>)[fieldKeyOrId];\n if (!entry) return [];\n const list = Array.isArray(entry) ? entry : [entry];\n return list.filter((x): x is ChoiceOption => !!x && typeof x === \"object\" && typeof (x as ChoiceOption).key === \"string\");\n}\n\n/** True when this cell's value points at a choice that has since been retired. */\nexport function holdsARetiredChoice(document: RecordDocument | undefined, fieldKeyOrId: string): boolean {\n return choicesOf(document, fieldKeyOrId).some((c) => c.retired === true);\n}\n\n/** True when a token looks like a uuid — which a choice value is no longer allowed to be. */\nexport function looksLikeAnId(value: unknown): boolean {\n return typeof value === \"string\" && isUuidShape(value);\n}\n\n/* ═══ WORDS TYPED INTO A CHOICE CELL THAT ARE NOT A CHOICE (lane CHOICE-COLUMN-EDIT) ═══════════\n *\n * A software team's \"Account Type\" column offers Cursor · Claude · Codex, and somebody types\n * \"Gemini\". Three answers are possible and the store has a door for each: add it to the choices\n * and the cell takes it (`recordUpdateAddingChoices`), keep it as typed on a column that takes\n * other values (`config.allow_other` — an ordinary `recordUpdate`), or refuse it. Which one is\n * the Feature Knob `custom/choice_nudge` (`choiceNudge()`), and this is the ONE place that\n * reads it, so the grid, the record form and every other surface answer the same way.\n */\n\n/** The Feature Knob `custom/choice_nudge`: ask (the default), always add, or never add. */\nexport type ChoiceNudge = \"ask\" | \"always_add\" | \"never_add\";\n\nexport const CHOICE_NUDGES: readonly ChoiceNudge[] = [\"ask\", \"always_add\", \"never_add\"];\n\n/** Any answer the knob door gives, as one of the three; anything unknown is the default, `ask`. */\nexport function asChoiceNudge(value: unknown): ChoiceNudge {\n return typeof value === \"string\" && (CHOICE_NUDGES as readonly string[]).includes(value) ? (value as ChoiceNudge) : \"ask\";\n}\n\n/** What `decideTypedChoice` answers. */\nexport type TypedChoiceDecision =\n /** Nothing was typed. */\n | { decision: \"empty\" }\n /** The words name a live choice (by its words or its key, any case): write `key`. */\n | { decision: \"chosen\"; key: string; label: string }\n /** Ask the person. `keepOffered` is true only when the column takes other values. */\n | { decision: \"ask\"; words: string; keepOffered: boolean }\n /** Add the words to the choices and the cell takes them — without asking (`always_add`). */\n | { decision: \"add\"; words: string }\n /** Keep the words as typed, an \"other\" value (`never_add` on a column that takes other values). */\n | { decision: \"keep_as_typed\"; words: string }\n /** The words are not one of the choices and nothing may add them (`never_add`, closed column). */\n | { decision: \"not_a_choice\"; words: string };\n\n/** A choice as either door hands it: an option record (`fieldOptions`) or a `_choices` entry. */\nexport type ChoiceLike = StoredRecord | ChoiceOption;\n\nfunction choiceKeyAndLabel(option: ChoiceLike): { key: string; label: string; retired: boolean } {\n if (typeof (option as ChoiceOption).key === \"string\" && typeof (option as ChoiceOption).label === \"string\") {\n const o = option as ChoiceOption;\n return { key: o.key, label: o.label, retired: o.retired === true };\n }\n // `custom.field_options` answers LIVE options only, so an option record is never retired.\n const record = option as StoredRecord;\n return { key: optionKey(record), label: optionLabel(record), retired: false };\n}\n\n/**\n * THE ONE DECISION for words typed into a choice cell.\n *\n * `options` are the column's choices; a retired one is not pickable, so words naming only a\n * retired choice are treated as new (adding them brings the retired choice back, which is what\n * the store does). `nudge` absent or unknown is `ask`.\n */\nexport function decideTypedChoice(args: {\n words: string;\n options: readonly ChoiceLike[];\n allowOther: boolean;\n nudge?: ChoiceNudge | string | null | undefined;\n}): TypedChoiceDecision {\n const words = args.words.trim();\n if (words === \"\") return { decision: \"empty\" };\n const asked = words.toLowerCase();\n for (const option of args.options) {\n const { key, label, retired } = choiceKeyAndLabel(option);\n if (retired) continue;\n if (label.toLowerCase() === asked || key.toLowerCase() === asked) return { decision: \"chosen\", key, label };\n }\n const nudge = asChoiceNudge(args.nudge);\n if (nudge === \"always_add\") return { decision: \"add\", words };\n if (nudge === \"never_add\") return args.allowOther ? { decision: \"keep_as_typed\", words } : { decision: \"not_a_choice\", words };\n return { decision: \"ask\", words, keepOffered: args.allowOther };\n}\n\n/* ═══ REMOVING A CHOICE THAT RECORDS STILL HOLD (lane CHOICE-TAILS, 2026-09-27) ════════════════\n *\n * A dental front desk's \"Visit Type\" offers Cleaning · Exam · X-ray · Whitening, and the office\n * stops booking X-rays as their own visit. Removing X-ray used to leave every record that held it\n * holding a retired choice, with nobody asked. Now the column editor asks, Notion-style:\n * \"3 records use “X-ray”.\" — move them to another choice, keep the words as other values (only\n * where the column takes other values), or clear them. The answer goes in the SAME save as the\n * list (`fieldUpdateRehomingChoices`), and that save answers its own undo.\n */\n\n/** How many records hold one choice (`custom.field_choice_usage`), keyed by the option's id. */\nexport interface ChoiceUsage {\n key: string;\n words: string;\n retired: boolean;\n /** Live records the caller may see whose cell holds the choice. */\n records: number;\n}\n\n/** Where the records of a removed choice go. */\nexport type ChoiceRehome =\n | { then: \"move\"; to: string }\n | { then: \"keep\" }\n | { then: \"clear\" };\n\n/** One cell as it was before a rehoming save — what its undo writes back. */\nexport interface ChoiceCellBack {\n record_id: string;\n value: unknown;\n}\n\n/** What `fieldUpdateRehomingChoices` answers. */\nexport interface ChoicesRehomed {\n field_id: string;\n rehomed: Array<{ choice_id: string; words: string; then: ChoiceRehome[\"then\"]; to: string | null; records: number }>;\n cells_back: number;\n /** Send `{ patch: { options: undo.options }, cells_back: undo.cells_back }` to put it all back. */\n undo: { options: Array<{ id: string; words: string }>; cells_back: ChoiceCellBack[] };\n}\n\n/**\n * THE CHOICES A LIST NO LONGER NAMES THAT RECORDS STILL HOLD — the ones the editor must ask about.\n * `beforeIds` is the list as the store answered it, `afterIds` the list as the person has it now.\n */\nexport function removedChoicesInUse(\n beforeIds: readonly string[],\n afterIds: readonly string[],\n usage: Readonly<Record<string, ChoiceUsage>> | null | undefined,\n): Array<{ id: string; words: string; records: number }> {\n if (!usage) return [];\n const kept = new Set(afterIds);\n return beforeIds\n .filter((id) => !kept.has(id))\n .map((id) => ({ id, words: usage[id]?.words ?? \"\", records: usage[id]?.records ?? 0 }))\n .filter((c) => c.records > 0);\n}\n\n/** “1 record uses “X-ray”.” · “3 records use “X-ray”.” — the question's first line. */\nexport function recordsUseSentence(records: number, words: string): string {\n return `${records} ${records === 1 ? \"record uses\" : \"records use\"} “${words}”.`;\n}\n\n/** What the answer will do, said before Save: “3 records move to “Exam”.” */\nexport function rehomeSentence(records: number, words: string, rehome: ChoiceRehome, toWords?: string): string {\n const n = `${records} ${records === 1 ? \"record\" : \"records\"}`;\n if (rehome.then === \"move\") return `${n} that ${records === 1 ? \"holds\" : \"hold\"} “${words}” ${records === 1 ? \"moves\" : \"move\"} to “${toWords ?? \"another choice\"}”.`;\n if (rehome.then === \"keep\") return `${n} ${records === 1 ? \"keeps\" : \"keep\"} “${words}” as another value.`;\n return `${n} that ${records === 1 ? \"holds\" : \"hold\"} “${words}” ${records === 1 ? \"is\" : \"are\"} cleared.`;\n}\n","// src/memory/world.ts — @ai-matrx/records/memory (lane CHAIR-GALLERY-2, 2026-10-05)\n//\n// A TEMPLATE, INSTALLED INTO MEMORY. `templateWorld(spec)` walks the template's OWN install plan\n// (`compileInstallPlan` — the very steps `custom.template_install` runs) and applies each step to an\n// in-memory world instead of the store: the tables, their fields, the pick-list choices, the relations,\n// the seed rows, the views, the forms, the booking pages and the dashboards. Nothing is invented and\n// nothing is sent anywhere; the answers the memory doors (./doors.ts) give are read off this world.\n//\n// Ids are STABLE: the same template gives the same ids on the server and in the browser, so a page\n// rendered on the server and hydrated in the browser names the same records.\n\nimport { compileInstallPlan, type TemplateInstallPlan } from \"../templates/plan\";\nimport { resolveDateToken } from \"../templates/validate\";\nimport type { TemplateSpec } from \"../templates/types\";\nimport { choiceSlug } from \"../choice\";\n\ntype Json = Record<string, unknown>;\n\n/** The ids the store's kernel tables carry everywhere (custom.table_kernel_id() and its siblings). */\nexport const MEMORY_KERNEL = {\n table: \"11111111-0000-4000-8000-000000000001\",\n field: \"11111111-0000-4000-8000-000000000002\",\n person: \"11111111-0000-4000-8000-000000000005\",\n file: \"11111111-0000-4000-8000-000000000006\",\n rule: \"11111111-0000-4000-8000-000000000003\",\n} as const;\n\n/** One stable uuid-shaped id per name (FNV-1a over the name, four lanes). */\nexport function stableId(name: string): string {\n const lanes = [0x811c9dc5, 0x01000193, 0x9e3779b9, 0x85ebca6b];\n for (let i = 0; i < name.length; i += 1) {\n const c = name.charCodeAt(i);\n for (let l = 0; l < 4; l += 1) lanes[l] = Math.imul((lanes[l]! ^ c) >>> 0, 0x01000193 + l * 2) >>> 0;\n }\n const hex = lanes.map((n) => n.toString(16).padStart(8, \"0\")).join(\"\");\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-4${hex.slice(13, 16)}-${\"89ab\"[parseInt(hex[16]!, 16) % 4]}${hex.slice(17, 20)}-${hex.slice(20, 32)}`;\n}\n\nexport interface MemoryField {\n id: string;\n table_id: string;\n data: Json;\n}\nexport interface MemoryOption {\n id: string;\n key: string;\n label: string;\n color: string | null;\n}\nexport interface MemoryTable {\n id: string;\n token: string;\n /** The Table's declaration as the table kernel holds it. */\n document: Json;\n fields: MemoryField[];\n /** Field key → its choices, in order. */\n options: Map<string, MemoryOption[]>;\n /** Record id → its stored document (choice cells hold the option KEY, relations hold record ids). */\n rows: Map<string, Json>;\n /** Insertion order, which is the template's own row order. */\n order: string[];\n}\nexport interface MemoryView {\n view_id: string;\n token: string;\n table_id: string;\n name: string;\n definition: Json;\n filters: Json;\n}\nexport interface MemoryForm {\n form_id: string;\n token: string;\n table_id: string;\n title: string;\n questions: Json[];\n presentation: Json;\n booking: Json | null;\n}\nexport interface MemoryDashboard {\n dashboard_id: string;\n token: string;\n table_id: string;\n name: string;\n blocks: Json[];\n}\nexport interface MemoryWorld {\n organization_id: string;\n user_id: string;\n /** The business's IANA zone. */\n timezone: string;\n today: string;\n businessName: string;\n tables: MemoryTable[];\n tableById: Map<string, MemoryTable>;\n views: MemoryView[];\n forms: MemoryForm[];\n dashboards: MemoryDashboard[];\n /** Every record id → the table it belongs to. */\n recordTable: Map<string, MemoryTable>;\n /** Table id → the field key that is its pipeline stage. */\n stageField: Map<string, string>;\n /** Standard sources (`{ kind: \"entity\", token }`) this world answers — `withEntities`. */\n entities?: Map<string, import(\"./entity\").MemoryEntity>;\n}\n\nexport interface TemplateWorldOptions {\n /** \"YYYY-MM-DD\" the template's relative dates resolve against. Default: today (UTC). */\n today?: string;\n}\n\nconst COMPUTED = new Set([\"lookup\", \"rollup\", \"formula\"]);\n\n/**\n * A field as the store keeps it, from the template's own words (the `table_from_example` /\n * `field_declare` translation, mirrored for reading: type, format, config, display format).\n */\nfunction storedField(spec: Json, tableId: string, tableToken: string, sort: number, idOf: (n: string) => string): MemoryField {\n const key = String(spec[\"key\"]);\n const parity = String(spec[\"parityType\"] ?? spec[\"type\"] ?? \"text\");\n const base: Json = {\n key,\n label: spec[\"label\"] ?? key,\n sort,\n dated: Boolean(spec[\"dated\"]),\n multi: Boolean(spec[\"multi\"]),\n required: Boolean(spec[\"required\"]),\n rules: Array.isArray(spec[\"rules\"]) ? spec[\"rules\"] : [],\n config: {},\n source: COMPUTED.has(parity) ? \"formula\" : \"manual\",\n depends_on: [],\n sensitivity: spec[\"sensitivity\"] ?? \"internal\",\n context_policy: spec[\"contextPolicy\"] ?? spec[\"context_policy\"] ?? \"include\",\n applies_to_types: [],\n entity_definition_id: tableId,\n parity_type: parity,\n };\n const unit = spec[\"unit\"];\n if (typeof unit === \"string\" && unit) base[\"unit\"] = unit;\n const display = spec[\"displayFormat\"] ?? spec[\"display_format\"];\n if (display && typeof display === \"object\") base[\"display_format\"] = display;\n const config = base[\"config\"] as Json;\n switch (parity) {\n case \"text\":\n base[\"type\"] = \"text\";\n break;\n case \"long_text\":\n base[\"type\"] = \"text\";\n base[\"format\"] = \"long\";\n config[\"multiline\"] = true;\n break;\n case \"email\":\n case \"phone\":\n case \"url\":\n case \"signature\":\n base[\"type\"] = \"text\";\n base[\"format\"] = parity;\n break;\n case \"number\":\n case \"integer\":\n case \"decimal\":\n base[\"type\"] = \"range\";\n break;\n case \"currency\":\n base[\"type\"] = \"range\";\n base[\"format\"] = \"currency\";\n if (!base[\"unit\"]) base[\"unit\"] = \"USD\";\n break;\n case \"percent\":\n base[\"type\"] = \"range\";\n base[\"format\"] = \"percent\";\n break;\n case \"datetime\": {\n base[\"type\"] = \"range\";\n const timed = spec[\"kind\"] === \"datetime\" || spec[\"format\"] === \"datetime\";\n config[\"kind\"] = timed ? \"datetime\" : \"date\";\n if (timed) base[\"format\"] = \"datetime\";\n break;\n }\n case \"checkbox\":\n base[\"type\"] = \"boolean\";\n break;\n case \"select\":\n case \"multi_select\":\n base[\"type\"] = \"list\";\n config[\"options_table_id\"] = idOf(`options.${tableToken}.${key}`);\n if (parity === \"multi_select\") base[\"multi\"] = true;\n break;\n case \"relation\":\n base[\"type\"] = \"relation\";\n base[\"relation_target\"] = spec[\"relation_target\"] ?? (spec[\"relationTarget\"] ? idOf(`tables.${String(spec[\"relationTarget\"])}`) : null);\n if (spec[\"relation_max\"] ?? spec[\"relationMax\"]) base[\"relation_max\"] = spec[\"relation_max\"] ?? spec[\"relationMax\"];\n break;\n case \"member\":\n base[\"type\"] = \"relation\";\n base[\"relation_target\"] = MEMORY_KERNEL.person;\n break;\n case \"attachment\":\n base[\"type\"] = \"relation\";\n base[\"relation_target\"] = MEMORY_KERNEL.file;\n break;\n case \"lookup\":\n base[\"type\"] = \"formula\";\n config[\"via\"] = spec[\"via\"];\n config[\"pick\"] = spec[\"pick\"];\n break;\n case \"rollup\":\n base[\"type\"] = \"formula\";\n config[\"via\"] = spec[\"via\"];\n config[\"agg\"] = spec[\"agg\"];\n config[\"of\"] = spec[\"of\"] ?? spec[\"pick\"];\n if (spec[\"filter\"]) config[\"filter\"] = spec[\"filter\"];\n break;\n case \"formula\":\n base[\"type\"] = \"formula\";\n config[\"formula_text\"] = spec[\"formula_text\"] ?? spec[\"formula\"];\n break;\n default:\n base[\"type\"] = \"text\";\n }\n if (parity !== \"datetime\" && typeof spec[\"format\"] === \"string\" && !base[\"format\"] && parity !== \"lookup\" && parity !== \"rollup\") {\n base[\"format\"] = spec[\"format\"];\n }\n return { id: idOf(`fields.${tableToken}.${key}`), table_id: tableId, data: base };\n}\n\nconst PLACEHOLDER = /\\$\\{(org|ref:[^}]+|new:[^}]+|date:[^}]+)\\}/g;\n\n/**\n * Walk the template's install plan into memory. Pure: the same spec and day give the same world.\n */\nexport function templateWorld(spec: TemplateSpec, options: TemplateWorldOptions = {}): MemoryWorld {\n const plan: TemplateInstallPlan = compileInstallPlan(spec);\n const today = options.today ?? new Date().toISOString().slice(0, 10);\n const tz = plan.timezone || spec.business?.timezone || \"UTC\";\n const seed = `template:${(spec as { id?: string }).id ?? spec.business?.name ?? \"preview\"}`;\n const idOf = (name: string): string => {\n if (name === \"kernel.person\") return MEMORY_KERNEL.person;\n if (name === \"kernel.file\") return MEMORY_KERNEL.file;\n return plan.ids?.[`ref:${name}`] ?? stableId(`${seed}:${name}`);\n };\n const org = stableId(`${seed}:organization`);\n const resolveString = (s: string): unknown => {\n const whole = /^\\$\\{(org|ref:[^}]+|new:[^}]+|date:[^}]+)\\}$/.exec(s);\n const one = (tok: string): string => {\n if (tok === \"org\") return org;\n if (tok.startsWith(\"date:\")) return resolveDateToken(tok.slice(5), today, tz) ?? tok.slice(5);\n return idOf(tok.slice(4));\n };\n if (whole) return one(whole[1]!);\n return s.replace(PLACEHOLDER, (_m, tok: string) => one(tok));\n };\n const resolve = (v: unknown): unknown => {\n if (typeof v === \"string\") return resolveString(v);\n if (Array.isArray(v)) return v.map(resolve);\n if (v && typeof v === \"object\") return Object.fromEntries(Object.entries(v).map(([k, x]) => [k, resolve(x)]));\n return v;\n };\n\n const world: MemoryWorld = {\n organization_id: org,\n user_id: stableId(`${seed}:viewer`),\n timezone: tz,\n today,\n businessName: spec.business?.name ?? \"\",\n tables: [],\n tableById: new Map(),\n views: [],\n forms: [],\n dashboards: [],\n recordTable: new Map(),\n stageField: new Map(),\n };\n const tokenOfTable = new Map<string, string>();\n\n const addField = (table: MemoryTable, raw: Json) => {\n const key = String(raw[\"key\"]);\n const existing = table.fields.findIndex((f) => f.data[\"key\"] === key);\n const field = storedField(raw, table.id, table.token, (existing >= 0 ? existing : table.fields.length) * 10 + 10, idOf);\n if (existing >= 0) table.fields[existing] = field;\n else table.fields.push(field);\n const choices = (raw[\"choices\"] ?? raw[\"options\"]) as unknown;\n if (Array.isArray(choices)) {\n const colors = new Map<string, string>();\n const display = (raw[\"displayFormat\"] ?? raw[\"display_format\"]) as { options?: { choices?: Array<{ value: string; color: string }> } } | undefined;\n for (const c of display?.options?.choices ?? []) colors.set(c.value, c.color);\n table.options.set(\n key,\n choices.map((label) => ({\n id: idOf(`options.${table.token}.${key}.${String(label)}`),\n key: choiceSlug(String(label)),\n label: String(label),\n color: colors.get(String(label)) ?? null,\n })),\n );\n }\n (table.document[\"fields\"] as string[]).push(key);\n };\n\n const writeRow = (table: MemoryTable, id: string, data: Json) => {\n const doc: Json = {};\n for (const [k, v] of Object.entries(data)) if (!k.startsWith(\"_\")) doc[k] = v;\n // A choice cell holds the option's KEY (the store normalises label → key on the way in).\n for (const [key, opts] of table.options) {\n const v = doc[key];\n const toKey = (x: unknown) => opts.find((o) => o.label === x || o.key === x || o.id === x)?.key ?? x;\n if (Array.isArray(v)) doc[key] = v.map(toKey);\n else if (v !== undefined && v !== null) doc[key] = toKey(v);\n }\n const before = table.rows.get(id);\n if (!before) table.order.push(id);\n table.rows.set(id, { ...(before ?? {}), ...doc });\n world.recordTable.set(id, table);\n };\n\n for (const step of plan.steps) {\n const args = resolve(step.args) as Json;\n const tableId = typeof args[\"p_table_id\"] === \"string\" ? (args[\"p_table_id\"] as string) : null;\n const table = tableId ? world.tableById.get(tableId) : undefined;\n switch (step.door) {\n case \"table_from_example\":\n case \"table_declare\": {\n const example = (args[\"p_example\"] ?? { tables: [args[\"p_spec\"]] }) as { tables?: Json[] };\n for (const t of example.tables ?? []) {\n const token = String(t[\"token\"]);\n const id = idOf(`tables.${token}`);\n const made: MemoryTable = {\n id,\n token,\n document: {\n name: t[\"name\"],\n slug: token,\n label_singular: t[\"labelSingular\"] ?? null,\n label_plural: t[\"labelPlural\"] ?? null,\n description: t[\"describes\"] ?? null,\n title_field: t[\"titleField\"] ?? null,\n type: t[\"type\"] ?? \"entity\",\n display: t[\"display\"] ?? \"grid\",\n icon: t[\"icon\"] ?? null,\n fields: [],\n },\n fields: [],\n options: new Map(),\n rows: new Map(),\n order: [],\n };\n world.tables.push(made);\n world.tableById.set(id, made);\n tokenOfTable.set(id, token);\n for (const f of (t[\"fields\"] as Json[] | undefined) ?? []) addField(made, f);\n }\n break;\n }\n case \"field_declare\":\n if (table) addField(table, args[\"p_spec\"] as Json);\n break;\n case \"record_write\":\n if (table) writeRow(table, idOf(step.save ? Object.keys(step.save)[0]! : `${step.label}`), args[\"p_data\"] as Json);\n break;\n case \"record_write_many\":\n if (table) {\n const rows = (args[\"p_rows\"] as Json[]) ?? [];\n const ids = (args[\"p_ids\"] as string[] | undefined) ?? [];\n rows.forEach((r, i) => writeRow(table, ids[i] ?? idOf(`${step.label}.${i}`), r));\n }\n break;\n case \"record_change_many\":\n if (table) {\n for (const change of (args[\"p_changes\"] as Json[]) ?? []) {\n if (change[\"op\"] === \"update\" && typeof change[\"record_id\"] === \"string\") writeRow(table, change[\"record_id\"], change[\"patch\"] as Json);\n }\n }\n break;\n case \"view_declare\": {\n if (!tableId) break;\n const s = args[\"p_spec\"] as Json;\n const token = step.label.replace(/^views\\./, \"\");\n world.views.push({\n view_id: idOf(`views.${token}`),\n token,\n table_id: tableId,\n name: String(s[\"name\"] ?? token),\n definition: { table_id: tableId, ...((s[\"definition\"] as Json) ?? {}) },\n filters: (s[\"filters\"] as Json) ?? {},\n });\n break;\n }\n case \"form_declare\":\n case \"booking_declare\": {\n if (!tableId) break;\n const save = step.save ? Object.keys(step.save)[0]! : step.label;\n world.forms.push({\n form_id: idOf(save),\n token: step.label.replace(/^(forms|bookings|extras)\\./, \"\"),\n table_id: tableId,\n title: String(args[\"p_title\"] ?? \"\"),\n questions: (args[\"p_questions\"] as Json[]) ?? [],\n presentation: (args[\"p_presentation\"] as Json) ?? {},\n booking: step.door === \"booking_declare\" ? ((args[\"p_availability\"] as Json) ?? {}) : null,\n });\n break;\n }\n case \"dashboard_declare\": {\n if (!tableId) break;\n const save = step.save ? Object.keys(step.save)[0]! : step.label;\n world.dashboards.push({\n dashboard_id: idOf(save),\n token: step.label.replace(/^(dashboards|extras)\\./, \"\"),\n table_id: tableId,\n name: String(args[\"p_name\"] ?? \"\"),\n blocks: (args[\"p_blocks\"] as Json[]) ?? [],\n });\n break;\n }\n case \"pipeline_declare\": {\n const stage = ((args[\"p_spec\"] as Json)?.[\"stage_field\"] as Json | undefined)?.[\"key\"];\n if (tableId && typeof stage === \"string\") world.stageField.set(tableId, stage);\n break;\n }\n default:\n break;\n }\n }\n return world;\n}\n","// src/memory/doors.ts — @ai-matrx/records/memory (lane CHAIR-GALLERY-2, 2026-10-05)\n//\n// THE STORE'S READ DOORS, ANSWERED FROM MEMORY. `memoryDataSource(world)` is a `RecordsDataSource` —\n// the same seam a host binds supabase-js to — so every screen of @ai-matrx/records-ui mounts on it\n// unchanged and reads a template's tables, fields, choices, relations, rows, views, forms, booking\n// pages and dashboards exactly as the store would hand them back after an install.\n//\n// READ-ONLY BY CONSTRUCTION. There is no network here and nothing is persisted: every door that would\n// change the store answers the one refusal `PREVIEW_REFUSAL` in words a person can read. The only\n// thing a preview keeps is a viewer's own look (`view_look_set`), held in this data source's memory\n// for as long as the page is open — a switch between board and calendar is a look, not a write.\n//\n// A DOOR THIS FILE DOES NOT KNOW REFUSES BY NAME (it never answers an empty list): the refusal says\n// which door the preview does not answer, so a screen that needs one says so instead of lying.\n\nimport { memoryEntityDoors as entityDoors } from \"./entity\";\nimport type { RecordsDataSource, RecordsFilter, RecordsResponse } from \"../ports\";\nimport type { PgError } from \"../results\";\nimport { MEMORY_KERNEL, type MemoryTable, type MemoryWorld } from \"./world\";\n\ntype Json = Record<string, unknown>;\ntype Answer = { data: unknown; error: PgError | null };\n\n/** What every write door answers in a preview. */\nexport const PREVIEW_REFUSAL: PgError = {\n code: \"42501\",\n message: \"This is a preview of a template. Nothing here is saved — use the template to make it yours.\",\n details: null,\n hint: null,\n} as unknown as PgError;\n\nconst WRITE_DOOR =\n /(^|_)(write|writes|declare|delete|update|upsert|archive|restore|set|move|save|submit|insert|merge|retype|undo|retire|assign|claim|clear|snooze|unsnooze|publish|invite|revoke|issue|pin|duplicate|designate|bind|unbind|change|start|complete|decide|request|hold|release|expire|forget|begin|finish|rows|take|nudge|import|mute|sign|render|instantiate|ensure)(_|$)/;\n\nfunction ok(data: unknown): Answer {\n return { data, error: null };\n}\nfunction refuse(message: string, code = \"PGRST202\"): Answer {\n return { data: null, error: { code, message, details: null, hint: null } as unknown as PgError };\n}\n\nfunction stamp(world: MemoryWorld): Json {\n const at = `${world.today}T09:00:00+00:00`;\n return { created_at: at, updated_at: at, created_by: world.user_id, updated_by: world.user_id };\n}\n\n/** One row's document as the read doors hand it back: choices as words + `_choices`, worked-out values filled. */\nfunction readDocument(world: MemoryWorld, table: MemoryTable, id: string): Json {\n const stored = table.rows.get(id) ?? {};\n const doc: Json = { ...stored };\n const choices: Json = {};\n for (const [key, opts] of table.options) {\n const v = stored[key];\n if (v === undefined || v === null) continue;\n const one = (k: unknown) => opts.find((o) => o.key === k);\n if (Array.isArray(v)) {\n const picked = v.map(one).filter((o) => o !== undefined);\n doc[key] = picked.map((o) => o!.label);\n choices[key] = picked.map((o) => ({ key: o!.key, label: o!.label, id: o!.id, retired: false, reason: null }));\n } else {\n const o = one(v);\n if (o) {\n doc[key] = o.label;\n choices[key] = { key: o.key, label: o.label, id: o.id, retired: false, reason: null };\n }\n }\n }\n if (Object.keys(choices).length) doc[\"_choices\"] = choices;\n for (const f of table.fields) {\n if (f.data[\"type\"] !== \"formula\") continue;\n const key = String(f.data[\"key\"]);\n const config = (f.data[\"config\"] ?? {}) as Json;\n const parity = f.data[\"parity_type\"];\n if (parity === \"lookup\") doc[key] = lookup(world, table, stored, config);\n else if (parity === \"rollup\") doc[key] = rollup(world, table, id, config);\n }\n return doc;\n}\n\nfunction lookup(world: MemoryWorld, table: MemoryTable, stored: Json, config: Json): unknown {\n const via = String(config[\"via\"] ?? \"\");\n const pick = String(config[\"pick\"] ?? \"\");\n const target = stored[via];\n const first = Array.isArray(target) ? target[0] : target;\n if (typeof first !== \"string\") return null;\n const far = world.recordTable.get(first);\n if (!far) return null;\n const value = readDocument(world, far, first)[pick];\n void table;\n return value ?? null;\n}\n\nfunction rollup(world: MemoryWorld, table: MemoryTable, id: string, config: Json): unknown {\n // `via` names the relation field on the OTHER table that points here (\"table.field\" or \"field\").\n const via = String(config[\"via\"] ?? \"\");\n const [maybeTable, maybeField] = via.includes(\".\") ? via.split(\".\") : [null, via];\n const of = config[\"of\"] ? String(config[\"of\"]) : null;\n const agg = String(config[\"agg\"] ?? \"count\");\n const filter = (config[\"filter\"] ?? null) as Json | null;\n const values: unknown[] = [];\n let count = 0;\n for (const other of world.tables) {\n if (maybeTable && other.token !== maybeTable) continue;\n const rel = other.fields.find((f) => f.data[\"key\"] === maybeField && f.data[\"type\"] === \"relation\" && f.data[\"relation_target\"] === table.id);\n if (!rel) continue;\n for (const rid of other.order) {\n const row = other.rows.get(rid)!;\n const link = row[maybeField!];\n const linked = Array.isArray(link) ? link.includes(id) : link === id;\n if (!linked) continue;\n if (filter && !admits(world, other, rid, filter)) continue;\n count += 1;\n if (of) values.push(readDocument(world, other, rid)[of]);\n }\n }\n const nums = values.filter((v): v is number => typeof v === \"number\");\n switch (agg) {\n case \"count\":\n return count;\n case \"sum\":\n return nums.reduce((a, b) => a + b, 0);\n case \"avg\":\n return nums.length ? nums.reduce((a, b) => a + b, 0) / nums.length : null;\n case \"min\":\n return nums.length ? Math.min(...nums) : values.filter((v) => typeof v === \"string\").sort()[0] ?? null;\n case \"max\":\n return nums.length ? Math.max(...nums) : values.filter((v) => typeof v === \"string\").sort().at(-1) ?? null;\n default:\n return count;\n }\n}\n\n/** The store's filter, both shapes: a flat key → scalar / null / window object, or a rule tree. */\nfunction admits(world: MemoryWorld, table: MemoryTable, id: string, filter: unknown): boolean {\n if (!filter || typeof filter !== \"object\") return true;\n const doc = readDocument(world, table, id);\n const stored = table.rows.get(id) ?? {};\n const f = filter as Json;\n if (typeof f[\"op\"] === \"string\") return rule(table, doc, stored, f) !== false;\n for (const [key, want] of Object.entries(f)) {\n const got = doc[key];\n const raw = stored[key];\n if (want === null) {\n if (!(got === null || got === undefined || got === \"\")) return false;\n } else if (typeof want === \"object\" && !Array.isArray(want)) {\n const w = want as { from?: string | null; to?: string | null };\n if (typeof got !== \"string\" && typeof got !== \"number\") return false;\n const g = String(got);\n const at = new Date(g.length === 10 ? `${g}T00:00:00Z` : g).getTime();\n if (w.to && at >= new Date(w.to).getTime()) return false;\n if (w.from && at < new Date(w.from).getTime()) return false;\n } else {\n const list = Array.isArray(got) ? got : [got];\n const rawList = Array.isArray(raw) ? raw : [raw];\n if (!list.some((x) => x === want) && !rawList.some((x) => x === want)) return false;\n }\n }\n return true;\n}\n\nfunction rule(table: MemoryTable, doc: Json, stored: Json, node: Json): unknown {\n if (\"const\" in node) return node[\"const\"];\n if (typeof node[\"field\"] === \"string\") {\n const field = table.fields.find((f) => f.id === node[\"field\"] || f.data[\"key\"] === node[\"field\"]);\n return field ? doc[String(field.data[\"key\"])] ?? stored[String(field.data[\"key\"])] ?? null : null;\n }\n const args = ((node[\"args\"] as Json[]) ?? []).map((a) => rule(table, doc, stored, a));\n switch (node[\"op\"]) {\n case \"and\":\n case \"all\":\n return args.every((a) => a !== false);\n case \"or\":\n case \"any\":\n return args.some((a) => a !== false && a !== null);\n case \"not\":\n return args[0] === false;\n case \"eq\":\n return Array.isArray(args[0]) ? (args[0] as unknown[]).includes(args[1]) : args[0] === args[1];\n case \"neq\":\n return args[0] !== args[1];\n case \"is_empty\":\n return args[0] === null || args[0] === undefined || args[0] === \"\";\n case \"not_empty\":\n return !(args[0] === null || args[0] === undefined || args[0] === \"\");\n default:\n return true;\n }\n}\n\nfunction sortRows(world: MemoryWorld, table: MemoryTable, ids: string[], sort: unknown): string[] {\n const sorts = (Array.isArray(sort) ? sort : []) as Array<{ field?: string; direction?: string }>;\n if (!sorts.length) return ids;\n const docs = new Map(ids.map((id) => [id, readDocument(world, table, id)]));\n return [...ids].sort((a, b) => {\n for (const s of sorts) {\n const key = s.field ?? \"\";\n const x = docs.get(a)![key];\n const y = docs.get(b)![key];\n if (x === y) continue;\n if (x === undefined || x === null) return 1;\n if (y === undefined || y === null) return -1;\n const c = typeof x === \"number\" && typeof y === \"number\" ? x - y : String(x).localeCompare(String(y));\n if (c !== 0) return s.direction === \"desc\" ? -c : c;\n }\n return 0;\n });\n}\n\nfunction matching(world: MemoryWorld, table: MemoryTable, args: Json): string[] {\n const search = typeof args[\"p_search\"] === \"string\" ? (args[\"p_search\"] as string).trim().toLowerCase() : \"\";\n let ids = table.order.filter((id) => admits(world, table, id, args[\"p_filter\"]));\n if (search) ids = ids.filter((id) => JSON.stringify(readDocument(world, table, id)).toLowerCase().includes(search));\n return sortRows(world, table, ids, args[\"p_sort\"]);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// A dashboard block, worked out from the template's rows the way `custom.dashboard_run` answers it.\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst DAY_MS = 86_400_000;\n\n/** The first day of the bucket a date falls in, as the store answers it (\"YYYY-MM-DDT00:00:00+00:00\"). */\nfunction bucketOf(value: unknown, by: string): string | null {\n if (typeof value !== \"string\" || value.length < 10) return null;\n const [y, m, d] = value.slice(0, 10).split(\"-\").map(Number) as [number, number, number];\n let at = new Date(Date.UTC(y, m - 1, d));\n if (by === \"week\") at = new Date(at.getTime() - ((at.getUTCDay() + 6) % 7) * DAY_MS);\n else if (by === \"month\") at = new Date(Date.UTC(y, m - 1, 1));\n else if (by === \"quarter\") at = new Date(Date.UTC(y, Math.floor((m - 1) / 3) * 3, 1));\n else if (by === \"year\") at = new Date(Date.UTC(y, 0, 1));\n return `${at.toISOString().slice(0, 10)}T00:00:00+00:00`;\n}\n\nfunction groupValues(doc: Json, stored: Json, key: string): Array<string | null> {\n const shown = doc[key];\n const raw = stored[key];\n // A relation groups by the linked record's id (the chart names it); a choice by its words.\n const pick = typeof raw === \"string\" && raw === shown ? raw : shown ?? raw;\n const list = Array.isArray(pick) ? pick : [pick];\n const out = list.map((v) => (v === undefined || v === null || v === \"\" ? null : String(v)));\n return out.length ? out : [null];\n}\n\nfunction runBlock(world: MemoryWorld, subject: string, raw: Json, canvas: Json, index: number): Json {\n const table = world.tableById.get(String(raw[\"table_id\"] ?? subject));\n const title = String(raw[\"title\"] ?? `Block ${index + 1}`);\n const base = { ...raw, title, table_id: table?.id ?? subject, ms: 0 };\n if (!table) return { ...base, rows: [], refused: \"This block's table is not in this template.\" };\n if (raw[\"kind\"] === \"stuck\") return { ...base, rows: [] };\n const measures = ((raw[\"measures\"] as Json[]) ?? [{ op: \"count\" }]).map((m) => ({ op: String(m[\"op\"] ?? \"count\"), key: m[\"key\"] as string | undefined }));\n const groupBy = ((raw[\"group_by\"] as string[]) ?? []).slice();\n const bucket = (raw[\"bucket\"] as { key?: string; by?: string } | null) ?? null;\n const ids = table.order.filter((id) => admits(world, table, id, raw[\"filter\"]) && admits(world, table, id, canvas));\n const groups = new Map<string, { groups: Record<string, string | null>; ids: string[] }>();\n for (const id of ids) {\n const doc = readDocument(world, table, id);\n const stored = table.rows.get(id) ?? {};\n let combos: Array<Record<string, string | null>> = [{}];\n for (const key of groupBy) {\n const values = groupValues(doc, stored, key);\n combos = combos.flatMap((c) => values.map((v) => ({ ...c, [key]: v })));\n }\n if (bucket?.key) {\n const at = bucketOf(doc[bucket.key] ?? stored[bucket.key], bucket.by ?? \"month\");\n if (at === null) continue;\n combos = combos.map((c) => ({ ...c, [`${bucket.key}_${bucket.by ?? \"month\"}`]: at }));\n }\n for (const c of combos) {\n const k = JSON.stringify(c);\n const g = groups.get(k) ?? { groups: c, ids: [] };\n g.ids.push(id);\n groups.set(k, g);\n }\n }\n if (!groupBy.length && !bucket?.key && !groups.size) groups.set(\"{}\", { groups: {}, ids: [] });\n const measureName = (m: { op: string; key?: string | undefined }) => (m.op === \"count\" ? \"count\" : `${m.op}_${m.key ?? \"\"}`);\n let rows = [...groups.values()].map((g) => {\n const out: Record<string, number | null> = {};\n for (const m of measures) {\n if (m.op === \"count\") {\n out[\"count\"] = g.ids.length;\n continue;\n }\n const nums = g.ids.map((id) => readDocument(world, table, id)[m.key ?? \"\"]).filter((v): v is number => typeof v === \"number\");\n const sum = nums.reduce((a, b) => a + b, 0);\n out[measureName(m)] =\n m.op === \"sum\" ? sum : !nums.length ? null : m.op === \"avg\" ? sum / nums.length : m.op === \"min\" ? Math.min(...nums) : m.op === \"max\" ? Math.max(...nums) : null;\n }\n return { groups: g.groups, measures: out, row_count: g.ids.length };\n });\n const primary = measures[0] ? measureName(measures[0]) : \"count\";\n if (bucket?.key) {\n const k = `${bucket.key}_${bucket.by ?? \"month\"}`;\n rows.sort((a, b) => String(a.groups[k]).localeCompare(String(b.groups[k])));\n } else rows.sort((a, b) => (b.measures[primary] ?? 0) - (a.measures[primary] ?? 0));\n const limit = Number(raw[\"limit\"] ?? 0);\n if (limit > 0) rows = rows.slice(0, limit);\n return { ...base, measures, group_by: groupBy, rows };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// A booking page's times, from its declared hours, in the business's own clock.\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface Availability {\n timezone: string;\n slot_minutes: number;\n buffer_minutes: number;\n lead_minutes: number;\n max_per_day: number;\n days: number;\n windows: Array<{ weekday: number; from: string; to: string; member_user_id: string | null }>;\n}\n\nfunction bookingAvailability(world: MemoryWorld, raw: Json): Availability {\n const num = (k: string, fallback: number) => (typeof raw[k] === \"number\" ? (raw[k] as number) : fallback);\n return {\n timezone: String(raw[\"timezone\"] ?? world.timezone),\n slot_minutes: num(\"slot_minutes\", 30),\n buffer_minutes: num(\"buffer_minutes\", 0),\n lead_minutes: num(\"lead_minutes\", 0),\n max_per_day: num(\"max_per_day\", 0),\n days: num(\"days\", 14),\n windows: ((raw[\"windows\"] as Json[]) ?? []).map((w) => ({\n weekday: Number(w[\"weekday\"] ?? 1),\n from: String(w[\"from\"] ?? \"09:00\"),\n to: String(w[\"to\"] ?? \"17:00\"),\n member_user_id: null,\n })),\n };\n}\n\n/** Minutes the zone is ahead of UTC at one instant. */\nfunction zoneOffset(zone: string, at: number): number {\n const parts = new Intl.DateTimeFormat(\"en-US\", { timeZone: zone, hourCycle: \"h23\", year: \"numeric\", month: \"2-digit\", day: \"2-digit\", hour: \"2-digit\", minute: \"2-digit\" })\n .formatToParts(new Date(at))\n .reduce<Record<string, number>>((acc, p) => (p.type === \"literal\" ? acc : { ...acc, [p.type]: Number(p.value) }), {});\n return (Date.UTC(parts[\"year\"]!, parts[\"month\"]! - 1, parts[\"day\"]!, parts[\"hour\"]!, parts[\"minute\"]!) - at) / 60_000;\n}\n\n/** The instant a wall-clock time on one day in a zone is. */\nfunction zonedInstant(zone: string, day: number, minutes: number): number {\n const guess = day + minutes * 60_000;\n return guess - zoneOffset(zone, guess - zoneOffset(zone, guess) * 60_000) * 60_000;\n}\n\nfunction bookingSlots(world: MemoryWorld, table: MemoryTable, a: Availability, days: number) {\n const zone = (() => {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: a.timezone });\n return a.timezone;\n } catch {\n return \"UTC\";\n }\n })();\n const taken = new Set<number>();\n for (const id of table.order) {\n for (const v of Object.values(table.rows.get(id) ?? {})) {\n if (typeof v === \"string\" && /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}/.test(v)) taken.add(new Date(v).getTime());\n }\n }\n const toMin = (hhmm: string) => {\n const [h, m] = hhmm.split(\":\").map(Number);\n return (h ?? 0) * 60 + (m ?? 0);\n };\n const [y, m, d] = world.today.split(\"-\").map(Number) as [number, number, number];\n const start = Date.UTC(y, m - 1, d);\n const earliest = zonedInstant(zone, start, 9 * 60) + a.lead_minutes * 60_000;\n const step = Math.max(5, a.slot_minutes + a.buffer_minutes);\n const slots: Array<{ key: string; at: string; taken: boolean; member_user_id: null }> = [];\n for (let i = 0; i < Math.max(1, days); i += 1) {\n const day = start + i * DAY_MS;\n const weekday = new Date(day).getUTCDay();\n let today = 0;\n for (const w of a.windows.filter((x) => x.weekday === weekday)) {\n for (let t = toMin(w.from); t + a.slot_minutes <= toMin(w.to); t += step) {\n if (a.max_per_day > 0 && today >= a.max_per_day) break;\n const at = zonedInstant(zone, day, t);\n if (at < earliest) continue;\n today += 1;\n const iso = new Date(at).toISOString();\n slots.push({ key: iso, at: iso, taken: taken.has(at), member_user_id: null });\n }\n }\n }\n return slots;\n}\n\nconst VIEWER = \"viewer\";\n\n/** The memory store, as the seam every records-ui screen reads through. */\nexport function memoryDataSource(world: MemoryWorld): RecordsDataSource & { readonly world: MemoryWorld } {\n const looks = new Map<string, { look: Json; updated_at: string }>();\n const tableRow = (t: MemoryTable) => ({ id: t.id, document: { ...t.document }, level: VIEWER });\n const row = (t: MemoryTable, id: string) => ({ id, document: readDocument(world, t, id), level: VIEWER });\n const tableOf = (args: Json) => world.tableById.get(String(args[\"p_table_id\"] ?? \"\"));\n const fieldById = (id: unknown) => {\n for (const t of world.tables) for (const f of t.fields) if (f.id === id) return { t, f };\n return null;\n };\n const nameOf = (id: string): string | null => {\n const t = world.recordTable.get(id);\n if (!t) return null;\n const title = String(t.document[\"title_field\"] ?? \"\");\n const v = readDocument(world, t, id)[title];\n return typeof v === \"string\" ? v : v === undefined || v === null ? null : String(v);\n };\n\n const doors: Record<string, (args: Json) => Answer> = {\n table_kernel_id: () => ok(MEMORY_KERNEL.table),\n field_kernel_id: () => ok(MEMORY_KERNEL.field),\n person_kernel_id: () => ok(MEMORY_KERNEL.person),\n file_kernel_id: () => ok(MEMORY_KERNEL.file),\n rule_kernel_id: () => ok(MEMORY_KERNEL.rule),\n store_is_open: () => ok(true),\n read_records: (args) => {\n const limit = Number(args[\"p_limit\"] ?? 50);\n const offset = Number(args[\"p_offset\"] ?? 0);\n if (args[\"p_table_id\"] === MEMORY_KERNEL.table) return ok(world.tables.slice(offset, offset + limit).map(tableRow));\n const t = tableOf(args);\n if (!t) return ok([]);\n return ok(t.order.slice(offset, offset + limit).map((id) => row(t, id)));\n },\n read_records_by_ids: (args) => {\n const ids = (args[\"p_record_ids\"] as string[]) ?? [];\n if (args[\"p_table_id\"] === MEMORY_KERNEL.table) return ok(world.tables.filter((t) => ids.includes(t.id)).map(tableRow));\n const t = tableOf(args);\n if (!t) return ok([]);\n return ok(ids.filter((id) => t.rows.has(id)).map((id) => row(t, id)));\n },\n read_records_matching: (args) => {\n const t = tableOf(args);\n if (!t) return ok([]);\n const limit = Number(args[\"p_limit\"] ?? 50);\n const offset = Number(args[\"p_offset\"] ?? 0);\n return ok(matching(world, t, args).slice(offset, offset + limit).map((id) => row(t, id)));\n },\n read_records_page: (args) => {\n const t = tableOf(args);\n const limit = Number(args[\"p_limit\"] ?? 50);\n const offset = Number(args[\"p_offset\"] ?? 0);\n if (!t) return ok({ rows: [], total: 0, limit, offset, sort_ignored: [] });\n const ids = matching(world, t, args);\n return ok({ rows: ids.slice(offset, offset + limit).map((id) => row(t, id)), total: ids.length, limit, offset, sort_ignored: [] });\n },\n read_record: (args) => {\n const id = String(args[\"p_record_id\"] ?? \"\");\n const t = world.recordTable.get(id);\n if (!t) return refuse(\"That record is not in this template.\", \"P0002\");\n return ok(readDocument(world, t, id));\n },\n record_headers: (args) =>\n ok(\n ((args[\"p_ids\"] as string[]) ?? [])\n .filter((id) => world.recordTable.has(id))\n .map((id) => ({ id, mine: false, version: 1, table_id: world.recordTable.get(id)!.id, deleted_at: null, ...stamp(world) })),\n ),\n applicable_fields: (args) => {\n const t = tableOf(args);\n if (!t) return ok([]);\n return ok(\n t.fields.map((f) => ({\n id: f.id,\n data: f.data,\n version: 1,\n metadata: {},\n shown_to: null,\n table_id: MEMORY_KERNEL.field,\n data_class: \"field\",\n deleted_at: null,\n visibility: \"internal\",\n custom_fields: {},\n organization_id: world.organization_id,\n ...stamp(world),\n })),\n );\n },\n field_options: (args) => {\n const hit = fieldById(args[\"p_field_id\"]);\n if (!hit) return ok([]);\n const opts = hit.t.options.get(String(hit.f.data[\"key\"])) ?? [];\n return ok(\n opts.map((o, i) => ({\n id: o.id,\n organization_id: world.organization_id,\n table_id: (hit.f.data[\"config\"] as Json)[\"options_table_id\"] ?? null,\n data_class: \"record\",\n data: { name: o.label, sort: (i + 1) * 10, ...(o.color ? { color: o.color } : {}) },\n version: 1,\n metadata: { option_key: o.key },\n custom_fields: {},\n visibility: \"internal\",\n deleted_at: null,\n ...stamp(world),\n })),\n );\n },\n my_levels: (args) => ok(((args[\"p_ids\"] as string[]) ?? []).map((id) => ({ id, level: VIEWER }))),\n views: (args) =>\n ok(\n world.views\n .filter((v) => !args[\"p_table_id\"] || v.table_id === args[\"p_table_id\"])\n .map((v) => ({ view_id: v.view_id, name: v.name, table_id: v.table_id, filters: v.filters, definition: v.definition, created_at: `${world.today}T09:00:00Z` })),\n ),\n view_look_read: (args) => {\n const out: Json = {};\n for (const [key, look] of looks) if (key.startsWith(`${String(args[\"p_table_id\"])}:`)) out[key.split(\":\")[1]!] = look;\n return ok(out);\n },\n view_look_set: (args) => {\n const key = `${String(args[\"p_table_id\"])}:${String(args[\"p_view_id\"])}`;\n const look = (args[\"p_look\"] as Json | null) ?? null;\n if (look) looks.set(key, { look, updated_at: new Date().toISOString() });\n else looks.delete(key);\n return ok(look);\n },\n grid_layout: (args) =>\n ok({\n layout: { mode: \"auto\", wrap: false, row_height: \"normal\", fit_max_columns: 8, freeze_first_column: false },\n source: { mode: \"platform\", wrap: \"platform\", row_height: \"platform\", fit_max_columns: \"platform\", freeze_first_column: \"platform\" },\n refused: [],\n view_id: args[\"p_view_id\"] ?? null,\n }),\n table_decorations: () => ok({ rows: {}, cells: {}, rules: [], stale: [], colors: [\"slate\", \"green\", \"amber\", \"red\", \"blue\", \"violet\", \"teal\"], columns: {}, version: 1, rule_ops: [] }),\n row_actions: () => ok({ stale: [], actions: [] }),\n table_stage_field: (args) => ok(world.stageField.get(String(args[\"p_table_id\"])) ?? null),\n pipeline_read: (args) => {\n const t = tableOf(args);\n const stage = t ? world.stageField.get(t.id) : undefined;\n const field = stage ? t!.fields.find((f) => f.data[\"key\"] === stage) : undefined;\n if (!t || !stage || !field) return ok({ is_pipeline: false, why: \"This table has no stage column.\" });\n const stages = (t.options.get(stage) ?? []).map((o) => ({ key: o.key, label: o.label, retired: false }));\n return ok({ is_pipeline: true, table_id: t.id, stage_field: stage, field_id: field.id, stage_label: field.data[\"label\"], stages, rules: [] });\n },\n pipeline_board: (args) => {\n const t = tableOf(args);\n const stage = t ? world.stageField.get(t.id) : undefined;\n if (!t || !stage) return ok([]);\n const measure = typeof args[\"p_measure\"] === \"string\" ? (args[\"p_measure\"] as string) : null;\n const ids = t.order.filter((id) => admits(world, t, id, args[\"p_filter\"]));\n return ok(\n (t.options.get(stage) ?? []).map((o, i) => {\n const inIt = ids.filter((id) => t.rows.get(id)![stage] === o.key);\n const total = measure\n ? inIt.reduce((sum, id) => sum + (typeof t.rows.get(id)![measure] === \"number\" ? (t.rows.get(id)![measure] as number) : 0), 0)\n : null;\n return { stage_key: o.key, stage_label: o.label, stage_position: i + 1, cards: inIt.length, total, wip_limit: null, over_limit: false };\n }),\n );\n },\n relation_words_many: (args) =>\n ok(((args[\"p_record_ids\"] as string[]) ?? []).map((id) => ({ record_id: id, words: nameOf(id), archived: false }))),\n reverse_columns: (args) => {\n const target = String(args[\"p_table_id\"] ?? \"\");\n const out: Json[] = [];\n for (const t of world.tables) {\n for (const f of t.fields) {\n if (f.data[\"type\"] !== \"relation\" || f.data[\"relation_target\"] !== target) continue;\n out.push({\n key: `${t.token}__${String(f.data[\"key\"])}`,\n label: String(t.document[\"name\"] ?? t.token),\n source_field_id: f.id,\n source_field_key: f.data[\"key\"],\n source_field_label: f.data[\"label\"],\n source_table_id: t.id,\n source_table_name: t.document[\"name\"],\n cardinality: \"many\",\n read_only: true,\n });\n }\n }\n return ok(out);\n },\n reverse_links_many: (args) => {\n const hit = fieldById(args[\"p_field_id\"]);\n return ok(\n ((args[\"p_record_ids\"] as string[]) ?? []).map((rid) => {\n if (!hit) return { record_id: rid, total: 0, links: [] };\n const key = String(hit.f.data[\"key\"]);\n const links = hit.t.order\n .filter((id) => {\n const v = hit.t.rows.get(id)![key];\n return Array.isArray(v) ? v.includes(rid) : v === rid;\n })\n .map((id) => ({ id, words: nameOf(id) ?? \"\" }));\n return { record_id: rid, total: links.length, links };\n }),\n );\n },\n // A template's own record has no history, comments, checklists or worked-out provenance yet:\n // these are the answers an installed template gives on its first day.\n record_history: () => ok([]),\n field_history: () => ok([]),\n computed_provenance: () => ok([]),\n comment_thread: (args) => ok({ record_id: args[\"p_record_id\"] ?? null, comments: [], may_comment: false, may_resolve: false }),\n checklist_runs: () => ok([]),\n checklist_templates: () => ok([]),\n doc_templates: () => ok([]),\n doc_renders: () => ok([]),\n doc_signatures: () => ok([]),\n record_row_controls: () =>\n ok({\n shown_to: { value: null, effective: \"everyone\", type_default: null, table_default: null, allowed: [\"everyone\"], is_child: false, can_change: false },\n published_to_web: { available: false, value: false, table_default: null, can_change: false },\n indexed: { available: false, value: null, table_default: null, effective: false, can_change: false },\n }),\n enrich_cells: () => ok([]),\n enrichments: () => ok([]),\n pipeline_pending: () => ok([]),\n record_stage_pending: () => ok([]),\n io_imports: () => ok([]),\n relation_words: (args) => ok(nameOf(String(args[\"p_value\"] ?? \"\"))),\n // The read doors a form, a booking page and a dashboard are drawn from (lane CHAIR-GALLERY-3).\n forms: (args) =>\n ok(\n world.forms\n .filter((f) => !f.booking && (!args[\"p_table_id\"] || f.table_id === args[\"p_table_id\"]))\n .map((f) => ({\n form_id: f.form_id,\n table_id: f.table_id,\n title: f.title,\n slug: f.token,\n published_at: `${world.today}T09:00:00Z`,\n closed_at: null,\n submission_cap: null,\n responses: 0,\n in_table: 0,\n held: 0,\n rejected: 0,\n state: \"open\",\n quarantine_rule_id: null,\n notify_rule_id: null,\n questions: f.questions,\n presentation: { ...f.presentation, questions: f.presentation[\"questions\"] ?? f.questions },\n })),\n ),\n form_preview_asks: (args) => {\n const t = tableOf(args);\n const values = (args[\"p_values\"] as Json | null) ?? {};\n return ok(\n ((args[\"p_questions\"] as Json[]) ?? []).map((q) => {\n const when = q[\"show_if\"] ?? q[\"showIf\"] ?? null;\n const asked = !when || !t ? true : rule(t, values, values, when as Json) !== false;\n return { field_key: String(q[\"field\"] ?? q[\"key\"] ?? \"\"), asked, decided: true, said: null };\n }),\n );\n },\n bookings: (args) =>\n ok(\n world.forms\n .filter((f) => f.booking && (!args[\"p_table_id\"] || f.table_id === args[\"p_table_id\"]))\n .map((f) => ({\n form_id: f.form_id,\n table_id: f.table_id,\n title: f.title,\n slug: f.token,\n published_at: `${world.today}T09:00:00Z`,\n closed_at: null,\n slot_minutes: Number(f.booking![\"slot_minutes\"] ?? 30),\n timezone: String(f.booking![\"timezone\"] ?? world.timezone),\n slot_table_id: null,\n booked: 0,\n cancelled: 0,\n upcoming: 0,\n held: 0,\n next_at: null,\n state: \"open\",\n })),\n ),\n booking_public: (args) => {\n const f = world.forms.find((x) => x.form_id === args[\"p_form_id\"] && x.booking);\n const t = f ? world.tableById.get(f.table_id) : undefined;\n if (!f || !t) return refuse(\"That booking page is not in this template.\", \"P0002\");\n const availability = bookingAvailability(world, f.booking!);\n return ok({\n form_id: f.form_id,\n organization_id: world.organization_id,\n table_id: t.id,\n title: f.title,\n presentation: { ...f.presentation, questions: f.questions },\n fields: t.fields.map((x) => ({ id: x.id, ...x.data })),\n honeypot_key: null,\n availability,\n slots: bookingSlots(world, t, availability, Number(args[\"p_days\"] ?? availability.days)),\n state: \"open\",\n message: null,\n });\n },\n dashboards: (args) =>\n ok(\n world.dashboards\n .filter((d) => !args[\"p_table_id\"] || d.table_id === args[\"p_table_id\"])\n .map((d) => ({\n dashboard_id: d.dashboard_id,\n table_id: d.table_id,\n name: d.name,\n blocks: d.blocks,\n presentation: {},\n block_count: d.blocks.length,\n version: 1,\n created_at: `${world.today}T09:00:00Z`,\n updated_at: `${world.today}T09:00:00Z`,\n })),\n ),\n dashboard_run: (args) => {\n const d = world.dashboards.find((x) => x.dashboard_id === args[\"p_dashboard_id\"]);\n if (!d) return refuse(\"That dashboard is not in this template.\", \"P0002\");\n const canvas = (args[\"p_filter\"] as Json | null) ?? {};\n return ok({\n dashboard_id: d.dashboard_id,\n name: d.name,\n subject_table_id: d.table_id,\n presentation: {},\n filter: canvas,\n grain: null,\n compare: null,\n calendar: { time_zone: world.timezone, week_start: \"monday\" },\n blocks: d.blocks.map((b, i) => runBlock(world, d.table_id, b, canvas, i)),\n });\n },\n dashboard_stuck: () => ok([]),\n };\n\n const source = {\n world,\n rpc(fn: string, args: Record<string, unknown>): PromiseLike<Answer> {\n const name = fn.replace(/^custom\\./, \"\").replace(/^platform\\./, \"\");\n const entityDoor = world.entities ? (entityDoors(world.entities) as Record<string, (a: Json) => Answer | null>)[name] : undefined;\n const fromEntity = entityDoor ? entityDoor(args ?? {}) : null;\n if (fromEntity) return Promise.resolve(fromEntity);\n const door = doors[name];\n if (door) return Promise.resolve(door(args ?? {}));\n if (WRITE_DOOR.test(name)) return Promise.resolve({ data: null, error: PREVIEW_REFUSAL });\n return Promise.resolve(refuse(`A template preview does not answer ${name}.`));\n },\n schema() {\n return {\n from(): never {\n throw new Error(\"A template preview reads through the store's doors, never a table.\");\n },\n };\n },\n };\n return source as unknown as RecordsDataSource & { readonly world: MemoryWorld };\n}\n\nexport type { RecordsFilter, RecordsResponse };\n"],"mappings":"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","names":["question","COMPUTED","ok","refuse","zoneOffset","m","t"]}
|
|
1
|
+
{"version":3,"sources":["../../src/memory/index.ts","../../src/memory/entity.ts","../../src/templates/payloads.ts","../../src/templates/types.ts","../../src/templates/confidential.ts","../../src/templates/extras.ts","../../src/store.generated.ts","../../src/templates/validate.ts","../../src/templates/plan.ts","../../src/choice.ts","../../src/memory/world.ts","../../src/memory/doors.ts"],"sourcesContent":["// src/memory/index.ts — @ai-matrx/records/memory (lane CHAIR-GALLERY-2, 2026-10-05)\n//\n// THE IN-MEMORY RECORD STORE. One call turns a template spec into a `RecordsConfig` every\n// @ai-matrx/records hook and every @ai-matrx/records-ui screen mounts on, read-only:\n//\n// const preview = templatePreview(spec, { today });\n// <RecordsMount config={preview.config}> <TablePage tableId={preview.tables[0].id} /> </RecordsMount>\n//\n// For: template pages, the describe box's \"here is what I will build\" before install, docs, and any\n// migration preview. Nothing it answers is sent anywhere and nothing a person does in it is saved.\n\nimport type { RecordsConfig } from \"../ports\";\nimport type { TemplateSpec } from \"../templates/types\";\nimport { memoryDataSource } from \"./doors\";\nimport { stableId as stableIdOf, templateWorld, type MemoryWorld, type TemplateWorldOptions } from \"./world\";\n\nexport { memoryDataSource, PREVIEW_REFUSAL } from \"./doors\";\nexport { MEMORY_KERNEL, stableId, templateWorld } from \"./world\";\nexport { memoryEntityAsk, memoryEntityDescribe, memoryEntityRows, memoryEntityWrite } from \"./entity\";\nexport type { MemoryEntity, MemoryEntityColumn, MemoryEntitySpec } from \"./entity\";\nimport type { MemoryEntitySpec } from \"./entity\";\n\n/** Add standard sources (`{ kind: \"entity\", token }`) to a memory world, in the live doors' shapes. */\nexport function withEntities(world: MemoryWorld, specs: MemoryEntitySpec[]): MemoryWorld {\n const entities = new Map(world.entities ?? []);\n for (const s of specs) entities.set(s.token, { ...s, rows: s.rows.map((r) => ({ ...r })) });\n world.entities = entities;\n return world;\n}\nexport type { MemoryDashboard, MemoryField, MemoryForm, MemoryOption, MemoryTable, MemoryView, MemoryWorld, TemplateWorldOptions } from \"./world\";\n\nexport interface TemplatePreview {\n /** Mount this: `<RecordsMount config={preview.config}>` / `<RecordsProvider config={preview.config}>`. */\n config: RecordsConfig;\n world: MemoryWorld;\n /** The template's tables in its own order: id (for `TablePage`), token, name. */\n tables: Array<{ id: string; token: string; name: string; rows: number }>;\n forms: Array<{ id: string; token: string; title: string; tableId: string; booking: boolean }>;\n dashboards: Array<{ id: string; token: string; name: string; tableId: string }>;\n}\n\n/** A template, installed into memory and ready to mount. Pure for a given spec and day. */\nexport function templatePreview(spec: TemplateSpec, options: TemplateWorldOptions = {}): TemplatePreview {\n const world = templateWorld(spec, options);\n const config: RecordsConfig = {\n dataSource: memoryDataSource(world),\n actor: { actor: \"user\", user_id: world.user_id },\n organizationId: world.organization_id,\n };\n return {\n config,\n world,\n tables: world.tables.map((t) => ({ id: t.id, token: t.token, name: String(t.document[\"name\"] ?? t.token), rows: t.order.length })),\n forms: world.forms.map((f) => ({ id: f.form_id, token: f.token, title: f.title, tableId: f.table_id, booking: f.booking !== null })),\n dashboards: world.dashboards.map((d) => ({ id: d.dashboard_id, token: d.token, name: d.name, tableId: d.table_id })),\n };\n}\n\n/** A memory store holding only standard sources — mount it like a template preview. */\nexport function entityStore(specs: MemoryEntitySpec[], options: { today?: string } = {}): { config: RecordsConfig; world: MemoryWorld } {\n const world: MemoryWorld = {\n organization_id: stableIdOf(\"entity-store-organization\"),\n user_id: stableIdOf(\"entity-store-person\"),\n timezone: \"UTC\",\n today: options.today ?? new Date().toISOString().slice(0, 10),\n businessName: \"\",\n tables: [], tableById: new Map(), views: [], forms: [], dashboards: [],\n recordTable: new Map(), stageField: new Map(),\n };\n withEntities(world, specs);\n return {\n world,\n config: { dataSource: memoryDataSource(world), actor: { actor: \"user\", user_id: world.user_id }, organizationId: world.organization_id },\n };\n}\n","// src/memory/entity.ts — @ai-matrx/records/memory · lane CHAIR-ENTITY-BLOCKS (2026-10-05)\n//\n// A STANDARD SOURCE IN MEMORY: `{ kind: \"entity\", token }` answered the way the live drill doors\n// answer it since chairblk_a (matrx-frontend migrations/campaign/): `drill_describe` names each\n// column already presented (`api.columns`: api_name, name, type, choices, lookup), `drill_rows`\n// returns rows in WORDS (a deal's `stage_id` reads \"Qualified\"), and `entity_row_write` takes a\n// choice by its word. A screen built on an entity source runs on this fake with the same shapes.\n\ntype Json = Record<string, unknown>;\n\n/** One presented column, exactly as `platform.drill_describe(...).api.columns[]` says it. */\nexport interface MemoryEntityColumn {\n api_name: string;\n name: string;\n /** \"text\" | \"number\" | \"choice\" | \"date\" | \"datetime\" | \"checkbox\" | … */\n type: string;\n writable?: boolean;\n choices?: string[];\n /** A column shown as the words another table holds (`replaces`: the id column itself). */\n lookup?: { via: string; token: string; column: string; replaces: boolean };\n}\n\nexport interface MemoryEntitySpec {\n token: string;\n label: string;\n columns: MemoryEntityColumn[];\n /** Rows as the door returns them: `id` plus api_name → value, lookups and choices in words. */\n rows: Json[];\n}\n\nexport interface MemoryEntity extends MemoryEntitySpec {\n rows: Json[];\n}\n\ntype Answer = { data: unknown; error: null } | { data: null; error: { code: string; message: string; details: null; hint: string | null } };\nconst ok = (data: unknown): Answer => ({ data, error: null });\nconst refuse = (message: string, code = \"22023\", hint: string | null = null): Answer => ({\n data: null,\n error: { code, message, details: null, hint },\n});\n\n/** What `drill_describe` answers for a memory entity (dimensions from its choices, count + sums). */\nexport function memoryEntityDescribe(e: MemoryEntity): Json {\n const dimensions = e.columns\n .filter((c) => c.type === \"choice\" && Array.isArray(c.choices))\n .map((c) => ({ key: c.api_name, label: c.name, from: c.api_name, kind: \"choice\", cardinality: \"low\",\n choices: (c.choices ?? []).map((w) => ({ value: w, label: w })) }));\n const measures = [\n { key: \"count\", label: `Number of ${e.label.toLowerCase()}`, op: \"count\", unit: \"count\", additive: true },\n ...e.columns.filter((c) => c.type === \"number\").map((c) => ({\n key: `sum_${c.api_name}`, label: `Total ${c.name.toLowerCase()}`, op: \"sum\", of: c.api_name, additive: true,\n })),\n ];\n return {\n key: e.token, label: e.label, grain: `one row per ${e.label.toLowerCase()}`, lanes: [\"organization\", \"platform\"],\n dimensions, measures, paths: [], inferred: [],\n detail: { columns: e.columns.map((c) => c.api_name) },\n source: { kind: \"entity\", token: e.token }, mode: \"invoker\",\n api: { label: e.label, reach: \"read_write\", columns: e.columns },\n calendar: { time_zone: \"UTC\", week_start: \"monday\" },\n };\n}\n\nfunction matches(row: Json, where: Json | undefined): boolean {\n for (const [k, want] of Object.entries(where ?? {})) {\n const have = row[k] ?? null;\n if (Array.isArray(want)) { if (!want.includes(have as never)) return false; }\n else if (want === null) { if (have !== null) return false; }\n else if (typeof want === \"object\") continue; // operators are the live door's; memory keeps equality\n else if (String(have).toLowerCase() !== String(want).toLowerCase()) return false;\n }\n return true;\n}\n\n/** What `drill_rows` answers: one page, rows in words. */\nexport function memoryEntityRows(e: MemoryEntity, question: Json): Json {\n const limit = Number(question[\"limit\"] ?? 50);\n const offset = Number(question[\"offset\"] ?? 0);\n const rows = e.rows.filter((r) => matches(r, question[\"where\"] as Json | undefined));\n const page = rows.slice(offset, offset + limit);\n return {\n rows: page, total: rows.length, limit, offset, as_of: null,\n columns: e.columns.map((c) => c.api_name),\n ...(offset + page.length < rows.length ? { next_offset: offset + page.length } : {}),\n };\n}\n\n/**\n * What `drill_ask` answers for a memory entity: one row per group of the asked Dimensions (a choice\n * or a lookup, both already words here), then the `total` row; `count`, `sum_<col>` and ad hoc\n * `{op, of}` measures keyed `<op>_<of>` exactly as the live door keys them; `where` narrows first.\n */\nexport function memoryEntityAsk(e: MemoryEntity, question: Json): Json[] {\n const by = ((question[\"by\"] as string[] | undefined) ?? []).map((k) => k.split(\":\")[0]!);\n const shown = ((question[\"show\"] as Array<string | { op: string; of?: string }> | undefined) ?? [\"count\"]);\n const measures = (shown.length ? shown : [\"count\"]).map((m) =>\n typeof m === \"string\"\n ? m === \"count\" ? { key: \"count\", op: \"count\", of: null as string | null } : { key: m, op: m.split(\"_\")[0]!, of: m.slice(m.indexOf(\"_\") + 1) }\n : { key: m.op === \"count\" ? \"count\" : `${m.op}_${m.of ?? \"\"}`, op: m.op, of: m.of ?? null });\n const rows = e.rows.filter((r) => matches(r, question[\"where\"] as Json | undefined));\n const measure = (list: Json[]): Record<string, number | null> => {\n const out: Record<string, number | null> = {};\n for (const m of measures) {\n if (m.op === \"count\") { out[m.key] = list.length; continue; }\n const nums = list.map((r) => r[m.of ?? \"\"]).filter((v): v is number => typeof v === \"number\");\n const sum = nums.reduce((a, b) => a + b, 0);\n out[m.key] = !nums.length ? null : m.op === \"sum\" ? sum : m.op === \"avg\" ? sum / nums.length\n : m.op === \"min\" ? Math.min(...nums) : m.op === \"max\" ? Math.max(...nums) : null;\n }\n return out;\n };\n const row = (kind: string, groups: Json, list: Json[]): Json => ({\n kind, groups, measures: measure(list), row_count: list.length, prior_groups: null, prior_measures: null,\n prior_row_count: null, delta: null, compare: null, distinct_groups: null, labels: {}, says: null, as_of: null,\n });\n const out: Json[] = [];\n if (by.length) {\n const groups = new Map<string, { groups: Json; rows: Json[] }>();\n for (const r of rows) {\n const g: Json = {};\n for (const k of by) { const v = r[k]; g[k] = v === undefined || v === \"\" ? null : v; }\n const key = JSON.stringify(g);\n const hit = groups.get(key) ?? { groups: g, rows: [] };\n hit.rows.push(r);\n groups.set(key, hit);\n }\n const first = measures[0]!.key;\n const answered = [...groups.values()].map((g) => row(\"group\", g.groups, g.rows));\n answered.sort((a, b) => Number((b[\"measures\"] as Json)[first] ?? 0) - Number((a[\"measures\"] as Json)[first] ?? 0));\n out.push(...answered.slice(0, Number(question[\"limit\"] ?? 50)));\n }\n out.push(row(\"total\", {}, rows));\n return out;\n}\n\n/** What `entity_row_write` does: a choice by its word (any case), refused in the door's words otherwise. */\nexport function memoryEntityWrite(e: MemoryEntity, recordId: string, columns: Json): Answer {\n const row = e.rows.find((r) => r[\"id\"] === recordId);\n if (!row) return refuse(`There is no ${e.label} you can open with that id.`, \"02000\");\n const next: Json = {};\n for (const [k, v] of Object.entries(columns ?? {})) {\n const c = e.columns.find((x) => x.api_name === k);\n if (!c) return refuse(`This table has no column called \"${k}\".`);\n if (c.lookup && !c.lookup.replaces) return refuse(`\"${c.name}\" is shown from another table, so it is changed there. Nothing was written.`);\n if (!c.writable) return refuse(`\"${c.name}\" is not changed through this door.`, \"42501\");\n if (c.type === \"choice\" && v !== null && v !== \"\") {\n const word = (c.choices ?? []).find((w) => w === v) ?? (c.choices ?? []).find((w) => w.toLowerCase() === String(v).toLowerCase());\n if (!word) return refuse(`\"${String(v)}\" is not one of the choices of \"${c.name}\".`, \"22023\", \"The columns call lists its choices.\");\n next[k] = word;\n } else next[k] = v === \"\" ? null : v;\n }\n const changed = Object.entries(next).some(([k, v]) => row[k] !== v);\n Object.assign(row, next);\n return ok({ id: recordId, organization_id: row[\"organization_id\"] ?? null, changed, row });\n}\n\n/** The memory doors for entity sources; each answers only an `{ kind: \"entity\" }` it holds. */\nexport function memoryEntityDoors(entities: Map<string, MemoryEntity>) {\n const of = (args: Json) => {\n const src = args[\"p_source\"] as Json | undefined;\n return src && src[\"kind\"] === \"entity\" ? entities.get(String(src[\"token\"])) : undefined;\n };\n return {\n drill_describe: (args: Json): Answer | null => {\n const e = of(args);\n return e ? ok(memoryEntityDescribe(e)) : null;\n },\n drill_ask: (args: Json): Answer | null => {\n const e = of(args);\n return e ? ok(memoryEntityAsk(e, (args[\"p_question\"] as Json | undefined) ?? {})) : null;\n },\n drill_rows: (args: Json): Answer | null => {\n const e = of(args);\n return e ? ok(memoryEntityRows(e, (args[\"p_question\"] as Json | undefined) ?? {})) : null;\n },\n entity_row_write: (args: Json): Answer | null => {\n const e = entities.get(String(args[\"p_token\"] ?? \"\"));\n if (!e) return null;\n return memoryEntityWrite(e, String(args[\"p_record_id\"] ?? \"\"), (args[\"p_columns\"] as Json | undefined) ?? {});\n },\n };\n}\n","// src/templates/payloads.ts — @ai-matrx/records (templates)\n//\n// SPEC → DOOR PAYLOADS: the pure translation of a template spec into the arguments each store door\n// takes. The plan (./plan.ts) and the validator (./validate.ts) compile from these; the installed\n// path is the store's own one-call door, custom.template_install (lane TEMPLATES).\n//\n// The interim browser installer that walked these doors one by one (installTemplate,\n// archiveTemplateInstall, resumeArchive) was retired onto the template family (lane TEMPLATES,\n// RETIRE-1, 2026-10-04); what it shared with the plan lives on here.\n\nimport type {\n TemplateAgent,\n TemplateBooking,\n TemplateDashboard,\n TemplateDocument,\n TemplateField,\n TemplateForm,\n TemplateRowAction,\n TemplateSpec,\n TemplateAutomation,\n TemplateChecklist,\n TemplateDigest,\n TemplateDimensions,\n TemplateDrillDown,\n TemplateNotification,\n TemplatePortal,\n TemplateStageRules,\n TemplateTable,\n TemplateView,\n} from \"./types\";\n\ntype Uuid = string;\n\n/**\n * Who is writing, said on every record write: the person signed in. The store lifts `_actor` out\n * before storage (an envelope key, like `_op_id`).\n */\nconst ACTOR = \"user\";\n\n/** The binding a host writes onto the copied agent's variable (the kit `merge_field` shape). */\nexport interface TemplateAgentBinding {\n variable: string;\n tableToken: string;\n tableId: Uuid;\n describes: string;\n}\n\nexport interface TemplateAgentCopyRequest {\n organizationId: Uuid;\n platformAgentId: string;\n platformAgent: string;\n name: string;\n bindings: TemplateAgentBinding[];\n /**\n * The host calls this the moment the fork returns the new agent's id, BEFORE naming or binding\n * it, so a failure after the fork never loses the id: the footprint keeps it either way.\n */\n onCreated?: (agentId: Uuid) => void;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pure translation: spec → door payloads (exported so the suite pins each shape)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Columns the store works out on read: never in the shells, never seeded, declared after rows. */\nconst COMPUTED = new Set([\"lookup\", \"rollup\", \"formula\"]);\n/**\n * A date WITH a time (\"@today-3d 09:30\"), declared as `format: \"datetime\"`. custom.table_from_example\n * forwards no `kind`, and the store makes every datetime it is not told about a whole-day date — a\n * calendar of all-day blocks. These columns are declared through field_declare with kind datetime.\n */\nexport const isTimedField = (f: TemplateField): boolean => f.parityType === \"datetime\" && f.format === \"datetime\";\n\n/**\n * A column table_from_example cannot make as declared, so the installer declares it itself through\n * custom.field_declare, before any row: a date WITH a time (the door forwards no `kind`) and any\n * column with a `default` (the door forwards no default, and a form that does not ask a required\n * column relies on it — \"Patient status\" starts as New).\n */\nexport const isSelfDeclaredField = (f: TemplateField): boolean =>\n f.parityType !== \"relation\" &&\n !COMPUTED.has(f.parityType) &&\n (isTimedField(f) || f.default !== undefined || f.parityType === \"entity_reference\");\n/** A coloured choice list, kept the way the grid reads it: display_format.options.choices. */\nexport function choiceDisplayFormat(field: TemplateField): { id: string; options: { choices: Array<{ value: string; color: string }> } } | undefined {\n if (!field.choices?.length || !field.choiceColors) return undefined;\n return {\n id: field.parityType === \"multi_select\" ? \"multi_choice\" : \"choice\",\n options: {\n choices: field.choices\n .filter((c) => field.choiceColors?.[c])\n .map((c) => ({ value: c, color: field.choiceColors![c]! })),\n },\n };\n}\n\n/**\n * `custom.table_from_example`'s `p_example` for ONE table: its own columns (coloured choices\n * included), no relation columns and no rows. One table per call, because the person's\n * statement ceiling is 8 s and the door costs ~80 ms a column (measured on the clone,\n * 2026-10-02: this template's six tables, 63 columns and 106 rows in one call took 12.8 s).\n * Relations, derived columns and rows follow through their own doors, each call small.\n */\n/**\n * LANE 10 FD — THE TABLES A TEMPLATE MARKS FOUNDATION, from its ONE source: `spec.foundation` (R13),\n * the day-one tables it lists with what each is kept for. The main table (`tables[0]`, the day-to-day\n * work) is never one, even if a list names it (the validator refuses that list too). Both installers\n * read this through `tableShellPayload`: the table is MADE marked, in the table step itself\n * (`custom.table_from_example` writes `foundation: true` into its document), so the browser install\n * and the gallery's server install (`plan.ts` → `custom.template_install`) mark the same tables.\n */\nexport function foundationTokens(spec: Partial<Pick<TemplateSpec, \"foundation\" | \"tables\">>): Set<string> {\n const main = spec.tables?.[0]?.token;\n return new Set((spec.foundation ?? []).map((f) => f.table).filter((token) => token && token !== main));\n}\n\nexport function tableShellPayload(\n spec: Pick<TemplateSpec, \"business\"> & Partial<Pick<TemplateSpec, \"foundation\" | \"tables\">>,\n t: TemplateTable,\n): Record<string, unknown> {\n return {\n business: spec.business.name,\n tables: [\n {\n token: t.token,\n ...(foundationTokens(spec).has(t.token) ? { foundation: true } : {}),\n name: t.name,\n labelSingular: t.labelSingular,\n labelPlural: t.labelPlural,\n type: t.type,\n display: t.display,\n weight: t.weight,\n ordered: t.ordered,\n titleField: t.titleField,\n describes: t.describes,\n fields: t.fields\n .filter((f) => !COMPUTED.has(f.parityType) && f.parityType !== \"relation\" && !isSelfDeclaredField(f))\n .map((f) => {\n const displayFormat = choiceDisplayFormat(f);\n return {\n key: f.key,\n label: f.label,\n parityType: f.parityType,\n multi: f.multi,\n dated: f.dated,\n required: f.required,\n unit: f.unit ?? undefined,\n rules: f.rules,\n choices: f.choices,\n source: f.source,\n computeOn: f.computeOn,\n sensitivity: f.sensitivity,\n contextPolicy: f.contextPolicy,\n ...(displayFormat ? { displayFormat } : {}),\n };\n }),\n rows: [],\n },\n ],\n };\n}\n\n/** `custom.table_from_example`'s `p_example` for EVERY table at once: columns and relations, no rows. */\nexport function shellsPayload(\n spec: Pick<TemplateSpec, \"business\">,\n tables: TemplateTable[],\n deferred: Map<string, Set<string>> = deferredRelations(tables),\n): Record<string, unknown> {\n // A relation that points BACK (a circle, or at its own table) is left out: table_from_example\n // refuses a circle of tables (\"Make one side of the circle optional\"), and the installer\n // declares those columns itself once every table exists (deferredRelationSteps).\n return {\n business: spec.business.name,\n tables: tables.map((t) => {\n const one = (tableShellPayload(spec, t)[\"tables\"] as Array<Record<string, unknown>>)[0]!;\n const relations = t.fields\n .filter((f) => f.parityType === \"relation\" && f.relationTarget && !deferred.get(t.token)?.has(f.key))\n .map((f) => ({\n key: f.key,\n label: f.label,\n parityType: \"relation\",\n relationTarget: f.relationTarget,\n multi: f.multi,\n relationMax: f.relationMax,\n required: f.required,\n sensitivity: f.sensitivity,\n contextPolicy: f.contextPolicy,\n }));\n return { ...one, fields: [...(one[\"fields\"] as unknown[]), ...relations] };\n }),\n };\n}\n\n/** `custom.field_declare`'s spec for one date-and-time column. */\nexport function timedFieldSpec(field: TemplateField): Record<string, unknown> {\n return {\n key: field.key,\n label: field.label,\n type: \"datetime\",\n kind: \"datetime\",\n ...(field.required ? { required: true } : {}),\n ...(field.rules ? { rules: field.rules } : {}),\n sensitivity: field.sensitivity,\n context_policy: field.contextPolicy,\n };\n}\n\n/**\n * `custom.field_declare`'s spec for one self-declared column (isSelfDeclaredField): every declared\n * key, its coloured choices, its kind for a date-and-time, and its default.\n */\nexport function selfDeclaredFieldSpec(field: TemplateField): Record<string, unknown> {\n if (isTimedField(field)) return { ...timedFieldSpec(field), ...(field.default !== undefined ? { default: field.default } : {}) };\n // An entity reference (S4) names the platform kinds it may point at; table_from_example forwards\n // no allowed_types, and the store refuses one that names none.\n const allowed = field.parityType === \"entity_reference\" ? { allowed_types: field.allowedTypes ?? [] } : {};\n const displayFormat = choiceDisplayFormat(field);\n return {\n key: field.key,\n label: field.label,\n type: field.parityType,\n ...(field.multi ? { multi: true } : {}),\n ...(field.required ? { required: true } : {}),\n ...(field.unit ? { unit: field.unit } : {}),\n ...(field.rules ? { rules: field.rules } : {}),\n ...(field.choices ? { options: field.choices } : {}),\n ...(displayFormat ? { display_format: displayFormat } : {}),\n ...(field.default !== undefined ? { default: field.default } : {}),\n ...allowed,\n sensitivity: field.sensitivity,\n context_policy: field.contextPolicy,\n };\n}\n\n/** `custom.field_declare`'s spec for one relation column, its target already made. */\nexport function relationFieldSpec(field: TemplateField, targetTableId: Uuid): Record<string, unknown> {\n return {\n key: field.key,\n label: field.label,\n type: \"relation\",\n relation_target: targetTableId,\n ...(field.multi ? { multi: true } : {}),\n ...(field.relationMax ? { relation_max: field.relationMax } : {}),\n ...(field.required ? { required: true } : {}),\n sensitivity: field.sensitivity,\n context_policy: field.contextPolicy,\n };\n}\n\n/** Tables in levels their rows can be written in: every table after the tables it points at. */\nexport function rowLevels(tables: TemplateTable[]): TemplateTable[][] {\n const done = new Set<string>();\n const levels: TemplateTable[][] = [];\n let left = [...tables];\n while (left.length) {\n let ready = left.filter((t) =>\n t.fields.every((f) => f.parityType !== \"relation\" || !f.relationTarget || f.relationTarget === t.token || done.has(f.relationTarget)),\n );\n // Tables that point at each other in a circle: none can go first, so ONE goes first on its own\n // (the first whose waiting links are optional), and its links to tables not yet written are set after every\n // row exists (deferredRelations / relationPatches). One table breaks the circle; the rest wait.\n if (!ready.length) {\n // Break the circle at a table whose links to unwritten tables are all OPTIONAL: a required\n // link cannot wait for a later patch (the row would be refused \"Client is required\").\n const optionalOnly = left.find((t) =>\n t.fields.every(\n (f) => f.parityType !== \"relation\" || !f.relationTarget || f.relationTarget === t.token || done.has(f.relationTarget) || !f.required,\n ),\n );\n ready = [optionalOnly ?? left[0]!];\n }\n for (const t of ready) done.add(t.token);\n levels.push(ready);\n left = left.filter((t) => !done.has(t.token));\n }\n return levels;\n}\n\n/**\n * The relation columns whose values cannot travel WITH their row: a link to the table's own rows,\n * or to a table in the same or a later row level (a circle). Those rows are written without them,\n * and `relationPatches` sets them once every row exists. table token → field keys.\n */\nexport function deferredRelations(tables: TemplateTable[]): Map<string, Set<string>> {\n const levelOf = new Map<string, number>();\n rowLevels(tables).forEach((level, i) => level.forEach((t) => levelOf.set(t.token, i)));\n const out = new Map<string, Set<string>>();\n for (const t of tables) {\n const mine = levelOf.get(t.token) ?? 0;\n for (const f of t.fields) {\n if (f.parityType !== \"relation\" || !f.relationTarget) continue;\n if (f.relationTarget === t.token || (levelOf.get(f.relationTarget) ?? -1) >= mine) {\n out.set(t.token, new Set([...(out.get(t.token) ?? []), f.key]));\n }\n }\n }\n return out;\n}\n\n/** The relation columns `deferredRelations` holds back, with their tables, in template order. */\nexport function deferredRelationFields(tables: TemplateTable[], deferred: Map<string, Set<string>>): Array<{ table: TemplateTable; f: TemplateField }> {\n return tables.flatMap((table) => table.fields.filter((f) => f.parityType === \"relation\" && deferred.get(table.token)?.has(f.key)).map((f) => ({ table, f })));\n}\n\n/**\n * A deferred link that is REQUIRED: its rows would be refused before the link is set. Said before\n * install, the store's own way (\"make one side of the circle optional\").\n */\nexport function requiredCircleProblem(tables: TemplateTable[], deferred: Map<string, Set<string>>): string | null {\n for (const { table, f } of deferredRelationFields(tables, deferred)) {\n if (f.required && f.relationTarget !== table.token) {\n return `\"${table.name}\" and \"${tables.find((t) => t.token === f.relationTarget)?.name ?? f.relationTarget}\" point at each other and every link in the circle is required (\"${f.label}\"), so no table's rows can be written first. Make one side of the circle optional.`;\n }\n }\n return null;\n}\n\n/**\n * The deferred links of one table as `custom.record_change_many` changes:\n * [{op: \"update\", record_id, patch: {field: id | ids}}], one per row that has any.\n */\nexport function relationPatches(table: TemplateTable, ids: Map<string, Uuid>, deferred: Set<string> | undefined): Record<string, unknown>[] {\n if (!deferred?.size) return [];\n const rel = new Map(table.fields.filter((f) => deferred.has(f.key)).map((f) => [f.key, f.relationTarget!]));\n const out: Record<string, unknown>[] = [];\n for (const r of table.rows) {\n const patch: Record<string, unknown> = {};\n for (const [key, target] of rel) {\n const v = r.values?.[key];\n if (v === null || v === undefined) continue;\n const idOf = (k: unknown) => {\n const id = ids.get(`${target}.${String(k)}`);\n if (!id) throw new Error(`A row points at \"${String(k)}\" in \"${target}\", which the template does not have.`);\n return id;\n };\n patch[key] = Array.isArray(v) ? v.map(idOf) : idOf(v);\n }\n if (Object.keys(patch).length) out.push({ op: \"update\", record_id: ids.get(`${table.token}.${r.key}`), patch: { ...patch, _actor: ACTOR } });\n }\n return out;\n}\n\n/**\n * One table's rows as `custom.record_write_many` takes them, with ids minted here so every\n * relation value (a row key in the file) is already a record id. Derived columns carry no value.\n */\nexport function rowsFor(\n table: TemplateTable,\n ids: Map<string, Uuid>,\n deferred?: Set<string>,\n): { rows: Record<string, unknown>[]; ids: Uuid[] } {\n const relation = new Map(table.fields.filter((f) => f.parityType === \"relation\").map((f) => [f.key, f]));\n const derived = new Set(table.fields.filter((f) => COMPUTED.has(f.parityType)).map((f) => f.key));\n const idOf = (target: string, key: unknown): Uuid => {\n const id = ids.get(`${target}.${String(key)}`);\n if (!id) throw new Error(`A row points at \"${String(key)}\" in \"${target}\", which the template does not have.`);\n return id;\n };\n const rows = table.rows.map((r) => {\n const values: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(r.values ?? {})) {\n if (derived.has(key) || deferred?.has(key) || value === null || value === undefined) continue;\n const rel = relation.get(key);\n if (!rel?.relationTarget) {\n values[key] = value;\n continue;\n }\n values[key] = Array.isArray(value) ? value.map((v) => idOf(rel.relationTarget!, v)) : idOf(rel.relationTarget, value);\n }\n values[\"_actor\"] = ACTOR;\n return values;\n });\n return { rows, ids: table.rows.map((r) => ids.get(`${table.token}.${r.key}`)!) };\n}\n\n/** `custom.field_declare`'s spec for one lookup or rollup. */\nexport function derivedFieldSpec(field: TemplateField): Record<string, unknown> {\n const base = {\n key: field.key,\n label: field.label,\n type: field.parityType,\n via: field.via,\n sensitivity: field.sensitivity,\n context_policy: field.contextPolicy,\n ...(field.unit ? { unit: field.unit } : {}),\n };\n return field.parityType === \"rollup\"\n ? { ...base, agg: field.agg, of: field.pick, ...(field.filter ? { filter: field.filter } : {}) }\n : { ...base, pick: field.pick };\n}\n\n/** `custom.view_declare`'s spec. */\nexport function viewSpec(view: TemplateView, fieldIds: Record<string, string> = {}): Record<string, unknown> {\n const definition: Record<string, unknown> = { layout: view.kind };\n const where = anyOfWhere(view.anyOf, fieldIds);\n if (where) definition[\"where\"] = where;\n if (view.sorts?.length) definition[\"sorts\"] = view.sorts;\n if (view.isDefault) definition[\"is_default\"] = true;\n if (view.hiddenFields?.length) definition[\"presentation\"] = { hiddenFields: view.hiddenFields };\n switch (view.kind) {\n case \"kanban\":\n definition[\"group_field\"] = view.groupBy;\n if (view.swimlaneBy) definition[\"swimlane_field\"] = view.swimlaneBy;\n if (view.measure) definition[\"measure\"] = view.measure;\n break;\n case \"calendar\":\n definition[\"date_field\"] = view.dateField;\n break;\n case \"gallery\":\n definition[\"image_field\"] = view.coverField;\n break;\n case \"grid\":\n if (view.groupBy) {\n definition[\"presentation\"] = { ...((definition[\"presentation\"] as object) ?? {}), grouping: { field: view.groupBy } };\n }\n break;\n case \"timeline\":\n // The store keeps these keys (lane 10 VK); validateTemplate still holds a timeline template\n // as waiting until records-ui draws the layout (OWED_BY \"view.timeline\").\n definition[\"start_field\"] = view.startField;\n definition[\"end_field\"] = view.endField;\n if (view.groupBy) definition[\"group_field\"] = view.groupBy;\n break;\n }\n return { name: view.name, definition, ...(view.filters ? { filters: view.filters } : {}) };\n}\n\n/**\n * A view's any-of conditions as the store's Rule expression (S2-PRIME, Fields by id):\n * {op: \"and\", args: [{op: \"or\", args: [{op: \"eq\", args: [{field: <id>}, {const: v}]}, …]}, …]}.\n * A key with no id is a template error said by name, never a silently dropped condition.\n */\nexport function anyOfWhere(anyOf: Record<string, string[]> | undefined, fieldIds: Record<string, string>): Record<string, unknown> | undefined {\n const entries = Object.entries(anyOf ?? {}).filter(([, vals]) => vals.length);\n if (!entries.length) return undefined;\n return {\n op: \"and\",\n args: entries.map(([key, vals]) => {\n const id = fieldIds[key];\n if (!id) throw new Error(`The view filters on \"${key}\", which the install has no field id for.`);\n return { op: \"or\", args: vals.map((v) => ({ op: \"eq\", args: [{ field: id }, { const: v }] })) };\n }),\n };\n}\n\n/** `custom.field_declare`'s spec for a formula column: the store parses `formula_text` and computes it on read. */\nexport function formulaFieldSpec(field: TemplateField): Record<string, unknown> {\n return {\n key: field.key,\n label: field.label,\n type: \"formula\",\n formula_text: field.formula,\n ...(field.unit ? { unit: field.unit } : {}),\n sensitivity: field.sensitivity,\n context_policy: field.contextPolicy,\n };\n}\n\n/**\n * A table's formula columns in an order the store can parse: a formula that reads another formula\n * (by its label in braces) comes after it. A cycle keeps template order (the store refuses it by name).\n */\nexport function formulaOrder(table: TemplateTable): TemplateField[] {\n const formulas = table.fields.filter((f) => f.parityType === \"formula\");\n const out: TemplateField[] = [];\n const left = [...formulas];\n while (left.length) {\n const i = left.findIndex((f) => !left.some((g) => g !== f && (f.formula ?? \"\").includes(`{${g.label}}`)));\n out.push(...left.splice(i < 0 ? 0 : i, 1));\n }\n return out;\n}\n\n/** A form question in the door's words: {field, ask, help, required}. */\nfunction question(q: { fieldKey: string; ask: string; help?: string; required?: boolean }): Record<string, unknown> {\n return { field: q.fieldKey, ask: q.ask, ...(q.help ? { help: q.help } : {}), ...(q.required ? { required: true } : {}) };\n}\n\nexport function formArgs(org: Uuid, tableId: Uuid, form: TemplateForm): Record<string, unknown> {\n return {\n p_organization_id: org,\n p_table_id: tableId,\n p_title: form.name,\n p_questions: form.fields.map(question),\n p_presentation: { submit_label: form.submitLabel, thank_you: { title: \"Thank you\", body: form.confirmation } },\n p_submission_cap: null,\n p_quarantine_rule_id: null,\n p_notify_rule_id: null,\n p_form_id: null,\n p_slug: null,\n };\n}\n\nexport function bookingArgs(org: Uuid, tableId: Uuid, booking: TemplateBooking): Record<string, unknown> {\n const a = booking.availability;\n return {\n p_organization_id: org,\n p_table_id: tableId,\n p_title: booking.title,\n p_questions: booking.questions.map(question),\n p_availability: {\n timezone: a.timezone,\n slot_minutes: a.slotMinutes,\n buffer_minutes: a.bufferMinutes,\n lead_minutes: a.leadMinutes,\n max_per_day: a.maxPerDay,\n days: a.days,\n windows: a.windows,\n },\n p_presentation: {},\n p_submission_cap: null,\n p_quarantine_rule_id: null,\n p_notify_rule_id: null,\n p_form_id: null,\n p_slug: booking.slug ?? null,\n p_home_id: null,\n };\n}\n\nexport function dashboardBlocks(dashboard: TemplateDashboard, tables: Record<string, Uuid>): Record<string, unknown>[] {\n return dashboard.blocks.map((b) => ({\n title: b.title,\n kind: b.kind,\n ...(b.table && b.table !== dashboard.table ? { table_id: tables[b.table] } : {}),\n ...(b.groupBy ? { group_by: b.groupBy } : {}),\n ...(b.measures ? { measures: b.measures } : {}),\n ...(b.bucket ? { bucket: b.bucket } : {}),\n ...(b.filter ? { filter: b.filter } : {}),\n ...(b.span ? { span: b.span } : {}),\n ...(b.stateKey ? { state_key: b.stateKey } : {}),\n ...(b.days ? { days: b.days } : {}),\n }));\n}\n\nexport function stageRulesSpec(rules: TemplateStageRules): Record<string, unknown> {\n return {\n stage_field: { key: rules.stageField },\n ...(rules.transitions ? { transitions: rules.transitions } : {}),\n ...(rules.requires ? { requires: rules.requires } : {}),\n ...(rules.limits ? { limits: rules.limits } : {}),\n ...(rules.movesMessage ? { moves_message: rules.movesMessage } : {}),\n };\n}\n\n/**\n * A document body in the store's token form. `{{field_key}}` → `{{field:<id>}}` (REC-68: a token\n * names a Field by id, so a rename never breaks it); `{{business}}` → the business's own name.\n * A key with no field is left as written, and the door refuses it by name.\n */\nexport function documentBody(doc: TemplateDocument, fieldIds: Record<string, Uuid>, businessName: string): string {\n return doc.body.replace(/\\{\\{\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\s*\\}\\}/g, (whole, key: string) => {\n if (key === \"business\") return businessName;\n const id = fieldIds[key];\n return id ? `{{field:${id}}}` : whole;\n });\n}\n\nexport function rowActionList(actions: TemplateRowAction[], fieldIds: Record<string, Uuid>): Record<string, unknown>[] {\n return actions.map((a) =>\n a.actionKind === \"agent\"\n ? { name: a.name, kind: \"agent\", prompt: a.prompt, ...(a.color ? { color: a.color } : {}), confirm: !!a.confirm }\n : {\n name: a.name,\n kind: \"update\",\n ...(a.color ? { color: a.color } : {}),\n confirm: !!a.confirm,\n steps: (a.steps ?? []).map((s) =>\n s.set === \"value\" ? { field: fieldIds[s.field] ?? s.field, set: \"value\", value: s.value } : { field: fieldIds[s.field] ?? s.field, set: \"clear\" },\n ),\n },\n );\n}\n\nexport function agentCopyRequest(org: Uuid, agent: TemplateAgent, tables: Record<string, Uuid>): TemplateAgentCopyRequest {\n return {\n organizationId: org,\n platformAgentId: agent.platformAgent.id,\n platformAgent: agent.platformAgent.name,\n name: agent.name,\n bindings: agent.variables.map((v) => ({ variable: v.name, tableToken: v.table, tableId: tables[v.table] ?? \"\", describes: v.describes })),\n };\n}\n\n/** The choice field of `table` that holds `stage` as one of its choices. */\nexport function stageFieldOf(tables: TemplateTable[], table: string, stage: string | undefined): string | null {\n if (!stage) return null;\n const t = tables.find((x) => x.token === table);\n return t?.fields.find((f) => (f.parityType === \"select\" || f.parityType === \"multi_select\") && f.choices?.includes(stage))?.key ?? null;\n}\n\n/**\n * A drill-down extra as the store keeps one. The drill PATH is the table's own (declared through\n * `table_dimensions_set` with the template's Dimensions); there is no door that declares a drill\n * entry point for a custom table (platform.drill_* serves platform-declared definitions), so the\n * entry point is a dashboard whose one chart groups by the path's first level — clicking a bar is\n * the drill through custom.drill_resolve. `custom.dashboard_declare`'s name and blocks.\n */\nexport function drillDownDashboard(drill: TemplateDrillDown, dimensions: TemplateDimensions[]): { name: string; blocks: Record<string, unknown>[] } {\n const path = dimensions.find((d) => d.table === drill.table)?.paths?.find((p) => p.key === drill.path);\n if (!path?.levels.length) throw new Error(`The drill-down \"${drill.name}\" names the path \"${drill.path}\", which the Dimensions of \"${drill.table}\" do not declare.`);\n const [key, grain] = path.levels[0]!.split(\":\");\n const block: Record<string, unknown> = { title: drill.name, kind: grain ? \"line\" : \"bar\", measures: [{ op: \"count\" }] };\n if (grain) block[\"bucket\"] = { key, by: grain };\n else block[\"group_by\"] = [key];\n return { name: drill.name, blocks: [block] };\n}\n\n/** A digest as `custom.subscription_declare` takes it: the saved view it sends, how often, how. */\nexport function digestSpec(digest: TemplateDigest, viewId: string): Record<string, unknown> {\n return {\n name: digest.name,\n saved_view_id: viewId,\n cadence: digest.cadence,\n ...(digest.schedule ? { schedule: digest.schedule } : {}),\n channel: digest.channel ?? \"in_app\",\n event_key: \"records.changed\",\n };\n}\n\n/**\n * A checklist as `custom.checklist_declare` takes it (p_spec). Steps that ask for a form or a\n * document name it by the id the install made (`forms`, `documents`: token → id).\n */\nexport function checklistSpec(\n checklist: TemplateChecklist,\n tables: Record<string, string>,\n forms: Record<string, string>,\n documents: Record<string, string>,\n): Record<string, unknown> {\n const trigger = checklist.trigger ?? { kind: \"manual\" as const };\n return {\n name: checklist.name,\n about_table_id: tables[checklist.aboutTable],\n roles: (checklist.roles ?? []).map((r) => ({ role: r.role, ...(r.label ? { label: r.label } : {}) })),\n steps: checklist.steps.map((st) => {\n const req = st.requires;\n const requires =\n !req ? undefined\n : req.kind === \"form\" ? { kind: \"form\", form_id: forms[req.form] }\n : req.kind === \"document\" ? { kind: \"document\", template_id: documents[req.document] }\n : req;\n return {\n ref: st.ref,\n title: st.title,\n ...(st.role ? { role: st.role } : {}),\n ...(st.dueDays !== undefined ? { due_days: st.dueDays } : {}),\n ...(st.dependsOn?.length ? { depends_on: st.dependsOn } : {}),\n ...(requires ? { requires } : {}),\n };\n }),\n trigger:\n trigger.kind === \"manual\" ? { kind: \"manual\" }\n : trigger.kind === \"record_created\" ? { kind: \"record_created\", table_id: tables[trigger.table] }\n : { kind: \"status_reached\", table_id: tables[trigger.table], status: trigger.status },\n };\n}\n\n/** An automation has no door yet: lane 11 owes it, and the validator holds such a template. */\nexport function automationHeld(a: TemplateAutomation): string {\n return `The automation \"${a.name}\" is held for lane 11: no store door runs automations yet, so a template carrying one is held, never installed without it.`;\n}\n\n/**\n * What custom.booking_declare requires of its table, said BEFORE install: a `slot` column (the door\n * writes the booked time into it on confirm, and adds it as a required text column when missing),\n * and a `status` choice column holding \"booked\" and \"cancelled\". Null when the table has both.\n */\nexport function bookingColumnsProblem(tables: TemplateTable[], booking: TemplateBooking): string | null {\n const t = tables.find((x) => x.token === booking.table);\n if (!t) return `The booking page \"${booking.title}\" takes bookings into \"${booking.table}\", which the template does not have.`;\n const slot = t.fields.find((f) => f.key === \"slot\");\n if (!slot) {\n return `The booking page \"${booking.title}\" writes each booked time into a column keyed \"slot\" on \"${t.name}\", and that table has none. Declare it (a required date-and-time, like \"Visit time\") so the seeded rows carry it; the door would add it after the rows and leave every seeded row missing a required value.`;\n }\n if (!slot.required) return `\"${t.name}\"'s \"slot\" column holds the booked time and the door requires it; declare it required and seed it on every row.`;\n const missing = t.rows.filter((r) => r.values?.[\"slot\"] === undefined || r.values?.[\"slot\"] === null || r.values?.[\"slot\"] === \"\");\n if (missing.length) return `\"${t.name}\" has ${missing.length} seeded row(s) with no \"slot\" (${missing[0]!.key}); the booking page makes it required, so those rows could never be edited.`;\n // custom.booking_declare adds \"Status\" (key status) and \"With\" (key booked_with) when the table lacks those keys;\n // a column already labelled that way under another key makes the door refuse the whole page (T0399).\n for (const [key, label] of [[\"status\", \"Status\"], [\"booked_with\", \"With\"]] as const) {\n if (t.fields.some((f) => f.key === key)) continue;\n const clash = t.fields.find((f) => f.label.trim().toLowerCase() === label.toLowerCase());\n if (clash) return `The booking page adds a \"${label}\" column to \"${t.name}\", which already has one (\"${clash.key}\"). Rename that column, or key it \"${key}\".`;\n }\n const status = t.fields.find((f) => f.key === \"status\");\n const words = new Set((status?.choices ?? []).map((c) => c.toLowerCase()));\n if (status && (!words.has(\"booked\") || !words.has(\"cancelled\"))) {\n return `The booking page writes \"booked\" and \"cancelled\" into \"${t.name}\"'s status, and its choices do not hold both.`;\n }\n return null;\n}\n\n/** A notification as the store keeps one: a saved view of the stage, and an instant subscription. */\nexport function notificationParts(\n n: TemplateNotification,\n stageField: string | null,\n): { view: Record<string, unknown>; subscription: Record<string, unknown> } {\n const filters: Record<string, unknown> = {};\n if (n.when.event === \"stage_entered\" && n.when.stage && stageField) filters[stageField] = n.when.stage;\n return {\n view: { name: n.name, definition: { layout: \"grid\" }, filters },\n subscription: { name: n.name, cadence: \"instant\", channel: n.channel, event_key: \"records.changed\" },\n };\n}\n\n/** `custom.portal_declare`'s arguments: each exposed table names the relation that says \"theirs\". */\nexport function portalArgs(org: Uuid, portal: TemplatePortal, tables: Record<string, Uuid>): Record<string, unknown> {\n return {\n p_organization_id: org,\n p_title: portal.title,\n p_client_table_id: tables[portal.clientTable],\n p_tables: portal.tables.map((t) => ({\n table_id: tables[t.table],\n names_via: t.namesVia,\n visible_fields: t.visibleFields,\n editable_fields: t.editableFields ?? [],\n comments: !!t.comments,\n })),\n p_portal_id: null,\n p_slug: portal.slug ?? null,\n p_sign_in_method: \"magic_link\",\n p_config: null,\n };\n}\n","// src/templates/types.ts — @ai-matrx/records (templates, internal)\n//\n// THE SHAPE OF ONE TEMPLATE: a working business setup that teaches one feature.\n//\n// Lane 8 TEMPLATES (Unified Data System v6, handoff HANDOFF-TEMPLATES.md §5). A template\n// carries a real business (the `UseCase` law: who, what business, what job; realistic,\n// never real people) and everything that makes it installable and teachable: tables and\n// seed rows, relationships, views, forms with question text, Dimensions, extras, one\n// agent with a scripted question, a three-step walk, foundation markings and shared-block\n// references. `toUseCase` (./validate) derives the five singular artefacts a `UseCase`\n// carries (form, pipeline, dashboard question, document, notification) so every existing\n// use-case consumer keeps working; a template never states them twice.\n//\n// EVERY PIECE MAPS 1:1 ONTO A STORE DOOR'S PAYLOAD (bodies read on the clone 2026-10-02),\n// so the installer translates and never invents:\n//\n// tables / rows / relationships → custom.table_from_example\n// sharedBlocks → the block's table, seeded once per organization\n// (SHARED_BLOCKS[block].fields), rows from the template\n// dimensions[] → custom.table_dimensions_set(p_overrides)\n// {dimensions[{key,label,hidden}], measures[{key,label,hidden,op,of}],\n// paths[{key,levels[]}], default{by[],show[]}}\n// views[] → custom.view_declare(p_spec) {name, definition{layout, group_field,\n// swimlane_field, measure, date_field, image_field, sorts, is_default},\n// filters} (keys: custom.view_keys())\n// forms[] → custom.form_declare(p_title, p_questions[{field, ask, help, required}])\n// extras booking → custom.booking_declare(p_title, p_questions, p_availability, p_slug)\n// extras portal → custom.portal_declare(p_title, p_client_table_id,\n// p_tables[{table_id, names_via, visible_fields, editable_fields, comments}])\n// — it OPENS the organization's outside sign-in (footprint records it)\n// extras dashboard → custom.dashboard_declare(p_name, p_blocks[DashboardBlock]); a block may\n// name its own table (custom.dashboard_block_normalize)\n// extras drill_down → a `paths` entry of table_dimensions_set, opened by custom.drill_resolve\n// extras digest → custom.subscription_declare(p_spec{name, saved_view_id, cadence, schedule, channel})\n// extras checklist → custom.checklist_declare(p_spec{name, about_table_id, roles, trigger, steps})\n// extras document → custom.doc_template_save(p_name, p_body) — {{field_key}} becomes\n// {{field:<id>}}, the only token custom.doc_render_body resolves\n// extras notification → custom.rule_declare (a notify rule on the table)\n// extras stage_rules → custom.pipeline_declare(p_spec{stage_field, transitions, requires, who, limits})\n// extras row_action → custom.action_declare(p_actions[RowAction])\n// extras automation → lane 11's door (not landed: `requires` holds it)\n// walk import step → custom.io_import_begin(p_format 'csv', p_source_name, p_source_columns,\n// p_policy{on_duplicate 'update', unmapped 'ignore'}, p_dedupe_key) +\n// custom.io_import_rows(p_rows, p_mapping) + custom.io_import_finish\n// agent → the kit installer's agent-copy path (catalog_entries kit\n// `source_agent_id`), variables bound to table ids\n//\n// The JSON files live under `templates/**` at the PACKAGE ROOT (never `src/`), excluded\n// from the npm tarball and from every entry point: 1,000 files never ship to a browser.\n\nimport type { TemplateConfidential } from \"./confidential\";\nimport type { AggregateBucket, AggregateFilter, AggregateMeasure, AggregateOperation } from \"../aggregate\";\nimport type { DashboardBlockKind } from \"../dashboard\";\nimport type { SubscriptionCadence } from \"../subscription\";\nimport type {\n NotificationChannel,\n UseCase,\n UseCaseField,\n UseCaseForm,\n UseCaseFormField,\n UseCaseNotificationTrigger,\n UseCaseProvenance,\n UseCaseRow,\n UseCaseTable,\n} from \"../use-cases/types\";\n\n/** The schema version of this file format. Bumped only when the SHAPE changes. */\nexport const TEMPLATE_SPEC_VERSION = 1 as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Relative dates — seed dates are written relative to install day\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * THE RELATIVE-DATE GRAMMAR. A seed date is written relative to the day the template is\n * installed, so a calendar installed in March shows this week's work, not last year's:\n *\n * ANCHOR @today the install day\n * @mon … @sun that weekday of the install week (weeks start Monday)\n * @last-mon … @next-sun that weekday of the week before / after\n * OFFSET +3d -2w +1m -1y days / weeks / months / years (N ≤ 9999)\n * +2b -5b BUSINESS days (Monday–Friday): never lands on a weekend\n * SNAP ~b if the result is a Saturday or Sunday, move to Monday\n * TIME \" 09:30\" a moment that day, 24-hour local time in the business's\n * zone, written out with its offset\n *\n * \"@today-3b 08:30\" \"@today~b 10:00\" \"@next-tue\" \"@mon+1d 14:00\"\n *\n * Closed: anything else in a date field is an absolute date, which only a field flagged\n * `absoluteDates` (a date of birth) may hold. `resolveRelativeDates` (./validate) turns\n * every token into the store's own date or moment text.\n *\n * Groups: 1 anchor, 2 sign, 3 count, 4 unit, 5 snap, 6 hour, 7 minute.\n */\nexport const RELATIVE_DATE =\n /^@(today|(?:last-|next-)?(?:mon|tue|wed|thu|fri|sat|sun))(?:([+-])(\\d{1,4})([dwmyb]))?(~b)?(?: ([01]\\d|2[0-3]):([0-5]\\d))?$/;\n\n/** The day the validator resolves relative dates against, so every check is deterministic. */\nexport const TEMPLATE_REFERENCE_DATE = \"2026-10-05\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The closed vocabularies of the catalogue\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** The 20 industry groups of the catalogue (handoff §5 table). The quota per group is in CATALOGUE_QUOTAS. */\nexport const INDUSTRY_GROUPS = [\n \"healthcare\",\n \"legal_professional\",\n \"construction_trades\",\n \"real_estate_property\",\n \"hospitality_food\",\n \"agencies_creative\",\n \"field_home_services\",\n \"retail_ecommerce\",\n \"manufacturing_logistics\",\n \"education\",\n \"nonprofit_community\",\n \"software_it\",\n \"fitness_beauty_wellness\",\n \"media_creators\",\n \"staffing_hr_recruiting\",\n \"personal_family\",\n \"events_weddings\",\n \"automotive\",\n \"agriculture_environment\",\n \"cross_industry\",\n] as const;\nexport type IndustryGroup = (typeof INDUSTRY_GROUPS)[number];\n\n/** The first 1,000 rows' quota per group (sums to 1,000). G3 enforces it at 1,000 and proportionally before. */\nexport const CATALOGUE_QUOTAS: Readonly<Record<IndustryGroup, number>> = {\n healthcare: 90,\n legal_professional: 70,\n construction_trades: 70,\n real_estate_property: 60,\n hospitality_food: 60,\n agencies_creative: 60,\n field_home_services: 50,\n retail_ecommerce: 50,\n manufacturing_logistics: 50,\n education: 50,\n nonprofit_community: 50,\n software_it: 50,\n fitness_beauty_wellness: 50,\n media_creators: 40,\n staffing_hr_recruiting: 40,\n personal_family: 40,\n events_weddings: 30,\n automotive: 30,\n agriculture_environment: 30,\n cross_industry: 30,\n};\n\n/** The 12 jobs a template does for a business. */\nexport const TEMPLATE_JOBS = [\n \"intake\",\n \"scheduling\",\n \"crm_pipeline\",\n \"work_orders\",\n \"inventory\",\n \"billing\",\n \"team_hr\",\n \"projects\",\n \"content\",\n \"compliance_quality\",\n \"customer_service\",\n \"reporting\",\n] as const;\nexport type TemplateJob = (typeof TEMPLATE_JOBS)[number];\n\n/** The 16 features a template can teach. Each is taught by at least 40 of the first 1,000. */\nexport const TEACHES_FEATURES = [\n \"relations_rollups\",\n \"dimensions\",\n \"kanban\",\n \"calendar\",\n \"timeline\",\n \"gallery\",\n \"forms\",\n \"bookings\",\n \"portals\",\n \"dashboards\",\n \"drill_down\",\n \"agents\",\n \"field_governance\",\n \"import_upsert\",\n \"checklists\",\n \"documents_esign\",\n] as const;\nexport type TeachesFeature = (typeof TEACHES_FEATURES)[number];\n\n/**\n * The five places we beat the champions (ADV-P §4). Each is shown in at least 100 of the first 1,000.\n *\n * S1 — governed columns: every column says who sees it and whether AI may read it.\n * S2 — agents inside the data: an agent works on the table's own records.\n * S3 — every front door on one table: form, booking, portal, digest, webhook all land in one table.\n * S4 — a column can point at anything on the platform (entity reference).\n * S5 — imports and edits cannot lose data: an upsert import that updates and adds, or\n * archive → Trash → restore, shown in the walk.\n */\nexport const STRENGTHS = [\"S1\", \"S2\", \"S3\", \"S4\", \"S5\"] as const;\nexport type Strength = (typeof STRENGTHS)[number];\n\n/** Who installs it: a business, or a person for their own life. */\nexport const TEMPLATE_AUDIENCES = [\"organization\", \"individual\"] as const;\nexport type TemplateAudience = (typeof TEMPLATE_AUDIENCES)[number];\n\n/**\n * THE CAPABILITY WORDS a template may `require`. Closed: a word not here is a typo, and a\n * word the template does not use is refused. Whether each is PROVIDED today is derived by\n * `capabilityStatus` (./validate) from the store's registry and the records-ui layouts, so a\n * word flips to provided the day its lane lands, with no edit to this list.\n */\nexport const CAPABILITY_WORDS = [\n // views (custom.view_keys() layouts; records-ui VIEW_LAYOUTS)\n \"view.grid\",\n \"view.kanban\",\n \"view.kanban.swimlanes\",\n \"view.calendar\",\n \"view.calendar.month\",\n \"view.timeline\",\n \"view.gallery\",\n // field kinds (custom.field_kinds() / custom.parity_field_types())\n \"field.select\",\n \"field.multi_select\",\n \"field.datetime\",\n \"field.currency\",\n \"field.percent\",\n \"field.email\",\n \"field.phone\",\n \"field.url\",\n \"field.checkbox\",\n \"field.attachment\",\n \"field.member\",\n \"field.lookup\",\n \"field.rollup\",\n \"field.formula\",\n \"field.entity_reference\",\n \"field.signature\",\n \"field.rating\",\n // presentation and seed\n \"choice.colors\",\n \"seed.attachments\",\n // surfaces and machinery (store doors)\n \"form\",\n \"form.question_text\",\n \"booking\",\n \"portal\",\n \"dashboard\",\n \"dashboard.multi_table\",\n \"drill_down\",\n \"dimensions\",\n \"digest\",\n \"checklist\",\n \"document\",\n \"document.esign\",\n \"notification\",\n \"stage_rules\",\n \"row_action\",\n \"import.upsert\",\n \"archive.restore\",\n \"agent\",\n \"automation\",\n] as const;\nexport type CapabilityWord = (typeof CAPABILITY_WORDS)[number];\n\n/**\n * The platform kinds an entity_reference column may point at — custom.entity_reference_kinds(),\n * read on the clone 2026-10-02 (the TEMPLATES lane refreshes it the way it refreshes the agent\n * snapshot). A word outside it is refused: the store would refuse the column.\n */\nexport const ENTITY_REFERENCE_KINDS = [\n \"agent\", \"agent_shortcut\", \"agent_template\", \"ai_api\", \"ai_endpoint\", \"ai_model\", \"ai_provider\",\n \"ai_setting\", \"anon_form\", \"app\", \"assessment\", \"canvas_comment\", \"canvas_item\", \"canvas_score\",\n \"category\", \"code_file\", \"code_folder\", \"code_repository\", \"comparison_set\", \"contact_submission\",\n \"content_ir_kind\", \"content_ir_kind_instance\", \"context_item\", \"conversation\", \"crm_deal\",\n \"crm_outreach_list\", \"cx_agent_memory\", \"data_store\", \"fc_set\", \"feature_doc\", \"flexible_data\", \"folder\",\n \"game_result\", \"heatmap_save\", \"hr_asset\", \"hr_candidate\", \"hr_careers_portal\", \"hr_checklist_template\",\n \"hr_course\", \"hr_crew\", \"hr_deduction_code\", \"hr_department\", \"hr_earning_code\", \"hr_employee\",\n \"hr_holiday_calendar\", \"hr_interview_kit\", \"hr_job_title\", \"hr_jurisdiction\", \"hr_jurisdiction_rule_class\",\n \"hr_leave_policy\", \"hr_location\", \"hr_pay_group\", \"hr_posting\", \"hr_record_class\", \"hr_requisition\",\n \"hr_schedule\", \"hr_schedule_template\", \"hr_survey\", \"league_membership\", \"learn_doc\", \"mandate\",\n \"marketing_initiative\", \"meet_meeting\", \"message_template\", \"note\", \"note_folder\", \"organization\",\n \"page_extraction_job\", \"party\", \"pc_article\", \"pc_episode\", \"pc_show\", \"pc_studio_run\",\n \"processed_document\", \"project\", \"quiz_session\", \"research_template\", \"research_topic\", \"rulebook\",\n \"sch_task\", \"scope_type\", \"seo_topic\", \"shared_canvas_item\", \"skill\", \"skill_render_definition\",\n \"studio_session\", \"study_goal\", \"study_media\", \"study_plan\", \"study_plan_block\", \"surface\", \"task\",\n \"thread\", \"tool\", \"tool_bundle\", \"transcript\", \"udt_document\", \"user_markdown_sample\", \"voice\", \"war_room\",\n \"wbx_pattern\", \"web_analysis_item\", \"web_brand\", \"web_provider\", \"web_site\", \"workbook\", \"workflow\",\n \"workflow_template\", \"workflow_trigger\", \"working_document\",\n] as const;\n\n/** The colours a choice may wear — the palette `display_format.options.choices[].color` holds (design-system STYLE_COLORS). */\nexport const CHOICE_COLORS = [\"slate\", \"green\", \"amber\", \"red\", \"blue\", \"violet\", \"teal\"] as const;\nexport type ChoiceColor = (typeof CHOICE_COLORS)[number];\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Shared blocks — a seeded table referenced by relation, never copied\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SharedBlockField {\n key: string;\n label: string;\n parityType: UseCaseField[\"parityType\"];\n sensitivity: UseCaseField[\"sensitivity\"];\n contextPolicy: UseCaseField[\"contextPolicy\"];\n required?: boolean;\n /** Labels and keys that mean this field, for the copy check (normalised, lower-case words). */\n sameAs: readonly string[];\n}\n\nexport interface SharedBlock {\n /** The table's token in every organization: one table, shared by every template that uses it. */\n table: string;\n name: string;\n labelSingular: string;\n labelPlural: string;\n titleField: string;\n describes: string;\n fields: readonly SharedBlockField[];\n /** A template table matching this many of the block's fields (by type and meaning) has copied it. */\n copyThreshold: number;\n}\n\n/**\n * THE SHARED BLOCKS. The scope templates carried 26 byte-identical copies of a team-member\n * block (312 of 846 fields). Now the block is ONE seeded table per organization; a template\n * lists the block in `sharedBlocks` with the rows it seeds (its own people), and points its\n * \"assigned to\" columns at the block's table with an ordinary relation field — so the\n * column is filled, and no template declares those fields again.\n */\nexport const SHARED_BLOCKS = {\n team_member: {\n table: \"team_member\",\n name: \"Team\",\n labelSingular: \"Team member\",\n labelPlural: \"Team\",\n titleField: \"full_name\",\n describes: \"The people on the business's own team — who is assigned, who answers, who signs.\",\n fields: [\n { key: \"full_name\", label: \"Name\", parityType: \"text\", sensitivity: \"internal\", contextPolicy: \"include\", required: true, sameAs: [\"name\", \"full name\", \"employee name\", \"staff name\"] },\n { key: \"role\", label: \"Role\", parityType: \"text\", sensitivity: \"internal\", contextPolicy: \"include\", sameAs: [\"role\", \"job title\", \"title\", \"position\"] },\n { key: \"work_email\", label: \"Work email\", parityType: \"email\", sensitivity: \"confidential\", contextPolicy: \"summarize\", sameAs: [\"email\", \"work email\", \"email address\"] },\n { key: \"mobile\", label: \"Mobile\", parityType: \"phone\", sensitivity: \"confidential\", contextPolicy: \"exclude\", sameAs: [\"phone\", \"mobile\", \"work phone\", \"cell\", \"phone number\"] },\n { key: \"start_date\", label: \"Start date\", parityType: \"datetime\", sensitivity: \"internal\", contextPolicy: \"include\", sameAs: [\"start date\", \"hire date\", \"started\", \"date hired\"] },\n ],\n copyThreshold: 3,\n },\n} as const satisfies Record<string, SharedBlock>;\nexport type SharedBlockId = keyof typeof SHARED_BLOCKS;\nexport const SHARED_BLOCK_IDS = Object.keys(SHARED_BLOCKS) as SharedBlockId[];\n\n/** One shared block this template uses, with the rows it seeds into the block's table. */\nexport interface SharedBlockUse {\n block: SharedBlockId;\n /** Keyed by the block's field keys. Relation fields elsewhere point at these row keys. */\n rows: UseCaseRow[];\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Tables and fields\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface TemplateField extends UseCaseField {\n /** Every choice of a select/multi_select wears a colour: choice word → colour. */\n choiceColors?: Record<string, ChoiceColor>;\n /** For an `entity_reference` field (S4): the platform kinds it may point at. */\n allowedTypes?: string[];\n /** For a lookup / rollup: the relation field it reads through. */\n via?: string;\n /** Lookup: the field picked on the far side. Rollup: the field aggregated. */\n pick?: string;\n /** Rollup: the aggregate along the relation. */\n agg?: AggregateOperation;\n /**\n * Rollup: WHICH linked records it adds up — \"sessions booked\", \"unpaid balance\", \"open requests\"\n * per parent. The saved view's own filter grammar, written against the far table: a flat map of\n * far-side column keys (`{ status: \"open\" }`) or a Rule expression over far-side field IDs. The\n * store refuses an unknown column or op at install (custom.field_declare).\n */\n filter?: Record<string, unknown>;\n /**\n * For a `formula` field: the formula text custom.field_declare parses (`formula_text`, through\n * custom.formula_parse) — fields named by LABEL in braces, functions from\n * custom.formula_node_kinds(): `{Total} - {Paid}`, `DATEDIFF({Starts}, {Ends}, 'minutes') / 60`.\n * The store computes it on read; seeds never write it.\n */\n formula?: string;\n /**\n * ELIGIBILITY across tables, on a relation field: the record this field points at must hold a\n * row in `table` (linked back by `relation`) matching `where`, whose `until` date is on or after\n * this row's `onDate` — a shift's staff member holds an unexpired food-handler card on the\n * shift's day. Checked on the seed and on the walk's state after every step.\n */\n eligible?: { table: string; relation: string; where?: Record<string, string>; until: string; onDate: string };\n /**\n * A date field whose values are history, not schedule (a date of birth, a founding\n * date): its seed rows hold absolute dates. Every other date field is written in the\n * relative grammar (RELATIVE_DATE).\n */\n absoluteDates?: boolean;\n /**\n * A schedule date for a weekday-only business: every seed value must resolve to Monday–\n * Friday on EVERY install weekday (write it with business-day offsets \"+2b\" or the \"~b\" snap).\n */\n businessDays?: boolean;\n /** The value a new record gets when nobody gives one — lets a form or an import leave a required field out. */\n default?: unknown;\n /**\n * A public form may ask a confidential / restricted field only when it is the asker's OWN\n * data (a patient's member id on her own intake). Flag it here; never for anyone else's.\n */\n askOfSubject?: boolean;\n /** A parent or guardian answers this on a public form for a minor (youth league, school, pediatrics). */\n askOfGuardian?: boolean;\n /**\n * Required with `absoluteDates`: why these dates are history (\"date of birth\", \"the year\n * the firm was founded\"). A field flagged absolute may never drive a calendar, a timeline,\n * a booking, a digest, a stage rule, the Q6 question or a walk step — those are schedule.\n */\n historicalReason?: string;\n}\n\nexport interface TemplateTable extends UseCaseTable {\n fields: TemplateField[];\n /**\n * REUSE, NEVER DUPLICATE (CHAIR-DESCRIBE-2): this template table IS one the organization already has.\n * The install makes no table for it — `tables.<token>` is the existing table's id from the first step —\n * declares only the fields it lacks (`fields` = the keys it already has), seeds none of its rows, never\n * resets its Dimensions, and links the template's new tables to it. Uninstall archives only what the\n * install added (its new fields, views, forms), never the table.\n */\n bindsTo?: { tableId: string; fields: string[] };\n /**\n * Ordered date pairs that hold on every seed row: [earlier, later]. A side is a field of\n * this table (\"sent_on\") or a field reached through one of its relations (\"patient.date_of_birth\").\n * A table with two or more schedule date fields declares its order here, or says why the\n * dates are independent (`datesIndependent`).\n */\n before?: [string, string][];\n datesIndependent?: string;\n /**\n * A roster of recurring slots (weekly shifts, standing roles): rows may share a title when\n * they differ in a date and in who or what they are for (a relation).\n */\n schedule?: boolean;\n /**\n * Date coherence across relations, declared: on every seed row `earlier` is on or before\n * `later`. A side is a field of this table (\"invoice_date\") or one reached through a relation\n * (\"engagement.start_date\"). `onlyWhen` limits the pair to rows whose field holds one of the\n * values (a report is due only on an Awarded grant). A billing or grants template declares at\n * least one pair that crosses a relation.\n */\n datePairs?: { earlier: string; later: string; onlyWhen?: { field: string; values: string[] } }[];\n /**\n * CROSS-TABLE REALISM, stated once on the CHILD table (the one holding the relation) and\n * enforced on every seed row. A relation whose two sides both carry a schedule date needs a\n * childDates entry; both a status, a statusAgrees entry.\n *\n * childDates: this row's date is on or after its parent's (\"start_on\" ≥ \"requisition.opened_on\").\n */\n childDates?: { relation: string; field: string; parentField: string }[];\n /** withinParent: this row's number stays within its parent's (deal.price ≤ client.budget_max) unless a status says otherwise. */\n withinParent?: { relation: string; field: string; op: \"<=\" | \">=\"; parentField: string; unless?: { field: string; values: string[] } }[];\n /**\n * statusAgrees: a child in one of `childStatus` means its parent's `parentField` is one of\n * `parentStatus` (deal Closed ⇒ listing Sold); `maxPerParent` caps how many children of one\n * parent may sit in those statuses (one accepted offer per listing).\n */\n statusAgrees?: { relation: string; field: string; childStatus: string[]; parentField: string; parentStatus: string[]; maxPerParent?: number }[];\n /** countMatches: a stored count equals the number of linked rows. Prefer a rollup, which the store computes. */\n countMatches?: { field: string; childTable: string; childRelation: string }[];\n /**\n * STATUS IMPLIES FIELDS: a row in one of `when` (on `field`) has every `filled` field filled\n * and every `equals` field at that value — Paid ⇒ paid_on set and balance 0; Signed ⇒ the\n * signature filled. Checked on every seed row and after every walk step that changes a row.\n */\n statusImplies?: { field: string; when: string[]; filled?: string[]; equals?: Record<string, unknown> }[];\n /**\n * DATE-DRIVEN STATUS: `field` follows `dateField` measured from the install day, on every\n * install weekday — bands in days from today, `from` inclusive, `to` exclusive:\n * [{status: \"Expired\", to: 0}, {status: \"Renewal due\", from: 0, to: 61}, {status: \"Current\", from: 61}].\n * A row whose status is one of the bands' statuses sits in the band its date says. (A status the\n * store should compute is better a formula: IF(DATEDIFF(TODAY(), {Expires on}, 'days') < 0, …).)\n */\n statusByDate?: { field: string; dateField: string; bands: { status: string; from?: number; to?: number }[] };\n /** Relations (by field key) whose two sides' dates and statuses truly do not constrain each other, each with the reason. */\n independentOf?: Record<string, string>;\n /**\n * What one row is: a person, an animal or a thing. The personal-data floors (date of birth,\n * allergies, diagnoses, medications, member ids) bind people only — a dog's birthday is not\n * personal data. Undeclared, a table holds people when it has a name and a phone or email.\n */\n subject?: \"person\" | \"animal\" | \"thing\";\n /**\n * Lane 10 FD. An echo of the template's `foundation` list (R13), which is the ONE source the\n * installers read. Optional; when present the validator requires it to agree with the list.\n */\n foundation?: boolean;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Views → custom.view_declare\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const TEMPLATE_VIEW_KINDS = [\"grid\", \"kanban\", \"calendar\", \"gallery\", \"timeline\"] as const;\nexport type TemplateViewKind = (typeof TEMPLATE_VIEW_KINDS)[number];\n\nexport interface TemplateViewSort {\n field: string;\n direction: \"asc\" | \"desc\";\n}\n\ninterface TemplateViewBase {\n /** snake_case, unique within the template. */\n token: string;\n /** What a person clicks: \"Today's chairs\", \"Intake board\". */\n name: string;\n /** The table token it looks at. */\n table: string;\n /** The view the table opens on (at most one per table). */\n isDefault?: boolean;\n /** custom.view_declare `filters`: Field key → value (scalar equality, null = unset, object = window). */\n filters?: Record<string, AggregateFilter>;\n /**\n * Any-of conditions: Field key → the values a row may hold (\"Open requests\" = New, In progress,\n * Waiting). The store's flat `filters` map is equality only; this is declared as the view's\n * `where` Rule expression (S2-PRIME) — `{op: \"and\", args: [{op: \"or\", args: [{op: \"eq\", args:\n * [{field: <field id>}, {const: <value>}]}, …]}, …]}`, Fields by id — which custom.record_filter_sql\n * compiles for the grid and the board. Digests and the notifier read only `filters`, never this.\n */\n anyOf?: Record<string, string[]>;\n sorts?: TemplateViewSort[];\n /** Field keys hidden on this view (presentation.hiddenFields). */\n hiddenFields?: string[];\n}\n\nexport interface TemplateGridView extends TemplateViewBase {\n kind: \"grid\";\n groupBy?: string;\n}\n\nexport interface TemplateKanbanView extends TemplateViewBase {\n kind: \"kanban\";\n /** `group_field`: the choice field whose values are the columns. */\n groupBy: string;\n /** `swimlane_field`: never the column field itself. */\n swimlaneBy?: string;\n /** `measure`: a number field totalled under each column heading. */\n measure?: string;\n}\n\nexport interface TemplateCalendarView extends TemplateViewBase {\n kind: \"calendar\";\n /** `date_field`: a datetime, so every card has a time on the day. */\n dateField: string;\n /** The records are whole-day by intent (a deadline, a due date). */\n allDay?: boolean;\n /** \"month\" needs `view.calendar.month` (lane 10). */\n span?: \"month\" | \"week\";\n}\n\nexport interface TemplateGalleryView extends TemplateViewBase {\n kind: \"gallery\";\n /** `image_field`: the file field shown as each card's picture. Needs `seed.attachments`. */\n coverField: string;\n}\n\nexport interface TemplateTimelineView extends TemplateViewBase {\n kind: \"timeline\";\n startField: string;\n endField: string;\n groupBy?: string;\n}\n\nexport type TemplateView =\n | TemplateGridView\n | TemplateKanbanView\n | TemplateCalendarView\n | TemplateGalleryView\n | TemplateTimelineView;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Forms → custom.form_declare (with per-question text)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface TemplateFormField extends UseCaseFormField {\n /**\n * The question as it is ASKED: \"What brings you in today?\" — not the column label.\n * Sent as the question's `ask` to custom.form_declare / booking_declare (`help` rides beside it).\n */\n ask: string;\n}\n\nexport interface TemplateForm extends UseCaseForm {\n fields: TemplateFormField[];\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Dimensions → custom.table_dimensions_set(p_overrides)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface TemplateDimensionOverride {\n /** An inferred dimension key (custom._table_dimensions_infer): a single choice, a single relation, a tick box, a date, created_at or updated_at. */\n key: string;\n label?: string;\n hidden?: boolean;\n}\n\nexport interface TemplateMeasureOverride {\n /** An inferred measure key (count, sum_x, avg_x, min_x, max_x, filled_x) — rename/hide only — or a NEW key. */\n key: string;\n label?: string;\n hidden?: boolean;\n /** A NEW measure only: one of custom.agg_operations() except count. */\n op?: Exclude<AggregateOperation, \"count\">;\n /** A NEW measure only: the column it reads. */\n of?: string;\n}\n\nexport interface TemplateDrillPath {\n key: string;\n /** Dimension keys, coarsest first; a date takes \":year\" | \":quarter\" | \":month\" | \":week\" | \":day\". */\n levels: string[];\n}\n\nexport interface TemplateDimensions {\n table: string;\n dimensions?: TemplateDimensionOverride[];\n measures?: TemplateMeasureOverride[];\n paths?: TemplateDrillPath[];\n default?: { by?: string[]; show?: string[] };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Extras — at least two per template\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface TemplateBookingWindow {\n /** 0 = Sunday … 6 = Saturday. */\n weekday: number;\n /** \"09:00\". */\n from: string;\n /** \"17:00\", later than `from`. */\n to: string;\n}\n\nexport interface TemplateBooking {\n kind: \"booking\";\n token: string;\n title: string;\n table: string;\n questions: TemplateFormField[];\n availability: {\n timezone?: string;\n slotMinutes: number;\n bufferMinutes?: number;\n leadMinutes?: number;\n maxPerDay?: number;\n days?: number;\n windows: TemplateBookingWindow[];\n };\n slug?: string;\n /**\n * The statuses of rows that came through (or wait on) this booking page. Only those rows must\n * sit in its windows; rows that reached later stages by other routes (a same-day emergency\n * dispatch) do not. Default: Booked, Confirmed, Requested, Held, Pending, Scheduled, Cancelled.\n */\n bookedStages?: string[];\n}\n\nexport interface TemplatePortalTable {\n table: string;\n /** The relation field of `table` that points at the portal's client table — \"only theirs\". */\n namesVia: string;\n /** Never empty; never a restricted / confidential field or one the AI is kept from. */\n visibleFields: string[];\n editableFields?: string[];\n comments?: boolean;\n}\n\nexport interface TemplatePortal {\n kind: \"portal\";\n token: string;\n title: string;\n /** The table whose records are the portal's clients (patients, owners, tenants). */\n clientTable: string;\n tables: TemplatePortalTable[];\n /** Form tokens offered inside the portal. */\n forms?: string[];\n slug?: string;\n}\n\nexport interface TemplateDashboardBlock {\n title: string;\n kind: DashboardBlockKind;\n /** Absent = the dashboard's own table. */\n table?: string;\n groupBy?: string[];\n measures?: AggregateMeasure[];\n bucket?: { key: string; by: AggregateBucket };\n filter?: Record<string, AggregateFilter>;\n span?: number;\n /** `stuck` only. */\n stateKey?: string;\n days?: number;\n}\n\nexport interface TemplateDashboard {\n kind: \"dashboard\";\n token: string;\n name: string;\n table: string;\n /** At least two charts: bar, column, line or donut (`number`, `table` and `stuck` are not charts). */\n blocks: TemplateDashboardBlock[];\n}\n\nexport interface TemplateDrillDown {\n kind: \"drill_down\";\n token: string;\n name: string;\n table: string;\n /** A `paths[].key` of this table's `dimensions` entry. */\n path: string;\n}\n\nexport interface TemplateDigest {\n kind: \"digest\";\n token: string;\n name: string;\n /** The view token whose records the digest sends. */\n view: string;\n cadence: SubscriptionCadence;\n /** \"monday 08:00\". */\n schedule?: string;\n channel?: \"in_app\" | \"email\" | \"sms\";\n}\n\nexport interface TemplateChecklistStep {\n ref: string;\n title: string;\n role?: string;\n dueDays?: number;\n dependsOn?: string[];\n requires?:\n | { kind: \"none\" | \"note\" }\n | { kind: \"answer\"; key: string; label: string }\n | { kind: \"record_field\"; key: string; label?: string }\n | { kind: \"form\"; form: string }\n | { kind: \"document\"; document: string };\n}\n\nexport interface TemplateChecklist {\n kind: \"checklist\";\n token: string;\n name: string;\n aboutTable: string;\n roles?: { role: string; label?: string }[];\n trigger?: { kind: \"manual\" } | { kind: \"record_created\"; table: string } | { kind: \"status_reached\"; table: string; status: string };\n steps: TemplateChecklistStep[];\n}\n\nexport interface TemplateDocument {\n kind: \"document\";\n token: string;\n name: string;\n describes: string;\n table: string;\n /** The subject or title line; merge fields allowed. */\n title: string;\n /**\n * Prose with {{field_key}} merge fields, each a field of `table` (the installer writes\n * {{field:<id>}}, the only token custom.doc_render_body resolves). No {{today}}, no\n * {{business.x}}, no signature field (a signature never merges into the body).\n */\n body: string;\n /** Sent for e-signature (needs `document.esign`). */\n signature?: boolean;\n}\n\nexport interface TemplateNotification {\n kind: \"notification\";\n token: string;\n name: string;\n describes: string;\n when: UseCaseNotificationTrigger;\n /** Who it goes to, in the business's own words: \"the assigned hygienist\". */\n audience: string;\n channel: NotificationChannel;\n /** The message; {{field_key}} merge fields of the watched table only. */\n message: string;\n}\n\nexport interface TemplateStageRules {\n kind: \"stage_rules\";\n token: string;\n /** \"Route board\" — the lifecycle's own name. */\n name: string;\n table: string;\n /** The choice field holding the stage. */\n stageField: string;\n /** Stage → what is true of a record sitting there, in the staff's words (every stage). */\n stages: Record<string, string>;\n transitions?: { from: string; to: string }[];\n /** Stage → field keys that must be filled to land there. */\n requires?: Record<string, string[]>;\n /** Stage → how many cards may sit there at once. */\n limits?: Record<string, number>;\n movesMessage?: string;\n /**\n * Status ↔ date coherence, enforced on every seed row for every install weekday: the date\n * field, and per stage whether its date is in the past (on or before install day), today,\n * or the future (on or after install day). A stage left out is unconstrained.\n */\n dateField?: string;\n /** Every stage is listed once a dateField is declared; \"any\" says a stage's date is unconstrained, on purpose. */\n /** \"none\": this stage has no date yet (\"New call\", \"Draft\") — its date field is EMPTY. */\n stageDates?: Record<string, \"past\" | \"today\" | \"future\" | \"any\" | \"none\">;\n /** Why a time-bound stage (\"No-show\", \"Completed\", \"Scheduled\"…) is \"any\": one real sentence (≥ 6 words) per such stage. */\n anyBecause?: Record<string, string>;\n /**\n * Moves OUT of a terminal stage (Cancelled, No-show, Lost, Declined, Closed, Withdrawn…) are\n * refused unless declared here with the business reason — a reopened deal, a rebooked guest.\n */\n reopen?: { from: string; to: string; because: string }[];\n /**\n * A stage that needs a linked child: \"First pickup booked\" ⇒ at least `min` (default 1) row of\n * `table` whose `relation` points at this row and whose `field` is one of `in`. Checked on the\n * seed and on the walk's state after every step.\n */\n requiresChild?: Record<string, { table: string; relation: string; field?: string; in?: string[]; min?: number }>;\n}\n\nexport interface TemplateRowAction {\n kind: \"row_action\";\n token: string;\n table: string;\n name: string;\n actionKind: \"update\" | \"agent\";\n confirm?: boolean;\n color?: ChoiceColor;\n /** `update`: what it writes. Fields by key; the installer resolves ids. */\n steps?: ({ field: string; set: \"value\"; value: unknown } | { field: string; set: \"clear\" })[];\n /** `agent`: what the record chat opens with. */\n prompt?: string;\n}\n\nexport interface TemplateAutomation {\n kind: \"automation\";\n token: string;\n name: string;\n when: UseCaseNotificationTrigger;\n /** What happens, in the business's words: \"text the owner the pickup window\". */\n then: string;\n}\n\nexport type TemplateExtra =\n | TemplateBooking\n | TemplatePortal\n | TemplateDashboard\n | TemplateDrillDown\n | TemplateDigest\n | TemplateChecklist\n | TemplateDocument\n | TemplateNotification\n | TemplateStageRules\n | TemplateRowAction\n | TemplateAutomation;\nexport type TemplateExtraKind = TemplateExtra[\"kind\"];\nexport const TEMPLATE_EXTRA_KINDS: readonly TemplateExtraKind[] = [\n \"booking\",\n \"portal\",\n \"dashboard\",\n \"drill_down\",\n \"digest\",\n \"checklist\",\n \"document\",\n \"notification\",\n \"stage_rules\",\n \"row_action\",\n \"automation\",\n];\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The agent — a copy of a platform agent, variables bound, one scripted question (Q6)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface TemplateAgentVariable {\n /** One of the platform agent's own variable names (templates/AGENTS.snapshot.json). */\n name: string;\n /** The table token bound to it at install. */\n table: string;\n describes: string;\n /**\n * Optional (Kits → Template merge): the full merge-field binding instead of the whole-table\n * default. Its `table` must equal `table` above.\n */\n binding?: TemplateMergeBinding;\n}\n\n/**\n * Q6: one question, and the exact `custom.record_aggregate` answer it must give. The\n * validator recomputes the answer from the seed rows with the store's own semantics\n * (text-equality filters, half-open date windows, sum over nothing is null, no rounding).\n */\nexport interface TemplateAgentQuestion {\n ask: string;\n /** Why the owner asks it — what they do differently depending on the answer. */\n whyItMatters: string;\n expect: {\n table: string;\n measure: AggregateMeasure;\n /**\n * Scalar equality, null = unset, or a {from, to} window on a date field whose bounds are\n * relative tokens WITH a time (\"@today-7d 00:00\"), never a bare or absolute date. The\n * filter may not match 90% or more of the table's rows (that is \"how many are there\").\n */\n filter?: Record<string, AggregateFilter>;\n /** Never 0 and never null. */\n answer: number;\n unit: string;\n };\n}\n\n/** The platform agent every template copies unless it says why not (`agentReason`). */\nexport const DEFAULT_TEMPLATE_AGENT = { id: \"4cd676c6-f55d-4426-b7eb-a9d0273566ec\", name: \"Answers From Your Tables\" } as const;\n\nexport interface TemplateAgent {\n /** The platform agent copied — id AND name, as the committed catalogue snapshot has them. */\n platformAgent: { id: string; name: string };\n /** Required when platformAgent is not DEFAULT_TEMPLATE_AGENT: why this template needs another agent. */\n agentReason?: string;\n /** The copy's name in the installed org. */\n name: string;\n variables: TemplateAgentVariable[];\n question: TemplateAgentQuestion;\n /** Optional (Kits → Template merge): what \"Try it\" sends the copy. */\n tryIt?: TemplateTryIt;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Kits → Template merge (2026-10-04, ADDITIVE): more agents, full merge-field bindings,\n// workflows and a display guide. Every field below is optional on TemplateSpec; a template\n// without them installs exactly as before.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * The merge-field binding, with the two ids replaced by template-local handles the host resolves\n * at install: `table` (a table token) and `rowIndex` (the index of a seed row of that table).\n * `collection` = the table's rows (one text, via `transform`); `reference` = one row (`rowIndex`);\n * `value` = one field (`field`) of one row (`rowIndex`).\n */\nexport interface TemplateMergeBinding {\n semantic: \"collection\" | \"reference\" | \"value\";\n table: string;\n rowIndex?: number;\n field?: string;\n transform?: { name: \"list\"; template?: string; join?: string; max?: number; header?: string };\n limit?: number;\n sort?: { field: string; dir: \"asc\" | \"desc\" };\n match?: Record<string, unknown>;\n /** What the agent sees when nothing matches (default \"absent\"). */\n missing?: string;\n}\n\n/** What \"Try it\" sends a template's agent copy: the user's message and/or its other variables. */\nexport interface TemplateTryIt {\n userInput?: string;\n variables?: Record<string, string>;\n}\n\nexport interface TemplateExtraAgentVariable {\n /** One of the platform agent's own variable names (templates/AGENTS.snapshot.json). */\n name: string;\n describes: string;\n binding: TemplateMergeBinding;\n}\n\n/** One more agent a template copies (no Q6: its question is the primary agent's). */\nexport interface TemplateExtraAgent {\n /** Template-local handle: guide highlights and workflow `{{agent:key}}` placeholders use it. */\n key: string;\n platformAgent: { id: string; name: string };\n /** Why this template carries this agent — a full sentence (agents never author agents). */\n agentReason: string;\n name: string;\n variables: TemplateExtraAgentVariable[];\n tryIt?: TemplateTryIt;\n}\n\n/** A workflow made at install through aidream `POST /workflows`; `{{table:<token>}}` / `{{agent:<key>}}` are resolved. */\nexport interface TemplateWorkflow {\n key: string;\n name: string;\n description: string;\n definition: unknown;\n}\n\n/** One display step of how the template works (NOT the gated `walk`). */\nexport interface TemplateGuideStep {\n title: string;\n body: string;\n /** `agent` key \"agent\" names the primary agent. */\n highlight?: { kind: \"table\" | \"agent\" | \"workflow\" | \"binding\"; key: string };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The walk — three steps, each a machine-checkable, non-vacuous assertion (Q5)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** One CSV-shaped import: a header of field keys and the rows under it, as the file holds them. */\nexport interface WalkImport {\n kind: \"import\";\n table: string;\n /** What the file is called: \"October customer list.csv\". */\n sourceName: string;\n /** The field that makes a row the same row (`p_dedupe_key`); it carries a `unique` rule. */\n dedupeKey: string;\n /** The header row: field keys (the mapping is identity). */\n columns: string[];\n /** The data rows, cell by cell, as text — at least one updates a seed row and one is new. */\n rows: string[][];\n}\n\n/** One row's move inside a grouped `moves` step. */\nexport interface WalkMove {\n table: string;\n row: string;\n field: string;\n to: string;\n set?: Record<string, unknown>;\n}\n\nexport type WalkAction =\n | { kind: \"open\"; surface: string }\n /**\n * A stage move, optionally landing with the fields that stage requires or implies (`set`:\n * \"mark Paid\" writes paid_on and balance in the same step). Judged as ONE step: stage\n * requires, statusImplies, date pairs and the stage's date rule are checked on the result.\n * A checker or installer runs it as ONE store call, as the person:\n * `pipeline_move(p_record_id, p_to, p_also => set)` — the door writes `p_also` with the\n * stage in the same record write, judged by the same Rules (the board's \"this move needs\n * these fields\" prompt makes the same call). Never record_update first: that leaves a\n * half-moved row if the move is then refused.\n */\n | { kind: \"move\"; table: string; row: string; field: string; to: string; set?: Record<string, unknown> }\n /**\n * A GROUPED step: 2–3 linked moves made together (\"accept the quote AND move its lead to\n * Agreement signed\"). Each move is judged against its own table's transitions, requires,\n * statusImplies and date rules; the template's cross-table rules (statusAgrees,\n * withinParent, childDates) are judged on the state after the WHOLE group. A checker runs it\n * as one `pipeline_move(p_record_id, p_to, p_also => set)` per row, in the listed order, as\n * the person; the expect asserts where one of the moved rows landed.\n */\n | { kind: \"moves\"; moves: WalkMove[] }\n /**\n * One field (`field` + `value`) or several at once (`set: {field: value, …}` — \"mark paid\"\n * sets status, paid and balance together); the coherence rules judge the whole result.\n */\n | { kind: \"edit\"; table: string; row: string; field?: string; value?: unknown; set?: Record<string, unknown> }\n | { kind: \"submit_form\"; form: string; values: Record<string, unknown> }\n | { kind: \"archive\"; table: string; row: string }\n | { kind: \"restore\"; table: string; row: string }\n | WalkImport\n | { kind: \"ask_agent\" };\n\nexport type WalkAssertion =\n /** The surface renders with at least `minItems` (≥ 1) records. */\n /**\n * The surface renders with at least `minItems` (≥ 1) records. `within` is the date window the\n * step talks about (\"the next three weeks\"): relative tokens on the view's date field, checked\n * on every install weekday. A step that names a span on a calendar or timeline must carry it.\n */\n | { kind: \"renders\"; surface: string; minItems: number; within?: { from?: string; to?: string } }\n /** Over the walk's state after this step; never 0. */\n | { kind: \"count\"; table: string; where?: Record<string, AggregateFilter>; equals: number }\n | { kind: \"value\"; table: string; row: string; field: string; equals: unknown }\n | { kind: \"aggregate\"; table: string; measure: AggregateMeasure; where?: Record<string, AggregateFilter>; equals: number }\n /** After `ask_agent`: the exact number the agent must answer (= agent.question.expect.answer). */\n | { kind: \"agent_answer\"; equals: number }\n /** After `archive` / `restore`: the row it acted on is (or is no longer) archived. */\n | { kind: \"archived\"; table: string; row: string; equals: boolean };\n\nexport interface WalkStep {\n /** What the person does, in plain words: \"Drag Rosa to Scheduled\". */\n says: string;\n action: WalkAction;\n expect: WalkAssertion;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Foundation, provenance, footprint\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** A table marked as day-one foundation data (R13): kept for the reason given. */\nexport interface TemplateFoundation {\n table: string;\n keptFor: string;\n}\n\nexport interface TemplateSource {\n title: string;\n url?: string;\n /** What was taken: structure ideas only — never text, data or a real person. */\n took: string;\n}\n\nexport interface TemplateProvenance extends UseCaseProvenance {\n sources: TemplateSource[];\n /** Every domain an email, website or url in the file uses. Each must not resolve in DNS (G6). */\n fictionalDomains: string[];\n /** Every street a numbered address in the file is on: invented, never a real street. */\n fictionalStreets: string[];\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The template\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** The five singular artefacts a UseCase carries; a template derives them (toUseCase). */\nexport type UseCaseSingulars = \"form\" | \"pipeline\" | \"dashboardQuestion\" | \"documentTemplate\" | \"notificationRule\";\n\n/**\n * ONE TEMPLATE: the UseCase's business, tables and relationships, with the singulars\n * replaced by their plural, installable forms (forms[], stage_rules / document /\n * notification extras, the agent's question).\n */\nexport interface TemplateSpec extends Omit<UseCase, UseCaseSingulars | \"tables\" | \"provenance\" | \"industry\"> {\n /** The schema version of this file (TEMPLATE_SPEC_VERSION). */\n specVersion: typeof TEMPLATE_SPEC_VERSION;\n /** The CATALOGUE.json row this realises: \"T0042\". Stable, never positional. */\n catalogueId: string;\n industry: IndustryGroup;\n /** The practitioner's own vertical: \"Dental practice\", \"Residential HVAC\". */\n vertical: string;\n job: TemplateJob;\n audience: TemplateAudience;\n teaches: TeachesFeature;\n strengths: Strength[];\n requires: CapabilityWord[];\n tables: TemplateTable[];\n sharedBlocks: SharedBlockUse[];\n views: TemplateView[];\n forms: TemplateForm[];\n dimensions: TemplateDimensions[];\n extras: TemplateExtra[];\n agent: TemplateAgent;\n /** Three teaching steps, plus an optional fourth that is the ask_agent step. */\n walk: [WalkStep, WalkStep, WalkStep] | [WalkStep, WalkStep, WalkStep, WalkStep];\n foundation: TemplateFoundation[];\n provenance: TemplateProvenance;\n /** The gallery card's picture (lane 2), relative to the template file. */\n previewImage?: string;\n /** Content version: an integer, bumped on every published change. */\n version: number;\n /**\n * Lane 12 P7: tables that are Confidential (asked of the chair after install — a template never\n * sets the level itself) and tables whose members add their own rows. See ./confidential.\n */\n confidential?: TemplateConfidential[];\n membersAddRows?: string[];\n /** Kits → Template merge: more agents the install copies, after `agent`. */\n extraAgents?: TemplateExtraAgent[];\n /** Kits → Template merge: workflows the install creates. */\n workflows?: TemplateWorkflow[];\n /** Kits → Template merge: how-it-works steps, shown only (the gated teaching steps are `walk`). */\n guide?: TemplateGuideStep[];\n}\n\n/** \"3 tables · 2 views · 1 form · 1 booking\" plus the counts it is made of — what uninstall takes back. */\nexport interface TemplateFootprint {\n tables: number;\n /** Shared-block tables it seeds rows into (not owned: uninstall archives its rows only). */\n sharedBlocks: number;\n views: number;\n forms: number;\n dimensions: number;\n extras: Partial<Record<TemplateExtraKind, number>>;\n agents: number;\n /** Workflows an install creates (host step). */\n workflows: number;\n /**\n * custom.portal_declare opens the organization's outside sign-in. Q7: uninstall restores\n * the setting it found (the installer records the before-value).\n */\n opensOutsideSignIn: boolean;\n line: string;\n}\n\nconst EXTRA_WORDS: Record<TemplateExtraKind, [string, string]> = {\n booking: [\"booking page\", \"booking pages\"],\n portal: [\"portal\", \"portals\"],\n dashboard: [\"dashboard\", \"dashboards\"],\n drill_down: [\"drill-down\", \"drill-downs\"],\n digest: [\"digest\", \"digests\"],\n checklist: [\"checklist\", \"checklists\"],\n document: [\"document\", \"documents\"],\n notification: [\"notification\", \"notifications\"],\n stage_rules: [\"stage rule set\", \"stage rule sets\"],\n row_action: [\"row action\", \"row actions\"],\n automation: [\"automation\", \"automations\"],\n};\n\nfunction counted(n: number, [one, many]: [string, string]): string {\n return `${n} ${n === 1 ? one : many}`;\n}\n\n/** The footprint, DERIVED from the spec — never written by hand, so it cannot drift. */\nexport function footprintOf(\n spec: Pick<TemplateSpec, \"tables\" | \"views\" | \"forms\" | \"extras\" | \"agent\" | \"dimensions\" | \"sharedBlocks\"> &\n Partial<Pick<TemplateSpec, \"extraAgents\" | \"workflows\">>,\n): TemplateFootprint {\n const extras: Partial<Record<TemplateExtraKind, number>> = {};\n for (const extra of spec.extras ?? []) extras[extra.kind] = (extras[extra.kind] ?? 0) + 1;\n const dimensions = spec.dimensions?.length ?? 0;\n // Every table an install makes: the template's own and its shared blocks (a Team table is a table too —\n // a card that said \"3 tables\" installed 4).\n const tables = (spec.tables?.length ?? 0) + (spec.sharedBlocks?.length ?? 0);\n // A part the template does not make is left out (\"1 table · 3 agents\", never \"0 views · 0 forms\").\n const parts = [\n ...(tables ? [counted(tables, [\"table\", \"tables\"])] : []),\n ...(spec.views?.length ? [counted(spec.views.length, [\"view\", \"views\"])] : []),\n ...(spec.forms?.length ? [counted(spec.forms.length, [\"form\", \"forms\"])] : []),\n ...(dimensions ? [counted(dimensions, [\"dimension set\", \"dimension sets\"])] : []),\n ...TEMPLATE_EXTRA_KINDS.filter((k) => extras[k]).map((k) => counted(extras[k] ?? 0, EXTRA_WORDS[k])),\n ];\n // Every agent an install copies: the template's own and its extra agents (a card that said\n // \"1 agent\" made 3).\n const agents = (spec.agent ? 1 : 0) + (spec.extraAgents?.length ?? 0);\n if (agents) parts.push(counted(agents, [\"agent\", \"agents\"]));\n const workflows = spec.workflows?.length ?? 0;\n if (workflows) parts.push(counted(workflows, [\"workflow\", \"workflows\"]));\n return {\n tables,\n sharedBlocks: spec.sharedBlocks?.length ?? 0,\n views: spec.views?.length ?? 0,\n forms: spec.forms?.length ?? 0,\n dimensions,\n extras,\n agents,\n workflows,\n opensOutsideSignIn: (extras.portal ?? 0) > 0,\n line: parts.join(\" · \"),\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The catalogue row (templates/CATALOGUE.json) and the agent snapshot\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const CATALOGUE_STATUSES = [\"planned\", \"authoring\", \"checking\", \"waiting_on_lane_10\", \"ready\", \"published\", \"retired\"] as const;\nexport type CatalogueStatus = (typeof CATALOGUE_STATUSES)[number];\n\nexport interface CatalogueRow {\n /** Stable forever: a retired row keeps its id with status \"retired\"; ids are never reused. */\n catalogueId: string;\n industry: IndustryGroup;\n /** The vertical within the group: \"Dental practice\". */\n vertical: string;\n job: TemplateJob;\n teaches: TeachesFeature;\n strengths: Strength[];\n audience: TemplateAudience;\n /** One sentence the writer starts from: who, what business, what job. */\n personaSeed: string;\n ownerLane: string;\n status: CatalogueStatus;\n /** \"scope-template:<key>\" | \"use-case:<id>\" | \"new\". */\n source: string;\n /** Why a retired row was retired (\"duplicate of T0009\"). */\n retiredBecause?: string;\n /** The gallery card's picture, once the template has one. */\n previewImage?: string;\n /** Capabilities this row will need that may still be held (seed.attachments, automation), so batches can skip held rows. */\n requires?: CapabilityWord[];\n /**\n * The real install check of the CURRENT file (scripts/templates-publish.ts verify): installed through\n * the template family on the clone as a person, then uninstalled. `fileHash` pins which file passed.\n */\n installCheck?: {\n result: \"pass\" | \"fail\";\n /** Where the install ran: \"live\" since 2026-10-04 (Arman 2026-10-03: checks run on live; the clone is for destructive rehearsals only). */\n target: \"clone\" | \"live\";\n checkedAt: string;\n fileHash: string;\n wallMs: number;\n installMs?: number;\n steps?: number;\n calls?: number;\n orgId?: string;\n /** The refusal verbatim (store sentence, validator problem, or uninstall leftover). */\n refusal?: string;\n };\n /** Set by scripts/templates-publish.ts publish once declared for everyone on production. */\n published?: { templateId: string; version: number; steps: number; publishedAt: string; fileHash: string };\n}\n\n/** One platform agent a template may copy (templates/AGENTS.snapshot.json). */\nexport interface AgentSnapshotRow {\n id: string;\n name: string;\n variables: string[];\n}\n\n/** One entry of templates/RETIRED_IDS.json — append-only. */\nexport interface RetiredId {\n catalogueId: string;\n retiredOn: string;\n because: string;\n}\n","// src/templates/confidential.ts — @ai-matrx/records (templates)\n//\n// A TEMPLATE'S CONFIDENTIAL TABLES AND ITS \"MEMBERS ADD THEIR OWN ROWS\" TABLES.\n//\n// Lane 12 P7 (the HR employee review). Two table settings a template states and the install plan\n// alone cannot make:\n//\n// membersAddRows: [\"review_submission\", …]\n// The table's document says members_add_rows = true (custom.table_add_rung, CHAIR-DOORS-3A):\n// every member who may see the table adds rows, each edits only her own. A plan step sets it\n// through custom.record_change_many on the Table kernel — a door the family already allows,\n// run as the installing person, who owns the table she just made.\n//\n// confidential: [{ table, readers: [{field, level, when?}], makerIsReader, why }]\n// The store Table's Confidential level (custom.confidential_answer: the row's owner and the people\n// the row's own reader fields name — no organization, admin or library lane). It is set ONLY\n// through custom.set_table_confidential_arman_explicitly_approved, which records Arman's words\n// and which no client role may call (CHAIR-GUIDANCE: \"set only through the Arman-approved door\n// the chair runs\"). So a template never sets it: installing answers these REQUESTS, and the\n// chair runs each with Arman's standing word. Until the chair has run them the tables are\n// ordinary organization tables, so a host must not open the template's forms before then\n// (`confidentialPending`).\n//\n// `when` is a reader entry's condition on the row's own values (CHAIR-ACCESS c), written in the spec\n// as {column key: stored value} and sent as a Rule over field ids (`whenRule`), so derived columns\n// (lookups) are read too and a reader can wait on what another row says (\"both sides submitted\").\n\nimport type { TemplateSpec } from \"./types\";\n\nexport const TABLE_KERNEL_ID = \"11111111-0000-4000-8000-000000000001\";\n\nexport type ConfidentialLevel = \"viewer\" | \"commenter\" | \"editor\";\n\nexport interface TemplateConfidentialReader {\n /** A member / person field of the table whose value names the reader. */\n field: string;\n level: ConfidentialLevel;\n /** The row's own condition, flat saved-view filter: { \"cycle_manager_status\": \"Submitted\" }. */\n when?: Record<string, string | number | boolean>;\n}\n\nexport interface TemplateConfidential {\n table: string;\n readers: TemplateConfidentialReader[];\n /** true: the person who installs it is only a reader (the organization owns the table). */\n makerIsReader: boolean;\n /** One sentence for the chair and for Arman: why this table is Confidential. */\n why: string;\n}\n\nexport interface TemplateTableSettings {\n confidential?: TemplateConfidential[];\n membersAddRows?: string[];\n}\n\n/** One request the chair runs after install (the SQL is the exact call; words are the chair's). */\nexport interface ConfidentialRequest {\n table: string;\n tableId: string;\n readers: Array<{ field: string; level: ConfidentialLevel; when?: Record<string, unknown> }>;\n makerIsReader: boolean;\n why: string;\n /** `select custom.set_table_confidential_arman_explicitly_approved(…)` with `:'arman_words'` left for the chair. */\n sql: string;\n}\n\nconst sqlText = (s: string) => `'${s.replace(/'/g, \"''\")}'`;\n\n/** What a spec's confidential / membersAddRows say is wrong, in plain sentences ([] = fine). */\nexport function tableSettingsProblems(spec: TemplateSpec & TemplateTableSettings): string[] {\n const out: string[] = [];\n const tables = new Map(spec.tables.map((t) => [t.token, t]));\n for (const token of spec.membersAddRows ?? []) {\n if (!tables.has(token)) out.push(`membersAddRows names \"${token}\", which is not one of this template's tables.`);\n }\n const seen = new Set<string>();\n for (const c of spec.confidential ?? []) {\n const t = tables.get(c.table);\n if (!t) {\n out.push(`confidential names \"${c.table}\", which is not one of this template's tables.`);\n continue;\n }\n if (seen.has(c.table)) out.push(`confidential lists \"${c.table}\" twice.`);\n seen.add(c.table);\n if (!c.why?.trim()) out.push(`confidential \"${c.table}\" says why it is Confidential (one sentence for Arman).`);\n if (typeof c.makerIsReader !== \"boolean\") out.push(`confidential \"${c.table}\" says makerIsReader true or false.`);\n if (!c.readers?.length) out.push(`confidential \"${c.table}\" names at least one reader field; with none only each row's own writer reads it.`);\n for (const r of c.readers ?? []) {\n const f = t.fields.find((x) => x.key === r.field);\n if (!f) out.push(`confidential \"${c.table}\" reader \"${r.field}\" is not a field of the table.`);\n else if (![\"member\", \"person\", \"relation\"].includes(f.parityType as string)) out.push(`confidential \"${c.table}\" reader \"${r.field}\" is ${f.parityType}; a reader field names people (member).`);\n if (![\"viewer\", \"commenter\", \"editor\"].includes(r.level)) out.push(`confidential \"${c.table}\" reader \"${r.field}\" level is viewer, commenter or editor (never above editor).`);\n for (const k of Object.keys(r.when ?? {})) {\n if (!t.fields.some((x) => x.key === k)) out.push(`confidential \"${c.table}\" reader \"${r.field}\" waits on \"${k}\", which is not a field of the table.`);\n }\n }\n }\n return out;\n}\n\n/** The plan steps that set members_add_rows (custom.record_change_many on the Table kernel, as the person). */\nexport function membersAddRowsSteps(spec: TemplateTableSettings, tableRef: (token: string) => string) {\n return (spec.membersAddRows ?? []).map((token) => ({\n label: `members_add_rows.${token}`,\n door: \"record_change_many\" as const,\n args: {\n p_organization_id: \"${org}\",\n p_table_id: TABLE_KERNEL_ID,\n p_changes: [{ op: \"update\", record_id: tableRef(token), patch: { members_add_rows: true } }],\n },\n }));\n}\n\n/** The chair's requests for one install: table ids from the install answer's `made`. */\nexport function confidentialRequests(\n spec: TemplateTableSettings,\n made: Array<{ kind: string; ref: string; id: string | null }>,\n): ConfidentialRequest[] {\n const idOf = (token: string) => made.find((m) => m.kind === \"table\" && m.ref === `tables.${token}`)?.id ?? null;\n return (spec.confidential ?? []).map((c) => {\n const tableId = idOf(c.table);\n if (!tableId) throw new Error(`The install made no \"${c.table}\" table, so it cannot be made Confidential.`);\n const readers = c.readers.map((r) => ({ field: r.field, level: r.level, ...(r.when ? { when: whenRule(c.table, r.when, made) } : {}) }));\n return {\n table: c.table,\n tableId,\n readers,\n makerIsReader: c.makerIsReader,\n why: c.why,\n sql: `select custom.set_table_confidential_arman_explicitly_approved(${sqlText(tableId)}::uuid, ${sqlText(JSON.stringify(readers))}::jsonb, :'arman_words', current_date, ${c.makerIsReader});`,\n };\n });\n}\n\n/**\n * A reader's `when`, as the store asks it. The flat saved-view map compiles against the row's STORED\n * document only (custom.record_filter_sql reads r.data), so a lookup — \"both sides are submitted\",\n * read through the review cycle — would never be true there. A Rule expression is evaluated over\n * custom.record_values_of(r), which works lookups and roll-ups out on read; so every condition is\n * written as a Rule over the installed fields' ids (REC-17: a Rule points at a Field by id).\n */\nexport function whenRule(table: string, when: Record<string, unknown>, made: Array<{ kind: string; ref: string; id: string | null }>): Record<string, unknown> {\n const args = Object.entries(when).map(([key, value]) => {\n const id = made.find((m) => m.kind === \"field\" && m.ref === `fields.${table}.${key}`)?.id;\n if (!id) throw new Error(`The install answer names no field \"${key}\" on \"${table}\", so a reader cannot wait on it.`);\n return { op: \"eq\", args: [{ field: id }, { const: value }] };\n });\n return args.length === 1 ? args[0]! : { op: \"and\", args };\n}\n\n/** True while any of the template's Confidential tables is not Confidential yet (hold its forms). */\nexport function confidentialPending(spec: TemplateTableSettings, levels: Record<string, string | null | undefined>): boolean {\n return (spec.confidential ?? []).some((c) => levels[c.table] !== \"confidential\");\n}\n","// templates/extras.ts — Kits → Template merge (2026-10-04): the optional parts a kit carried.\n//\n// A template may carry, besides its one gated `agent`:\n// - `agent.variables[i].binding` the full merge-field binding (collection / one row / one field,\n// transform, limit, sort) instead of the whole-table default\n// - `extraAgents[]` more platform-agent copies, each variable bound the same way\n// - `workflows[]` workflows the host creates through aidream `POST /workflows`\n// - `guide[]` how-it-works steps, shown only (never the gated `walk`)\n// All are optional and ADDITIVE: a spec without them compiles, validates and installs exactly as\n// before. This file is their validator (`extrasProblems`, called once by validateTemplate) and\n// their compiler (`compileHostExtras`, called once by compileInstallPlan).\n//\n// The record pointer is template-local — a table token plus a seed-row index — and compiles to the\n// seed row's KEY; the install mints that row's id as `new:row.<token>.<key>` and the door's answer\n// hands the host those ids (custom._template_answer `host`), so the host never matches by name.\n\nimport type { UseCaseProblem } from \"../use-cases/validate\";\nimport type {\n AgentSnapshotRow,\n TemplateExtraAgent,\n TemplateMergeBinding,\n TemplateSpec,\n TemplateTable,\n TemplateTryIt,\n TemplateWorkflow,\n} from \"./types\";\n\n/** A binding as the install plan carries it: `rowIndex` replaced by the seed row's key. */\nexport interface TemplatePlanBinding extends Omit<TemplateMergeBinding, \"rowIndex\"> {\n rowKey?: string;\n}\n\nexport interface TemplatePlanExtraAgent {\n key: string;\n platformAgent: { id: string; name: string };\n name: string;\n bindings: Array<{ variable: string; describes: string; binding: TemplatePlanBinding }>;\n tryIt?: TemplateTryIt;\n}\n\nexport interface TemplateHostExtras {\n extraAgents?: TemplatePlanExtraAgent[];\n workflows?: TemplateWorkflow[];\n}\n\nconst KEY = /^[a-z][a-z0-9_]{0,63}$/;\nconst PLACEHOLDER = /\\{\\{(table|agent):([^}]+)\\}\\}/g;\n\nfunction tablesOf(spec: Pick<TemplateSpec, \"tables\">): Map<string, TemplateTable> {\n return new Map((spec.tables ?? []).map((t) => [t.token, t]));\n}\n\n/** The problems with one binding (`at` names where it sits). */\nfunction bindingProblems(at: string, b: TemplateMergeBinding | undefined, tables: Map<string, TemplateTable>, say: (at: string, says: string) => void): void {\n if (!b || typeof b !== \"object\") {\n say(at, \"Each variable carries its binding: what part of which table the agent reads.\");\n return;\n }\n if (![\"collection\", \"reference\", \"value\"].includes(b.semantic)) say(`${at}.semantic`, `\"${String(b.semantic)}\" is not a binding: it is a collection (the table's rows), a reference (one row) or a value (one field of one row).`);\n const t = tables.get(b.table);\n if (!t) {\n say(`${at}.table`, `It reads \"${b.table}\", which this template does not declare.`);\n return;\n }\n const keys = new Set(t.fields.map((f) => f.key));\n if (b.semantic === \"reference\" || b.semantic === \"value\") {\n const rows = t.rows ?? [];\n if (typeof b.rowIndex !== \"number\" || !Number.isInteger(b.rowIndex) || b.rowIndex < 0 || b.rowIndex >= rows.length) {\n say(`${at}.rowIndex`, `A ${b.semantic} points at one seed row of \"${b.table}\" by its index (0 to ${Math.max(rows.length - 1, 0)}); it has ${rows.length}.`);\n }\n } else if (b.rowIndex !== undefined) say(`${at}.rowIndex`, \"A collection reads the whole table; a row pointer belongs on a reference or a value.\");\n if (b.semantic === \"value\") {\n if (!b.field) say(`${at}.field`, \"A value names the one field it reads.\");\n else if (!keys.has(b.field)) say(`${at}.field`, `\"${b.table}\" has no field \"${b.field}\".`);\n }\n if (b.sort && !keys.has(b.sort.field)) say(`${at}.sort`, `It sorts on \"${b.sort.field}\", which \"${b.table}\" does not declare.`);\n if (b.sort && b.sort.dir !== \"asc\" && b.sort.dir !== \"desc\") say(`${at}.sort`, \"A sort is asc or desc.\");\n if (b.limit !== undefined && (!Number.isInteger(b.limit) || b.limit < 1)) say(`${at}.limit`, \"A limit is a whole number of rows, 1 or more.\");\n if (b.transform && b.transform.name !== \"list\") say(`${at}.transform`, `\"${String(b.transform.name)}\" is not a transform the resolver knows (list).`);\n}\n\n/** Every problem with the optional kit-merge parts of `spec`. Empty when it has none. */\nexport function extrasProblems(spec: TemplateSpec, agents: AgentSnapshotRow[] | undefined): UseCaseProblem[] {\n const problems: UseCaseProblem[] = [];\n const say = (at: string, says: string) => problems.push({ at, says });\n const tables = tablesOf(spec);\n\n // The primary agent's optional full bindings (every other rule on `agent` stays validateTemplate's).\n spec.agent?.variables?.forEach((v, vi) => {\n if (v.binding === undefined) return;\n const at = `agent.variables[${vi}].binding`;\n if (v.binding.table !== v.table) say(`${at}.table`, `The binding reads \"${v.binding.table}\" but the variable is bound to \"${v.table}\"; name one table.`);\n bindingProblems(at, v.binding, tables, say);\n });\n\n const extras: TemplateExtraAgent[] = spec.extraAgents ?? [];\n const agentKeys = new Set<string>([\"agent\"]);\n extras.forEach((a, ai) => {\n const at = `extraAgents[${ai}]`;\n if (!a.key || !KEY.test(a.key)) say(`${at}.key`, `\"${a.key}\" is not a key: lower-case letters, digits and _.`);\n else if (agentKeys.has(a.key)) say(`${at}.key`, `\"${a.key}\" is used twice (\"agent\" is the primary agent's).`);\n agentKeys.add(a.key);\n if (!a.name?.trim()) say(`${at}.name`, \"Name the copy the way the organization will see it.\");\n const row = agents?.find((x) => x.id === a.platformAgent?.id);\n if (!agents) say(`${at}.platformAgent`, \"No agent catalogue snapshot was given, so the agent could not be checked (pass templates/AGENTS.snapshot.json).\");\n else if (!row) say(`${at}.platformAgent`, `\"${a.platformAgent?.id}\" is not in the agent catalogue snapshot: a template copies a real platform agent, it never authors one.`);\n else if (row.name !== a.platformAgent.name) say(`${at}.platformAgent`, `The snapshot calls ${row.id} \"${row.name}\", not \"${a.platformAgent.name}\".`);\n if ((a.agentReason?.trim().split(/\\s+/).length ?? 0) < 8) say(`${at}.agentReason`, \"Say in agentReason, in a full sentence of at least eight words, why this template carries this agent.\");\n if (!a.variables?.length) say(`${at}.variables`, \"An agent without variables is not an agent: bind at least one to a table.\");\n const seen = new Set<string>();\n a.variables?.forEach((v, vi) => {\n const vat = `${at}.variables[${vi}]`;\n if (seen.has(v.name)) say(vat, `\"${v.name}\" is bound twice.`);\n seen.add(v.name);\n if (row && !row.variables.includes(v.name)) say(vat, `\"${row.name}\" has no variable \"${v.name}\"; its variables are: ${row.variables.join(\", \") || \"(none)\"}.`);\n if (!v.describes?.trim()) say(`${vat}.describes`, \"Say what the variable hands the agent.\");\n bindingProblems(`${vat}.binding`, v.binding, tables, say);\n });\n if (a.tryIt && row) {\n for (const k of Object.keys(a.tryIt.variables ?? {})) if (!row.variables.includes(k)) say(`${at}.tryIt.variables`, `\"${row.name}\" has no variable \"${k}\".`);\n }\n });\n\n const wfKeys = new Set<string>();\n (spec.workflows ?? []).forEach((w, wi) => {\n const at = `workflows[${wi}]`;\n if (!w.key || !KEY.test(w.key)) say(`${at}.key`, `\"${w.key}\" is not a key: lower-case letters, digits and _.`);\n else if (wfKeys.has(w.key)) say(`${at}.key`, `\"${w.key}\" is used twice.`);\n wfKeys.add(w.key);\n if (!w.name?.trim()) say(`${at}.name`, \"Name the workflow.\");\n if (!w.definition || typeof w.definition !== \"object\") say(`${at}.definition`, \"A workflow carries its definition (nodes and edges).\");\n for (const m of JSON.stringify(w.definition ?? null).matchAll(PLACEHOLDER)) {\n if (m[1] === \"table\" && !tables.has(m[2]!)) say(`${at}.definition`, `It names {{table:${m[2]}}}, which this template does not declare.`);\n if (m[1] === \"agent\" && !agentKeys.has(m[2]!)) say(`${at}.definition`, `It names {{agent:${m[2]}}}, which is not one of this template's agents.`);\n }\n });\n\n (spec.guide ?? []).forEach((g, gi) => {\n const at = `guide[${gi}]`;\n if (!g.title?.trim() || !g.body?.trim()) say(at, \"A guide step has a title and a body.\");\n const h = g.highlight;\n if (!h) return;\n const known =\n h.kind === \"table\" ? tables.has(h.key) : h.kind === \"agent\" ? agentKeys.has(h.key) : h.kind === \"workflow\" ? wfKeys.has(h.key) : h.kind === \"binding\";\n if (!known) say(`${at}.highlight`, `It highlights the ${h.kind} \"${h.key}\", which this template does not carry.`);\n });\n return problems;\n}\n\nfunction planBinding(b: TemplateMergeBinding, tables: Map<string, TemplateTable>): TemplatePlanBinding {\n const { rowIndex, ...rest } = b;\n if (rowIndex === undefined) return rest;\n const row = tables.get(b.table)?.rows?.[rowIndex];\n if (!row) throw new Error(`The binding points at seed row ${rowIndex} of \"${b.table}\", which has no such row.`);\n return { ...rest, rowKey: row.key };\n}\n\n/** The install plan's host parts: the primary agent's full bindings, extra agents and workflows. */\nexport function compileHostExtras(spec: TemplateSpec): {\n agentBindings: Map<string, TemplatePlanBinding>;\n extras: TemplateHostExtras;\n} {\n const tables = tablesOf(spec);\n const agentBindings = new Map<string, TemplatePlanBinding>();\n for (const v of spec.agent?.variables ?? []) if (v.binding) agentBindings.set(v.name, planBinding(v.binding, tables));\n const extras: TemplateHostExtras = {};\n if (spec.extraAgents?.length) {\n extras.extraAgents = spec.extraAgents.map((a) => ({\n key: a.key,\n platformAgent: a.platformAgent,\n name: a.name,\n bindings: a.variables.map((v) => ({ variable: v.name, describes: v.describes, binding: planBinding(v.binding, tables) })),\n ...(a.tryIt ? { tryIt: a.tryIt } : {}),\n }));\n }\n if (spec.workflows?.length) extras.workflows = spec.workflows;\n return { agentBindings, extras };\n}\n","// src/store.generated.ts — @ai-matrx/records\n//\n// GENERATED. Do not edit by hand: `pnpm records:generate` rewrites it from the\n// live record store, and `pnpm check:store-registry` fails the build when this\n// file and the store disagree. Every literal below was read from the database's\n// own catalogue — the vocabularies from the store's vocabulary functions, the\n// parity types from `custom.parity_field_types()`, the doors from `pg_proc`,\n// the kernel ids from the kernel rows themselves, the tokens from\n// `platform.entity_types`.\n//\n// Counts at generation: 3 actor words, 4 absence\n// reasons, 14 parity field types, 29 declarable field kinds,\n// 76 rule node kinds,\n// 9 kernel Tables, 884 doors, 72 knobs,\n// 1093 entity tokens.\n\nexport const ACTOR_VOCABULARY = [\"user\", \"agent\", \"system\"] as const;\n\n/** The three words the store still accepts and rewrites, and what each becomes. */\nexport const RETIRED_ACTOR_WORDS = {\"ai\": \"agent\", \"code\": \"system\", \"human\": \"user\"} as const;\n\nexport const ABSENCE_REASONS = [\"never asked\", \"none\", \"refused\", \"conflicting\"] as const;\n\nexport const VALUE_ENVELOPE_KEYS = [\"ver\", \"src\", \"actor\", \"on_behalf_of\", \"at\", \"absent\", \"alternates\", \"dated\", \"pinned\"] as const;\n\nexport const VALUE_ALTERNATE_KEYS = [\"value\", \"src\", \"rank\"] as const;\n\nexport const STORAGE_MODES = [\"light\", \"heavy\"] as const;\n\nexport const RULE_USES = [\"validate\", \"compute\", \"membership\", \"applicability\"] as const;\n\nexport const PER_VALUE_ACCESS_WORDS = [\"visibility\", \"access\", \"share\", \"acl\", \"permission\", \"permissions\", \"secret\"] as const;\n\n/** FLD-11's parity floor, each with the behaviour it is MADE OF (FLD-1). */\nexport const PARITY_FIELD_TYPES = [\n { parity_type: \"attachment\", behavior: \"relation\", made_of: \"REC-31: a File record reached through a relation, target the kernel `File` Table\" },\n { parity_type: \"checkbox\", behavior: \"boolean\", made_of: \"a ticked or unticked answer, stored as a REAL boolean — and a record that never answered holds neither, so filters and group-by see three states, not two\" },\n { parity_type: \"currency\", behavior: \"range\", made_of: \"FLD-N-1: a number whose UNIT is the currency and whose format is currency — on the Field, never in presentation\" },\n { parity_type: \"datetime\", behavior: \"range\", made_of: \"a range of kind date or datetime — the dated modifier says the VALUES are dated, which is a different question\" },\n { parity_type: \"email\", behavior: \"text\", made_of: \"text whose format is email\" },\n { parity_type: \"formula\", behavior: \"formula\", made_of: \"FLD-9: a declared computation, on read or on write, evaluated by custom.rule_eval\" },\n { parity_type: \"lookup\", behavior: \"formula\", made_of: \"a Value read THROUGH a relation — config.via names the relation field, config.pick the Value on the far side\" },\n { parity_type: \"member\", behavior: \"relation\", made_of: \"a person: a relation whose target is the kernel `Person` Table\" },\n { parity_type: \"multi_select\", behavior: \"list\", made_of: \"many choices from the same Table — the multi modifier, never a second behaviour\" },\n { parity_type: \"percent\", behavior: \"range\", made_of: \"a number whose unit is % and whose format is percent\" },\n { parity_type: \"phone\", behavior: \"text\", made_of: \"text whose format is phone\" },\n { parity_type: \"rollup\", behavior: \"formula\", made_of: \"an aggregate ALONG a relation — config.via, config.of, config.agg; far-side ids are taken DISTINCT, so nothing is counted twice\" },\n { parity_type: \"select\", behavior: \"list\", made_of: \"one choice from a Table shown as a list (FLD-5/FLD-6)\" },\n { parity_type: \"url\", behavior: \"text\", made_of: \"text whose format is url, with the pattern Rule that makes the format enforceable\" },\n] as const;\n\n/**\n * THE ONE REGISTRY: every kind a column can be DECLARED as, from\n * `custom.field_kinds()`. `parity` says whether the kind is one of FLD-11's parity\n * floor; the rest are the behaviours and formats the declaration door answers to and\n * nothing else enumerated — which is how `signature` came to be a shape\n * `custom.doc_sign` accepted and no screen could offer.\n */\nexport const DECLARABLE_FIELD_KINDS = [\n { kind: \"address\", behavior: \"text\", parity: false, made_of: \"P4: behaviour text, format address; the value is {street, city, region, postal_code, country}, every part optional, at least one filled\" },\n { kind: \"attachment\", behavior: \"relation\", parity: true, made_of: \"REC-31: a File record reached through a relation, target the kernel `File` Table\" },\n { kind: \"barcode\", behavior: \"text\", parity: false, made_of: \"P4: behaviour text, format barcode; one printable line a scanner reads, config.symbology optional (custom.barcode_symbologies()), EAN/UPC digits and check digit enforced\" },\n { kind: \"checkbox\", behavior: \"boolean\", parity: true, made_of: \"a ticked or unticked answer, stored as a REAL boolean — and a record that never answered holds neither, so filters and group-by see three states, not two\" },\n { kind: \"count\", behavior: \"formula\", parity: false, made_of: \"P4: a roll-up whose config.agg is count, with format count: how many records a many-relation points at, as a number of its own\" },\n { kind: \"created_by\", behavior: \"formula\", parity: false, made_of: \"P4: a formula Field whose config.system is created_by: who made the record, {id, name}, filled by the store from the record's writer on read and never typed\" },\n { kind: \"currency\", behavior: \"range\", parity: true, made_of: \"FLD-N-1: a number whose UNIT is the currency and whose format is currency — on the Field, never in presentation\" },\n { kind: \"datetime\", behavior: \"range\", parity: true, made_of: \"a range of kind date or datetime — the dated modifier says the VALUES are dated, which is a different question\" },\n { kind: \"duration\", behavior: \"range\", parity: false, made_of: \"P4: behaviour range, format duration, unit seconds; a length of time kept as seconds, never below zero\" },\n { kind: \"email\", behavior: \"text\", parity: true, made_of: \"text whose format is email\" },\n { kind: \"entity_reference\", behavior: \"relation\", parity: false, made_of: \"SC-R / P12: a relation whose target mode is any (REL-8), restricted by config.allowed_types to the platform kinds it may name (custom.entity_reference_kinds() — agents, notes, web sites, workbooks, datasets, conversations …); each value is {token, id}, the edge a platform.associations row record → <token>. File and Person stay relations to their kernel Tables\" },\n { kind: \"formula\", behavior: \"formula\", parity: true, made_of: \"FLD-9: a declared computation, on read or on write, evaluated by custom.rule_eval\" },\n { kind: \"long_text\", behavior: \"text\", parity: false, made_of: \"behaviour text with format long and config.multiline, for several lines rather than one\" },\n { kind: \"lookup\", behavior: \"formula\", parity: true, made_of: \"a Value read THROUGH a relation — config.via names the relation field, config.pick the Value on the far side\" },\n { kind: \"member\", behavior: \"relation\", parity: true, made_of: \"a person: a relation whose target is the kernel `Person` Table\" },\n { kind: \"modified_by\", behavior: \"formula\", parity: false, made_of: \"P4: a formula Field whose config.system is modified_by: who last changed the record, {id, name}, filled by the store on read and never typed\" },\n { kind: \"multi_select\", behavior: \"list\", parity: true, made_of: \"many choices from the same Table — the multi modifier, never a second behaviour\" },\n { kind: \"number\", behavior: \"range\", parity: false, made_of: \"a plain number: behaviour range with no date kind and neither the currency nor the percent format\" },\n { kind: \"percent\", behavior: \"range\", parity: true, made_of: \"a number whose unit is % and whose format is percent\" },\n { kind: \"phone\", behavior: \"text\", parity: true, made_of: \"text whose format is phone\" },\n { kind: \"rating\", behavior: \"range\", parity: false, made_of: \"P4: behaviour range, format rating; a whole number of stars from 0 to its max Rule (1 to 10, default 5), shown as stars\" },\n { kind: \"relation\", behavior: \"relation\", parity: false, made_of: \"REL / FLD-11: a relation a person aims themselves — relation_target names a Table of this organization, and it is a BEHAVIOUR, never a parity type of its own\" },\n { kind: \"rich_text\", behavior: \"text\", parity: false, made_of: \"P4: behaviour text, format rich_text; Markdown with no raw HTML and no script links, shown formatted\" },\n { kind: \"rollup\", behavior: \"formula\", parity: true, made_of: \"an aggregate ALONG a relation — config.via, config.of, config.agg; far-side ids are taken DISTINCT, so nothing is counted twice\" },\n { kind: \"select\", behavior: \"list\", parity: true, made_of: \"one choice from a Table shown as a list (FLD-5/FLD-6)\" },\n { kind: \"signature\", behavior: \"text\", parity: false, made_of: \"VAL-10: behaviour text whose format is signature — the one shape custom.doc_sign accepts, sealed by custom.doc_signature_write and checked by custom.doc_signature_intact\" },\n { kind: \"status\", behavior: \"list\", parity: false, made_of: \"P4: a single-choice list with format status; config.status_groups puts each choice key in todo, in_progress or done (Notion's Status)\" },\n { kind: \"text\", behavior: \"text\", parity: false, made_of: \"plain text: behaviour text with no format — it carries no parity type, which is exactly what custom.parity_type answers for it\" },\n { kind: \"url\", behavior: \"text\", parity: true, made_of: \"text whose format is url, with the pattern Rule that makes the format enforceable\" },\n] as const;\n\n/** The node kinds `custom.rule_eval` evaluates, and the lane that owns each. */\nexport const RULE_NODE_KINDS = [\n { node: \"actor_at_least\", evaluated_by: \"PIPELINES\" },\n { node: \"add\", evaluated_by: \"W1-RULE\" },\n { node: \"and\", evaluated_by: \"W1-RULE\" },\n { node: \"concat\", evaluated_by: \"W1-RULE\" },\n { node: \"const\", evaluated_by: \"W1-RULE\" },\n { node: \"div\", evaluated_by: \"W1-RULE\" },\n { node: \"eq\", evaluated_by: \"W1-RULE\" },\n { node: \"field\", evaluated_by: \"W1-RULE\" },\n { node: \"fx.abs\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.add\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.and\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.arraycompact\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.arrayjoin\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.autonumber\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.average\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.blank\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.concatenate\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.contains\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.created_time\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.dateadd\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.datediff\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.datetime_format\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.day\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.div\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.eq\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.find\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.gt\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.gte\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.if\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.isblank\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.left\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.len\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.lower\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.lt\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.lte\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.max\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.min\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.mod\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.modified_time\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.month\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.mul\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.ne\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.neg\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.not\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.now\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.or\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.regex_match\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.right\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.round\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.sub\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.substitute\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.sum\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.switch\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.today\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.trim\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.upper\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.workday\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"fx.year\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n { node: \"gt\", evaluated_by: \"W1-RULE\" },\n { node: \"gte\", evaluated_by: \"W1-RULE\" },\n { node: \"length\", evaluated_by: \"W1-RULE\" },\n { node: \"lt\", evaluated_by: \"W1-RULE\" },\n { node: \"lte\", evaluated_by: \"W1-RULE\" },\n { node: \"matches\", evaluated_by: \"W1-RULE\" },\n { node: \"merge_field\", evaluated_by: \"W5-MERGE-B\" },\n { node: \"mul\", evaluated_by: \"W1-RULE\" },\n { node: \"ne\", evaluated_by: \"W1-RULE\" },\n { node: \"not\", evaluated_by: \"W1-RULE\" },\n { node: \"or\", evaluated_by: \"W1-RULE\" },\n { node: \"parent_field\", evaluated_by: \"W1-RULE-APPLY\" },\n { node: \"present\", evaluated_by: \"W1-RULE\" },\n { node: \"previous\", evaluated_by: \"PIPELINES\" },\n { node: \"sibling_count\", evaluated_by: \"STAGE-RULES\" },\n { node: \"stage_count\", evaluated_by: \"PIPELINES\" },\n { node: \"sub\", evaluated_by: \"W1-RULE\" },\n { node: \"within\", evaluated_by: \"CHAIR-FILTER\" },\n] as const;\n\n/** REC-27. The kernel, by name and by id, as the store holds it. */\nexport const KERNEL_TABLES = [\n { id: \"11111111-0000-4000-8000-000000000002\", name: \"Field\" },\n { id: \"11111111-0000-4000-8000-000000000006\", name: \"File\" },\n { id: \"11111111-0000-4000-8000-000000000009\", name: \"Merge Field\" },\n { id: \"11111111-0000-4000-8000-000000000004\", name: \"Organization\" },\n { id: \"11111111-0000-4000-8000-000000000005\", name: \"Person\" },\n { id: \"11111111-0000-4000-8000-000000000007\", name: \"Presentation\" },\n { id: \"11111111-0000-4000-8000-000000000003\", name: \"Rule\" },\n { id: \"11111111-0000-4000-8000-000000000001\", name: \"Table\" },\n { id: \"11111111-0000-4000-8000-000000000008\", name: \"Widget\" },\n] as const;\n\n/**\n * Every door the store actually has, with the argument list and the result the\n * catalogue reports. A client call whose door is not in this list is answered\n * `door_absent` by name — never a guess, never a silent no-op.\n */\nexport const STORE_DOORS = [\n { name: \"absence_reasons\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"action_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_actions jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"action_run\", args: \"p_organization_id uuid, p_action_id uuid, p_record_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"actor_vocabulary\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"actor_word\", args: \"p_declared text\", returns: \"text\", security: \"invoker\" },\n { name: \"addressed_cap\", args: \"p_user_id uuid, p_type text, p_id uuid, p_organization_id uuid DEFAULT NULL::uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"permission_level\", security: \"definer\" },\n { name: \"addressed_cap_specific\", args: \"p_user_id uuid, p_type text, p_id uuid, p_organization_id uuid DEFAULT NULL::uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"permission_level\", security: \"definer\" },\n { name: \"agent_change_approval\", args: \"p_organization uuid, p_conversation uuid DEFAULT NULL::uuid, p_table uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"agent_change_trust\", args: \"p_organization_id uuid, p_approval_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"agent_context\", args: \"p_organization_id uuid, p_table_id uuid, p_limit integer DEFAULT 50\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"agent_context_value\", args: \"p_doc jsonb, p_key text, p_type text, p_organization_id uuid, p_record_id uuid, p_cap bigint\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"agent_context_value_cap\", args: \"p_organization_id uuid\", returns: \"bigint\", security: \"invoker\" },\n { name: \"agent_table_claim\", args: \"p_organization uuid, p_table uuid, p_conversation uuid DEFAULT NULL::uuid\", returns: \"void\", security: \"definer\" },\n { name: \"agg_assert_key\", args: \"p_key text\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_bucket_ordinal\", args: \"p_by text, p_window_from timestamp without time zone, p_at timestamp without time zone, p_week_start text\", returns: \"integer\", security: \"invoker\" },\n { name: \"agg_buckets\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"agg_cadence_normalize\", args: \"p_cadence text\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_calendar\", args: \"p_organization_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"agg_compare_kinds\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"agg_compare_windows\", args: \"p_organization_id uuid, p_compare jsonb, p_bucket jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"agg_deliver\", args: \"p_organization_id uuid, p_rule_id uuid, p_record_id uuid, p_channel text, p_recipient_user_id uuid, p_event_key text, p_subject text, p_body text, p_payload jsonb DEFAULT '{}'::jsonb, p_dedupe_suffix text DEFAULT NULL::text\", returns: \"uuid\", security: \"invoker\" },\n { name: \"agg_deliver_quietly\", args: \"p_organization_id uuid, p_rule_id uuid, p_subject_id uuid, p_channel text, p_recipient_user_id uuid, p_event_key text, p_subject text, p_body text, p_payload jsonb, p_quiet_hours jsonb, p_link text, p_dedupe_suffix text DEFAULT NULL::text\", returns: \"uuid\", security: \"invoker\" },\n { name: \"agg_delta\", args: \"p_current jsonb, p_prior jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"agg_digest_assemble\", args: \"p_organization_id uuid, p_rule_id uuid, p_since timestamp with time zone DEFAULT NULL::timestamp with time zone, p_until timestamp with time zone DEFAULT NULL::timestamp with time zone\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"agg_digest_due_at\", args: \"p_cadence text, p_schedule text, p_quiet jsonb, p_after timestamp with time zone\", returns: \"timestamp with time zone\", security: \"invoker\" },\n { name: \"agg_digest_judged_at\", args: \"p_organization_id uuid, p_rule_id uuid\", returns: \"timestamp with time zone\", security: \"invoker\" },\n { name: \"agg_digest_run\", args: \"p_organization_id uuid, p_rule_id uuid DEFAULT NULL::uuid, p_since timestamp with time zone DEFAULT NULL::timestamp with time zone\", returns: \"integer\", security: \"invoker\" },\n { name: \"agg_digest_run_at\", args: \"p_organization_id uuid, p_rule_id uuid, p_since timestamp with time zone, p_now timestamp with time zone\", returns: \"integer\", security: \"invoker\" },\n { name: \"agg_digest_tick\", args: \"\", returns: \"integer\", security: \"invoker\" },\n { name: \"agg_digest_tick_at\", args: \"p_now timestamp with time zone, p_organization_id uuid DEFAULT NULL::uuid\", returns: \"integer\", security: \"invoker\" },\n { name: \"agg_explain\", args: \"p_organization_id uuid, p_table_id uuid, p_group_by jsonb DEFAULT '[]'::jsonb, p_measures jsonb DEFAULT '[]'::jsonb, p_bucket jsonb DEFAULT NULL::jsonb, p_filter jsonb DEFAULT '{}'::jsonb, p_required text DEFAULT 'viewer'::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"agg_field_kind\", args: \"p_organization_id uuid, p_table_id uuid, p_key text\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_field_value_sql\", args: \"p_organization_id uuid, p_table_id uuid, p_key text\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_fields_readable_assert\", args: \"p_organization_id uuid, p_table_id uuid, p_keys text[], p_required text DEFAULT 'viewer'::text\", returns: \"void\", security: \"invoker\" },\n { name: \"agg_last_digest_at\", args: \"p_organization_id uuid, p_rule_id uuid\", returns: \"timestamp with time zone\", security: \"invoker\" },\n { name: \"agg_local_label\", args: \"p_local timestamp without time zone, p_tz text\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_moment_sql\", args: \"p_key text, p_tz text\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_operations\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"agg_parse_moment\", args: \"p_raw text, p_tz text, p_what text\", returns: \"timestamp with time zone\", security: \"invoker\" },\n { name: \"agg_period_start\", args: \"p_local timestamp without time zone, p_by text, p_week_start text DEFAULT 'monday'::text\", returns: \"timestamp without time zone\", security: \"invoker\" },\n { name: \"agg_period_step\", args: \"p_by text\", returns: \"interval\", security: \"invoker\" },\n { name: \"agg_quiet_until\", args: \"p_quiet jsonb, p_at timestamp with time zone\", returns: \"timestamp with time zone\", security: \"invoker\" },\n { name: \"agg_record_name\", args: \"p_organization_id uuid, p_record_id uuid, p_state jsonb DEFAULT NULL::jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_sql\", args: \"p_organization_id uuid, p_table_id uuid, p_group_by jsonb DEFAULT '[]'::jsonb, p_measures jsonb DEFAULT '[]'::jsonb, p_bucket jsonb DEFAULT NULL::jsonb, p_filter jsonb DEFAULT '{}'::jsonb, p_limit integer DEFAULT 200, p_required text DEFAULT 'viewer'::text, p_window jsonb DEFAULT NULL::jsonb, p_search text DEFAULT NULL::text, p_time_zone text DEFAULT NULL::text\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_subscription_cadences\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"agg_subscription_fire\", args: \"p_organization_id uuid, p_record_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_changed_field_ids jsonb DEFAULT '[]'::jsonb\", returns: \"integer\", security: \"invoker\" },\n { name: \"agg_subscription_fire_entered\", args: \"p_organization_id uuid, p_record_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_since timestamp with time zone DEFAULT NULL::timestamp with time zone\", returns: \"integer\", security: \"invoker\" },\n { name: \"agg_subscription_tick\", args: \"p_window interval DEFAULT '00:15:00'::interval\", returns: \"integer\", security: \"invoker\" },\n { name: \"agg_subscriptions\", args: \"p_organization_id uuid, p_saved_view_id uuid DEFAULT NULL::uuid, p_cadence text DEFAULT NULL::text\", returns: \"TABLE(rule_id uuid, saved_view_id uuid, table_id uuid, cadence text, schedule text, quiet_hours jsonb, channel text, recipient_user_id uuid, event_key text, name text)\", security: \"invoker\" },\n { name: \"agg_value_sql\", args: \"p_key text\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_value_text\", args: \"p_value jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"agg_view_admits\", args: \"p_organization_id uuid, p_saved_view_id uuid, p_record_id uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"agg_view_admits_state\", args: \"p_definition jsonb, p_state jsonb\", returns: \"boolean\", security: \"invoker\" },\n { name: \"agg_withheld_marker\", args: \"p_organization_id uuid, p_table_id uuid, p_key text, p_required text DEFAULT 'viewer'::text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"agg_zero\", args: \"p_measures jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"anon_capture\", args: \"p_organization_id uuid, p_client_key text, p_table_id uuid, p_payload jsonb, p_device text DEFAULT NULL::text, p_captured_at timestamp with time zone DEFAULT NULL::timestamp with time zone\", returns: \"uuid\", security: \"definer\" },\n { name: \"anon_clear\", args: \"p_organization_id uuid, p_submission_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"anon_inbound_land\", args: \"p_address text, p_secret text, p_payload jsonb, p_raw_payload jsonb DEFAULT '{}'::jsonb, p_client_key text DEFAULT NULL::text\", returns: \"uuid\", security: \"definer\" },\n { name: \"anon_publish\", args: \"p_organization_id uuid, p_form_id uuid, p_published boolean DEFAULT true\", returns: \"timestamp with time zone\", security: \"definer\" },\n { name: \"anon_rate_take\", args: \"p_organization_id uuid, p_form_id uuid, p_bucket text, p_token_id uuid DEFAULT NULL::uuid\", returns: \"integer\", security: \"definer\" },\n { name: \"anon_submissions\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_state text DEFAULT NULL::text, p_limit integer DEFAULT 100, p_offset integer DEFAULT 0\", returns: \"TABLE(id uuid, form_id uuid, inbound_id uuid, table_id uuid, source text, state text, payload jsonb, raw_payload jsonb, client_key text, record_id uuid, remote_origin text, rejection_reason text, created_at timestamp with time zone, cleared_at timestamp with time zone)\", security: \"definer\" },\n { name: \"anon_token_issue\", args: \"p_organization_id uuid, p_mode text, p_allowed_origins jsonb, p_form_id uuid DEFAULT NULL::uuid, p_saved_view_id uuid DEFAULT NULL::uuid, p_record_id uuid DEFAULT NULL::uuid, p_expires_at timestamp with time zone DEFAULT NULL::timestamp with time zone\", returns: \"TABLE(token_id uuid, secret text)\", security: \"definer\" },\n { name: \"anon_token_revoke\", args: \"p_organization_id uuid, p_token_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"anon_token_verify\", args: \"p_secret text, p_origin text, p_required_mode text\", returns: \"TABLE(token_id uuid, organization_id uuid, form_id uuid, saved_view_id uuid, record_id uuid, mode text)\", security: \"definer\" },\n { name: \"anon_write\", args: \"p_secret text, p_origin text, p_payload jsonb, p_client_key text DEFAULT NULL::text, p_raw_payload jsonb DEFAULT '{}'::jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"applicable_fields\", args: \"p_organization_id uuid, p_table_id uuid, p_record_type text DEFAULT NULL::text\", returns: \"SETOF custom.record\", security: \"definer\" },\n { name: \"archive_event_of\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"history.migration_log\", security: \"definer\" },\n { name: \"archived_tables_everywhere\", args: \"p_lane text DEFAULT 'org'::text, p_limit integer DEFAULT 100, p_offset integer DEFAULT 0, p_sort text DEFAULT 'archived_at'::text, p_desc boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"assert_client_may_change\", args: \"p_organization_id uuid, p_subject_id uuid, p_door text, p_required permission_level DEFAULT 'editor'::permission_level, p_subject_word text DEFAULT 'record'::text\", returns: \"void\", security: \"invoker\" },\n { name: \"assert_client_may_open\", args: \"p_organization_id uuid, p_subject_id uuid, p_door text, p_required permission_level DEFAULT 'viewer'::permission_level, p_subject_word text DEFAULT 'record'::text\", returns: \"void\", security: \"invoker\" },\n { name: \"assert_client_may_reach\", args: \"p_organization_id uuid, p_door text\", returns: \"void\", security: \"invoker\" },\n { name: \"assert_columns_are_defined\", args: \"p_organization_id uuid, p_record_id uuid, p_patch jsonb\", returns: \"void\", security: \"definer\" },\n { name: \"assert_entity_door\", args: \"p_organization_id uuid, p_door text\", returns: \"void\", security: \"definer\" },\n { name: \"assert_entity_is_organization_scoped\", args: \"p_token text, p_label text, p_scoped boolean\", returns: \"void\", security: \"invoker\" },\n { name: \"assert_may_know_table\", args: \"p_organization_id uuid, p_table_id uuid, p_door text\", returns: \"void\", security: \"invoker\" },\n { name: \"assert_organization_admin\", args: \"p_organization_id uuid, p_door text, p_what text\", returns: \"void\", security: \"invoker\" },\n { name: \"assert_organization_wall\", args: \"p_kind text, p_organization_id uuid, p_row jsonb\", returns: \"void\", security: \"invoker\" },\n { name: \"assert_scope_door\", args: \"p_organization_id uuid, p_door text\", returns: \"void\", security: \"definer\" },\n { name: \"assert_store_door\", args: \"p_organization_id uuid, p_door text\", returns: \"void\", security: \"invoker\" },\n { name: \"autonumber_backfill\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"barcode_symbologies\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"booking_cancel\", args: \"p_booking_ref text, p_origin text DEFAULT NULL::text\", returns: \"TABLE(booking_ref text, record_id uuid, slot_key text, state text, message text)\", security: \"definer\" },\n { name: \"booking_confirm\", args: \"p_form_id uuid, p_hold_id uuid, p_origin text, p_payload jsonb, p_bucket text, p_honeypot text DEFAULT NULL::text, p_client_key text DEFAULT NULL::text\", returns: \"TABLE(booking_ref text, record_id uuid, submission_id uuid, slot_key text, slot_at timestamp with time zone, state text, message text)\", security: \"definer\" },\n { name: \"booking_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_title text, p_questions jsonb, p_availability jsonb DEFAULT '{}'::jsonb, p_presentation jsonb DEFAULT '{}'::jsonb, p_submission_cap integer DEFAULT NULL::integer, p_quarantine_rule_id uuid DEFAULT NULL::uuid, p_notify_rule_id uuid DEFAULT NULL::uuid, p_form_id uuid DEFAULT NULL::uuid, p_slug text DEFAULT NULL::text, p_home_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"booking_hold\", args: \"p_form_id uuid, p_slot_key text, p_origin text, p_bucket text, p_client_key text DEFAULT NULL::text\", returns: \"TABLE(hold_id uuid, slot_key text, expires_at timestamp with time zone, member_user_id uuid, state text, message text)\", security: \"definer\" },\n { name: \"booking_manage\", args: \"p_booking_ref text, p_days integer DEFAULT NULL::integer\", returns: \"TABLE(booking_ref text, form_id uuid, title text, slot_key text, slot_at timestamp with time zone, status text, slots jsonb, availability jsonb, state text, message text)\", security: \"definer\" },\n { name: \"booking_notify\", args: \"p_organization_id uuid, p_form_id uuid, p_record_id uuid, p_submission_id uuid, p_event text, p_when text\", returns: \"uuid\", security: \"invoker\" },\n { name: \"booking_public\", args: \"p_form_id uuid, p_days integer DEFAULT NULL::integer\", returns: \"TABLE(form_id uuid, organization_id uuid, table_id uuid, title text, presentation jsonb, fields jsonb, honeypot_key text, availability jsonb, slots jsonb, state text, message text)\", security: \"definer\" },\n { name: \"booking_reschedule\", args: \"p_booking_ref text, p_slot_key text, p_origin text, p_bucket text DEFAULT NULL::text\", returns: \"TABLE(booking_ref text, record_id uuid, slot_key text, slot_at timestamp with time zone, state text, message text)\", security: \"definer\" },\n { name: \"bookings\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(form_id uuid, table_id uuid, title text, slug text, published_at timestamp with time zone, closed_at timestamp with time zone, slot_minutes integer, timezone text, slot_table_id uuid, booked bigint, cancelled bigint, upcoming bigint, held bigint, next_at timestamp with time zone, state text)\", security: \"definer\" },\n { name: \"bump_epoch\", args: \"p_entity_type text, p_entity_id uuid, p_organization_id uuid DEFAULT NULL::uuid\", returns: \"bigint\", security: \"definer\" },\n { name: \"cache_lookup\", args: \"p_container_type text, p_container_id uuid, p_item_type text, p_item_id uuid\", returns: \"permission_level\", security: \"definer\" },\n { name: \"caller_role\", args: \"\", returns: \"name\", security: \"invoker\" },\n { name: \"capture_open\", args: \"p_organization_id uuid, p_sheet_id uuid\", returns: \"TABLE(sheet_id uuid, organization_id uuid, table_id uuid, title text, presentation jsonb, fields jsonb, state text, may_capture boolean, message text)\", security: \"definer\" },\n { name: \"capture_publish\", args: \"p_organization_id uuid, p_sheet_id uuid, p_open boolean DEFAULT true\", returns: \"timestamp with time zone\", security: \"definer\" },\n { name: \"capture_sheet_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_title text, p_questions jsonb, p_presentation jsonb DEFAULT '{}'::jsonb, p_sheet_id uuid DEFAULT NULL::uuid, p_notify_rule_id uuid DEFAULT NULL::uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"capture_sheets\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(sheet_id uuid, table_id uuid, title text, slug text, state text, opened_at timestamp with time zone, captures bigint, replays bigint, last_capture_at timestamp with time zone, presentation jsonb)\", security: \"definer\" },\n { name: \"capture_submit\", args: \"p_organization_id uuid, p_sheet_id uuid, p_client_key text, p_payload jsonb, p_files jsonb DEFAULT '[]'::jsonb, p_device text DEFAULT NULL::text, p_captured_at timestamp with time zone DEFAULT NULL::timestamp with time zone, p_location jsonb DEFAULT NULL::jsonb\", returns: \"TABLE(record_id uuid, state text, message text, replay boolean, file_ids uuid[])\", security: \"definer\" },\n { name: \"carry_unchanged_value_stamps\", args: \"p_old jsonb, p_new jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"carrying_edges_in\", args: \"p_organization_id uuid\", returns: \"TABLE(container_type text, container_id uuid, item_type text, item_id uuid, conveys_max permission_level)\", security: \"definer\" },\n { name: \"carrying_edges_of\", args: \"p_item_type text, p_item_id uuid\", returns: \"TABLE(container_type text, container_id uuid, conveys_max permission_level)\", security: \"definer\" },\n { name: \"checklist_declare\", args: \"p_organization_id uuid, p_spec jsonb, p_template_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"checklist_refusal\", args: \"p_spec jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"checklist_run\", args: \"p_organization_id uuid, p_run_id uuid\", returns: \"TABLE(step_id uuid, step_order integer, ref text, title text, role text, assignee_name text, assignee_user_id uuid, due_on timestamp with time zone, due_state text, status text, finished boolean, requires text, requires_key text, requires_label text, requires_id uuid, evidence jsonb, blocked_by text[], may_complete boolean, refusal text)\", security: \"definer\" },\n { name: \"checklist_runs\", args: \"p_organization_id uuid, p_about_table_id uuid DEFAULT NULL::uuid, p_about_record_id uuid DEFAULT NULL::uuid, p_include_closed boolean DEFAULT true, p_limit integer DEFAULT 100\", returns: \"TABLE(run_id uuid, name text, template_id uuid, template text, about_record_id uuid, about text, about_table_id uuid, started_at timestamp with time zone, started_by uuid, origin text, step_count integer, done integer, overdue integer, next_step text, next_due timestamp with time zone, closed_at timestamp with time zone)\", security: \"definer\" },\n { name: \"checklist_start\", args: \"p_organization_id uuid, p_template_id uuid, p_about_record_id uuid DEFAULT NULL::uuid, p_roles jsonb DEFAULT '{}'::jsonb, p_starting_at timestamp with time zone DEFAULT NULL::timestamp with time zone\", returns: \"jsonb\", security: \"definer\" },\n { name: \"checklist_step_complete\", args: \"p_organization_id uuid, p_step_id uuid, p_evidence jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"checklist_step_refusal\", args: \"p_organization_id uuid, p_step_id uuid\", returns: \"text\", security: \"definer\" },\n { name: \"checklist_steps_table\", args: \"p_organization_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"checklist_template_shape\", args: \"p_organization_id uuid, p_template_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"checklist_templates\", args: \"p_organization_id uuid, p_about_table_id uuid DEFAULT NULL::uuid, p_limit integer DEFAULT 100\", returns: \"TABLE(template_id uuid, name text, about_table_id uuid, about_table text, steps integer, roles integer, trigger_kind text, trigger_status text, open_runs integer, total_runs integer, updated_at timestamp with time zone)\", security: \"definer\" },\n { name: \"checklist_templates_archived\", args: \"p_organization_id uuid, p_about_table_id uuid DEFAULT NULL::uuid, p_limit integer DEFAULT 100\", returns: \"TABLE(template_id uuid, name text, about_table_id uuid, about_table text, steps integer, archived_at timestamp with time zone, archived_by uuid, table_archived boolean)\", security: \"definer\" },\n { name: \"choice_census\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"choice_field_map\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_filter_normalize\", args: \"p_map jsonb, p_filter jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_key_for\", args: \"p_organization_id uuid, p_options_table_id uuid, p_title text, p_exclude uuid DEFAULT NULL::uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"choice_key_of\", args: \"p_field jsonb, p_token text\", returns: \"text\", security: \"invoker\" },\n { name: \"choice_nudge\", args: \"p_organization_id uuid\", returns: \"text\", security: \"definer\" },\n { name: \"choice_options\", args: \"p_organization_id uuid, p_options_table_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_render\", args: \"p_organization_id uuid, p_table_id uuid, p_doc jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_render_groups\", args: \"p_map jsonb, p_groups jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_render_note\", args: \"p_field jsonb, p_value jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_render_plan\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_render_value\", args: \"p_field jsonb, p_value jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_render_with\", args: \"p_organization_id uuid, p_table_id uuid, p_doc jsonb, p_plan jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"choice_slug\", args: \"p_word text\", returns: \"text\", security: \"invoker\" },\n { name: \"choice_synonyms\", args: \"p_organization_id uuid, p_table_id uuid, p_token text\", returns: \"text[]\", security: \"invoker\" },\n { name: \"choice_synonyms_in\", args: \"p_map jsonb, p_token text\", returns: \"text[]\", security: \"invoker\" },\n { name: \"choice_words\", args: \"p_field jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"client_write_grants\", args: \"\", returns: \"TABLE(role_name text, object_name text, privilege text)\", security: \"invoker\" },\n { name: \"comment_mention_deliver\", args: \"p_organization_id uuid, p_record_id uuid, p_table_id uuid, p_comment_id uuid, p_recipient uuid, p_author_name text, p_record_title text, p_body text\", returns: \"uuid\", security: \"definer\" },\n { name: \"comment_thread\", args: \"p_organization_id uuid, p_record_id uuid, p_include_resolved boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\n { name: \"comment_write\", args: \"p_organization_id uuid, p_record_id uuid, p_body text, p_anchor jsonb DEFAULT '{}'::jsonb, p_parent_comment_id uuid DEFAULT NULL::uuid, p_mentions uuid[] DEFAULT NULL::uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"computed_block\", args: \"p_block jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"computed_provenance\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(field_key text, field_id uuid, value jsonb, rule_id uuid, rule_version integer, computed_at timestamp with time zone)\", security: \"definer\" },\n { name: \"confidential_anchor\", args: \"p_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"confidential_answer\", args: \"p_user uuid, p_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level\", returns: \"boolean\", security: \"definer\" },\n { name: \"confidential_header\", args: \"p_user uuid, p_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"confidential_names\", args: \"p_organization_id uuid, p_value jsonb, p_user uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"containment_chain\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(ancestor_id uuid, depth integer)\", security: \"invoker\" },\n { name: \"containment_depth_ceiling\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"integer\", security: \"invoker\" },\n { name: \"containment_edges\", args: \"p_organization_id uuid\", returns: \"TABLE(parent_id uuid, child_id uuid, via text)\", security: \"invoker\" },\n { name: \"containment_parent\", args: \"p_data jsonb\", returns: \"uuid\", security: \"invoker\" },\n { name: \"context_archived_types\", args: \"p_organization_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_class_for_checkout\", args: \"p_scope_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_compare_facts\", args: \"p_user_id uuid, p_record_ids uuid[], p_item_ids uuid[] DEFAULT NULL::uuid[], p_cells jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_item_archive\", args: \"p_item_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_item_restore\", args: \"p_item_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_item_row_of\", args: \"p_field custom.record\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"context_item_write\", args: \"p_item_id uuid, p_scope_type_id uuid, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_items\", args: \"p_scope_type_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_policy_rank\", args: \"p_policy text\", returns: \"integer\", security: \"invoker\" },\n { name: \"context_resolve\", args: \"p_bindings jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_scope_archive\", args: \"p_scope_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_scope_restore\", args: \"p_scope_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_scope_write\", args: \"p_organization_id uuid, p_scope_id uuid, p_type_id uuid, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_scopes\", args: \"p_scope_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_system_items\", args: \"\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_tags_set\", args: \"p_entity_type text, p_entity_id uuid, p_scope_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_template_define\", args: \"p_organization_id uuid, p_definition jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"context_templates\", args: \"\", returns: \"SETOF jsonb\", security: \"invoker\" },\n { name: \"context_tree\", args: \"p_organization_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_tree_search\", args: \"p_organization_ids uuid[], p_query text, p_limit integer DEFAULT 100\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_tree_type_scopes\", args: \"p_scope_type_id uuid, p_offset integer DEFAULT 0, p_limit integer DEFAULT 200\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_tree_types\", args: \"p_organization_ids uuid[], p_with_counts boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_type_archive\", args: \"p_type_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_type_restore\", args: \"p_type_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_type_write\", args: \"p_organization_id uuid, p_type_id uuid, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_value_write\", args: \"p_payload jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"context_values\", args: \"p_scope_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"context_writer\", args: \"p_organization_id uuid\", returns: \"text\", security: \"definer\" },\n { name: \"conversation_scope\", args: \"p_organization_id uuid, p_conversation_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"conversation_scope_bind\", args: \"p_organization_id uuid, p_conversation_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"conversation_scope_context\", args: \"p_organization_id uuid, p_conversation_id uuid, p_relations integer DEFAULT 12, p_history integer DEFAULT 15, p_siblings integer DEFAULT 8\", returns: \"jsonb\", security: \"definer\" },\n { name: \"conversation_scope_unbind\", args: \"p_organization_id uuid, p_conversation_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"count_records_archived\", args: \"p_organization_id uuid, p_table_ids uuid[], p_lane text DEFAULT 'org'::text\", returns: \"TABLE(table_id uuid, n integer)\", security: \"definer\" },\n { name: \"cross_organization_links_open\", args: \"p_source_organization_id uuid, p_target_organization_id uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"custom_fields_tables\", args: \"\", returns: \"TABLE(token text, schema_name text, table_name text)\", security: \"invoker\" },\n { name: \"dashboard_block_normalize\", args: \"p_organization_id uuid, p_subject_table_id uuid, p_block jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"dashboard_class\", args: \"\", returns: \"text\", security: \"invoker\" },\n { name: \"dashboard_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_name text, p_blocks jsonb DEFAULT '[]'::jsonb, p_presentation jsonb DEFAULT '{}'::jsonb, p_dashboard_id uuid DEFAULT NULL::uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"dashboard_delete\", args: \"p_organization_id uuid, p_dashboard_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"dashboard_field_keys\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"text[]\", security: \"definer\" },\n { name: \"dashboard_kinds\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"dashboard_moment_sql\", args: \"p_key text\", returns: \"text\", security: \"invoker\" },\n { name: \"dashboard_restore\", args: \"p_organization_id uuid, p_dashboard_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"dashboard_run\", args: \"p_organization_id uuid, p_dashboard_id uuid, p_filter jsonb DEFAULT '{}'::jsonb, p_compare jsonb DEFAULT NULL::jsonb, p_grain text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"dashboard_stuck\", args: \"p_organization_id uuid, p_table_id uuid, p_state_key text, p_days integer DEFAULT 14, p_filter jsonb DEFAULT '{}'::jsonb, p_limit integer DEFAULT 50, p_required text DEFAULT 'viewer'::text\", returns: \"TABLE(record_id uuid, title text, state text, last_changed_at timestamp with time zone, days_unchanged numeric, measured_from text)\", security: \"definer\" },\n { name: \"dashboard_target_field_assert\", args: \"p_organization_id uuid, p_table_id uuid, p_field_key text\", returns: \"void\", security: \"invoker\" },\n { name: \"dashboard_window_sql\", args: \"p_key text, p_window jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"dashboards\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(dashboard_id uuid, table_id uuid, name text, blocks jsonb, presentation jsonb, block_count integer, version integer, created_at timestamp with time zone, updated_at timestamp with time zone)\", security: \"definer\" },\n { name: \"data_home\", args: \"p_organization_id uuid DEFAULT NULL::uuid, p_search text DEFAULT NULL::text, p_include_app_tables boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\n { name: \"data_home_changed_by\", args: \"p_asks jsonb\", returns: \"TABLE(organization_id uuid, id uuid, at timestamp with time zone, who text)\", security: \"definer\" },\n { name: \"data_home_items\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(kind text, organization_id uuid, organization_name text, item_id uuid, table_id uuid, table_name text, item_row jsonb)\", security: \"definer\" },\n { name: \"data_home_tables\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(table_id uuid, table_name text, organization_id uuid, organization_name text, member boolean, visibility text, updated_at timestamp with time zone, mine boolean, shared_with_me boolean, kept_by_the_app boolean, kind text, team boolean, system boolean, created_by uuid)\", security: \"definer\" },\n { name: \"data_home_tables\", args: \"p_organization_id uuid, p_include_app_tables boolean\", returns: \"TABLE(table_id uuid, table_name text, organization_id uuid, organization_name text, member boolean, visibility text, updated_at timestamp with time zone, mine boolean, shared_with_me boolean, kept_by_the_app boolean, kind text, team boolean, system boolean, created_by uuid)\", security: \"invoker\" },\n { name: \"declared_conversation\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"decoration_colors\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"decoration_rule_ops\", args: \"\", returns: \"TABLE(op text, takes_value boolean, label text)\", security: \"invoker\" },\n { name: \"delete_cascade_closure\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"uuid[]\", security: \"invoker\" },\n { name: \"delete_preview\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"delete_rule\", args: \"p_organization_id uuid, p_record_id uuid, p_apply boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"dependency_cycle\", args: \"p_organization_id uuid, p_row custom.record\", returns: \"text[]\", security: \"invoker\" },\n { name: \"dependency_label\", args: \"p_organization_id uuid, p_node text\", returns: \"text\", security: \"invoker\" },\n { name: \"derive_visibility\", args: \"p_container_type text, p_container_id uuid\", returns: \"TABLE(item_type text, item_id uuid, depth integer, max_level permission_level)\", security: \"definer\" },\n { name: \"derived_value\", args: \"p_organization_id uuid, p_record_id uuid, p_field_data jsonb, p_values jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"derived_values\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"derived_values_of\", args: \"v_rec custom.record\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"display_format_ids\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"doc_content_hash\", args: \"p_body text\", returns: \"text\", security: \"invoker\" },\n { name: \"doc_format_value\", args: \"p_field_data jsonb, p_value jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"doc_letterhead\", args: \"p_organization_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"doc_name_token_pattern\", args: \"\", returns: \"text\", security: \"invoker\" },\n { name: \"doc_name_tokens\", args: \"p_body text\", returns: \"TABLE(ordinal integer, raw text)\", security: \"invoker\" },\n { name: \"doc_render_body\", args: \"p_organization_id uuid, p_template_id uuid, p_record_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"doc_render_document\", args: \"p_organization_id uuid, p_template_id uuid, p_record_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"doc_render_read\", args: \"p_organization_id uuid, p_render_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"doc_render_write\", args: \"p_organization_id uuid, p_template_id uuid, p_record_id uuid, p_table_id uuid, p_template_version integer, p_body text, p_content_hash text\", returns: \"uuid\", security: \"definer\" },\n { name: \"doc_renders\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(render_id uuid, template_id uuid, record_id uuid, table_id uuid, template_version integer, body text, content_hash text, rendered_at timestamp with time zone)\", security: \"definer\" },\n { name: \"doc_sign\", args: \"p_organization_id uuid, p_render_id uuid, p_field_key text, p_signer_name text, p_signer_user_id uuid DEFAULT NULL::uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"doc_signature_field_ok\", args: \"p_field_data jsonb\", returns: \"boolean\", security: \"invoker\" },\n { name: \"doc_signature_intact\", args: \"p_organization_id uuid, p_signature_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"doc_signature_read\", args: \"p_organization_id uuid, p_signature_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"doc_signature_write\", args: \"p_organization_id uuid, p_render_id uuid, p_record_id uuid, p_field_key text, p_signer_name text, p_signer_user_id uuid, p_document_hash text, p_document_version integer\", returns: \"uuid\", security: \"definer\" },\n { name: \"doc_signatures\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(signature_id uuid, render_id uuid, record_id uuid, field_key text, signer_name text, signer_user_id uuid, signed_at timestamp with time zone, document_hash text, document_version integer)\", security: \"definer\" },\n { name: \"doc_template_delete\", args: \"p_organization_id uuid, p_template_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"doc_template_read\", args: \"p_organization_id uuid, p_template_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"doc_template_restore\", args: \"p_organization_id uuid, p_template_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"doc_template_save\", args: \"p_organization_id uuid, p_table_id uuid, p_name text, p_body text, p_template_id uuid DEFAULT NULL::uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"doc_templates\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(template_id uuid, renders_table_id uuid, name text, body text, template_version integer, token_count bigint, updated_at timestamp with time zone)\", security: \"definer\" },\n { name: \"doc_token_pattern\", args: \"\", returns: \"text\", security: \"invoker\" },\n { name: \"doc_tokens\", args: \"p_body text\", returns: \"TABLE(ordinal integer, raw text, field_id uuid)\", security: \"invoker\" },\n { name: \"doc_unresolved_tokens\", args: \"p_organization_id uuid, p_table_id uuid, p_body text\", returns: \"TABLE(raw text, field_id uuid, why text)\", security: \"invoker\" },\n { name: \"doors_not_deciding_the_caller\", args: \"\", returns: \"TABLE(function_name text, identity_args text)\", security: \"invoker\" },\n { name: \"doors_not_deciding_the_record\", args: \"\", returns: \"TABLE(function_name text, identity_args text, why text)\", security: \"invoker\" },\n { name: \"doors_not_masking_fields\", args: \"\", returns: \"TABLE(function_name text, identity_args text, why text)\", security: \"invoker\" },\n { name: \"doors_not_on_one_ladder\", args: \"\", returns: \"TABLE(function_name text, identity_args text, why text)\", security: \"invoker\" },\n { name: \"doors_refusing_in_another_doors_name\", args: \"\", returns: \"TABLE(function_name text, identity_args text, why text)\", security: \"invoker\" },\n { name: \"drill_resolve\", args: \"p_organization_id uuid, p_table_id uuid, p_group_by jsonb, p_measures jsonb, p_bucket jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"effective_level\", args: \"p_user_id uuid, p_organization_id uuid, p_id uuid, p_type text DEFAULT 'record'::text\", returns: \"permission_level\", security: \"definer\" },\n { name: \"enrich_cells\", args: \"p_organization_id uuid, p_table_id uuid, p_field_keys text[] DEFAULT NULL::text[], p_record_ids uuid[] DEFAULT NULL::uuid[]\", returns: \"TABLE(record_id uuid, field_key text, agent_owned boolean, value jsonb, value_version integer, actor text, on_behalf_of text, written_at timestamp with time zone, source jsonb, absent_reason text, alternates jsonb, pinned boolean, stale boolean, due_at timestamp with time zone)\", security: \"definer\" },\n { name: \"enrich_declare\", args: \"p_organization_id uuid, p_field_id uuid, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"enrich_due\", args: \"p_organization_id uuid, p_field_id uuid, p_limit integer DEFAULT 50, p_include_fresh boolean DEFAULT false, p_record_ids uuid[] DEFAULT NULL::uuid[]\", returns: \"TABLE(record_id uuid, title text, inputs jsonb, current_value jsonb, written_at timestamp with time zone, reason text, trimmed_to integer)\", security: \"definer\" },\n { name: \"enrich_land\", args: \"p_organization_id uuid, p_field_id uuid, p_results jsonb, p_run jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"enrich_normalize\", args: \"p_organization_id uuid, p_table_id uuid, p_field_key text, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"enrich_pin\", args: \"p_organization_id uuid, p_record_id uuid, p_field_key text, p_pinned boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"enrich_run_class\", args: \"\", returns: \"text\", security: \"invoker\" },\n { name: \"enrich_runs\", args: \"p_organization_id uuid, p_field_id uuid DEFAULT NULL::uuid, p_limit integer DEFAULT 50\", returns: \"TABLE(run_id uuid, field_id uuid, field_key text, model text, trigger_word text, rows_seen integer, rows_written integer, rows_absent integer, rows_below_floor integer, rows_pinned integer, rows_refused integer, cost_cents numeric, cost_per_row_cents numeric, ran_at timestamp with time zone)\", security: \"definer\" },\n { name: \"enrich_sensitivity_rank\", args: \"p_word text\", returns: \"integer\", security: \"invoker\" },\n { name: \"enrich_triggers\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"enrichments\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(field_id uuid, table_id uuid, field_key text, label text, enrichment jsonb, enabled boolean, review_interval_days integer, rows_total integer, rows_filled integer, rows_stale integer, rows_pinned integer, rows_absent integer, runs integer, cost_cents numeric, cost_per_row_cents numeric, last_run_at timestamp with time zone, last_run jsonb)\", security: \"definer\" },\n { name: \"entity_field_declare\", args: \"p_organization_id uuid, p_token text, p_spec jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"entity_field_protect_arman_explicitly_approved\", args: \"p_field_id uuid, p_readers jsonb, p_arman_words text, p_approved_on date\", returns: \"jsonb\", security: \"definer\" },\n { name: \"entity_field_retire\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"entity_field_rights\", args: \"p_organization_id uuid, p_token text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"entity_field_update\", args: \"p_organization_id uuid, p_field_id uuid, p_patch jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"entity_fields\", args: \"p_organization_id uuid, p_token text\", returns: \"SETOF custom.record\", security: \"definer\" },\n { name: \"entity_fields_across\", args: \"p_token text, p_organization_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"entity_read_mask\", args: \"p_organization_id uuid, p_token text, p_level permission_level, p_action text DEFAULT 'read'::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"entity_record_home\", args: \"p_token text, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_record_read\", args: \"p_organization_id uuid, p_token text, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_records_find\", args: \"p_organization_id uuid, p_token text, p_key text, p_value jsonb DEFAULT NULL::jsonb, p_limit integer DEFAULT 50, p_offset integer DEFAULT 0\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_reference_fields\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_reference_kinds\", args: \"\", returns: \"TABLE(token text, label text, category text)\", security: \"definer\" },\n { name: \"entity_reference_render\", args: \"p_organization_id uuid, p_table_id uuid, p_doc jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_reference_render_with\", args: \"p_organization_id uuid, p_table_id uuid, p_doc jsonb, p_fields jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_reference_rows\", args: \"p_organization_id uuid, p_token text, p_ids uuid[]\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_reference_search\", args: \"p_organization_id uuid, p_tokens text[], p_search text DEFAULT NULL::text, p_limit integer DEFAULT 20\", returns: \"jsonb\", security: \"definer\" },\n { name: \"entity_reference_target\", args: \"p_token text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"entity_reference_words\", args: \"p_organization_id uuid, p_refs jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"entity_row_propose\", args: \"p_organization_id uuid, p_token text, p_record_id uuid, p_columns jsonb DEFAULT '{}'::jsonb, p_custom jsonb DEFAULT '{}'::jsonb, p_expected_version integer DEFAULT NULL::integer, p_archive boolean DEFAULT NULL::boolean, p_note text DEFAULT NULL::text, p_conversation_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_row_write\", args: \"p_organization_id uuid, p_token text, p_record_id uuid, p_columns jsonb DEFAULT '{}'::jsonb, p_custom jsonb DEFAULT '{}'::jsonb, p_expected_version integer DEFAULT NULL::integer, p_archive boolean DEFAULT NULL::boolean\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"entity_seat_level\", args: \"p_organization_id uuid, p_token text, p_record_id uuid\", returns: \"permission_level\", security: \"invoker\" },\n { name: \"entity_table\", args: \"p_token text\", returns: \"TABLE(token text, schema_name text, table_name text, type text, title_column text, label text, has_organization boolean, has_deleted_at boolean)\", security: \"definer\" },\n { name: \"entity_value_write\", args: \"p_organization_id uuid, p_token text, p_record_id uuid, p_patch jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"export_ceiling\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"integer\", security: \"invoker\" },\n { name: \"export_records\", args: \"p_organization_id uuid, p_table_id uuid, p_limit integer DEFAULT 1000\", returns: \"TABLE(id uuid, document jsonb)\", security: \"invoker\" },\n { name: \"external_foreign_table_findings\", args: \"\", returns: \"SETOF text\", security: \"definer\" },\n { name: \"external_history_event\", args: \"p_organization_id uuid, p_link_id uuid, p_operation text\", returns: \"bigint\", security: \"definer\" },\n { name: \"external_rows\", args: \"p_organization_id uuid, p_source_id uuid\", returns: \"SETOF jsonb\", security: \"definer\" },\n { name: \"external_source_declare\", args: \"p_organization_id uuid, p_tier text, p_connection_token text, p_external_schema text, p_external_table text, p_link_template text\", returns: \"uuid\", security: \"definer\" },\n { name: \"external_stub_upsert\", args: \"p_organization_id uuid, p_source_id uuid, p_table_id uuid, p_external_key text, p_link_url text, p_cached_title text\", returns: \"uuid\", security: \"definer\" },\n { name: \"external_tier_contract\", args: \"\", returns: \"jsonb\", security: \"definer\" },\n { name: \"external_write_through\", args: \"p_organization_id uuid, p_record_id uuid, p_patch jsonb\", returns: \"void\", security: \"definer\" },\n { name: \"external_writes_set\", args: \"p_organization_id uuid, p_source_id uuid, p_enabled boolean\", returns: \"boolean\", security: \"definer\" },\n { name: \"far_value\", args: \"p_organization_id uuid, p_record_id uuid, p_key text, p_reader jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"field_access\", args: \"p_user uuid, p_field_id uuid, p_token text, p_row_id uuid, p_action text, p_audit boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"field_add_rung\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"permission_level\", security: \"invoker\" },\n { name: \"field_behaviour\", args: \"p_field_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"field_choice_usage\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"field_context_policy_floor\", args: \"p_organization_id uuid, p_field_data jsonb, p_self uuid DEFAULT NULL::uuid\", returns: \"TABLE(context_policy text, reads jsonb)\", security: \"definer\" },\n { name: \"field_cycle\", args: \"p_organization_id uuid, p_field_data jsonb, p_self uuid\", returns: \"text[]\", security: \"definer\" },\n { name: \"field_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_spec jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"field_dependants\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"TABLE(kind text, dependant_id uuid, label text, how text)\", security: \"definer\" },\n { name: \"field_history\", args: \"p_organization_id uuid, p_table_id uuid, p_field_key text, p_limit integer DEFAULT 100, p_offset integer DEFAULT 0, p_record_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(record_id uuid, record_title text, version integer, occurred_at timestamp with time zone, operation_label text, actor jsonb, before jsonb, after jsonb)\", security: \"definer\" },\n { name: \"field_input_closure\", args: \"p_organization_id uuid, p_field_data jsonb, p_self uuid DEFAULT NULL::uuid\", returns: \"TABLE(input_id uuid, input_key text, input_label text, input_table uuid, sensitivity text, retired boolean, depth integer)\", security: \"definer\" },\n { name: \"field_inputs_of\", args: \"p_organization_id uuid, p_field_data jsonb\", returns: \"TABLE(input_id uuid, input_key text, input_label text, input_table uuid, sensitivity text, retired boolean, how text)\", security: \"definer\" },\n { name: \"field_is_protected\", args: \"p_data jsonb\", returns: \"boolean\", security: \"invoker\" },\n { name: \"field_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"field_kind_of\", args: \"p_field_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"field_kinds\", args: \"\", returns: \"TABLE(kind text, behavior text, parity boolean, made_of text)\", security: \"invoker\" },\n { name: \"field_options\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"SETOF custom.record\", security: \"definer\" },\n { name: \"field_protection_refusal\", args: \"p_op text, p_old jsonb, p_new jsonb, p_field_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"field_restore\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"field_retire\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"field_rules\", args: \"p_field_data jsonb\", returns: \"TABLE(kind text, spec jsonb)\", security: \"invoker\" },\n { name: \"field_sensitivity_floor\", args: \"p_organization_id uuid, p_field_data jsonb, p_self uuid DEFAULT NULL::uuid\", returns: \"TABLE(sensitivity text, reads jsonb)\", security: \"definer\" },\n { name: \"field_source_archived\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"field_update\", args: \"p_organization_id uuid, p_field_id uuid, p_patch jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"field_update_rehoming_choices\", args: \"p_organization_id uuid, p_field_id uuid, p_patch jsonb, p_rehome jsonb DEFAULT NULL::jsonb, p_cells_back jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"field_value_convert\", args: \"p_to jsonb, p_value jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"field_value_kind\", args: \"p_organization_id uuid, p_field_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"field_words\", args: \"p_organization_id uuid, p_field_id uuid, p_value jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"file_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"filter_is_rule\", args: \"p_filter jsonb\", returns: \"boolean\", security: \"invoker\" },\n { name: \"form_archive\", args: \"p_organization_id uuid, p_form_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"form_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_title text, p_questions jsonb, p_presentation jsonb DEFAULT '{}'::jsonb, p_submission_cap integer DEFAULT NULL::integer, p_quarantine_rule_id uuid DEFAULT NULL::uuid, p_notify_rule_id uuid DEFAULT NULL::uuid, p_form_id uuid DEFAULT NULL::uuid, p_slug text DEFAULT NULL::text\", returns: \"uuid\", security: \"definer\" },\n { name: \"form_draft_read\", args: \"p_form_id uuid, p_secret text\", returns: \"TABLE(answers jsonb, saved_at timestamp with time zone, expires_at timestamp with time zone, state text, message text)\", security: \"definer\" },\n { name: \"form_draft_save\", args: \"p_form_id uuid, p_answers jsonb, p_secret text DEFAULT NULL::text, p_bucket text DEFAULT NULL::text, p_origin text DEFAULT NULL::text\", returns: \"TABLE(draft_secret text, saved_at timestamp with time zone, expires_at timestamp with time zone, state text, message text)\", security: \"definer\" },\n { name: \"form_look_options\", args: \"p_organization_id uuid, p_presentation jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"form_notify\", args: \"p_organization_id uuid, p_form_id uuid, p_record_id uuid, p_submission_id uuid\", returns: \"uuid\", security: \"invoker\" },\n { name: \"form_preview_asks\", args: \"p_organization_id uuid, p_table_id uuid, p_questions jsonb, p_values jsonb\", returns: \"TABLE(field_key text, asked boolean, decided boolean, said text)\", security: \"definer\" },\n { name: \"form_public\", args: \"p_form_id uuid\", returns: \"TABLE(form_id uuid, organization_id uuid, table_id uuid, title text, presentation jsonb, fields jsonb, honeypot_key text, state text, message text)\", security: \"definer\" },\n { name: \"form_public_asks\", args: \"p_form_id uuid, p_values jsonb, p_secret text DEFAULT NULL::text, p_origin text DEFAULT NULL::text\", returns: \"TABLE(field_key text, asked boolean, decided boolean, said text)\", security: \"definer\" },\n { name: \"form_redirect_domains\", args: \"p_organization_id uuid\", returns: \"text[]\", security: \"invoker\" },\n { name: \"form_redirect_refusal\", args: \"p_organization_id uuid, p_url text\", returns: \"text\", security: \"invoker\" },\n { name: \"form_restore\", args: \"p_organization_id uuid, p_form_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"form_slug\", args: \"p_organization_id uuid, p_title text, p_form_id uuid DEFAULT NULL::uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"form_submit\", args: \"p_form_id uuid, p_origin text, p_payload jsonb, p_bucket text, p_honeypot text DEFAULT NULL::text, p_client_key text DEFAULT NULL::text\", returns: \"TABLE(submission_id uuid, record_id uuid, state text, message text)\", security: \"definer\" },\n { name: \"forms\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(form_id uuid, table_id uuid, title text, slug text, published_at timestamp with time zone, closed_at timestamp with time zone, submission_cap integer, responses bigint, in_table bigint, held bigint, rejected bigint, state text, quarantine_rule_id uuid, notify_rule_id uuid, presentation jsonb)\", security: \"definer\" },\n { name: \"forms_archived\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_limit integer DEFAULT 100\", returns: \"TABLE(form_id uuid, table_id uuid, table_name text, kind text, title text, slug text, archived_at timestamp with time zone, archived_by uuid, table_archived boolean, can_restore boolean)\", security: \"definer\" },\n { name: \"formula_compile_sql\", args: \"p_organization_id uuid, p_expr jsonb, p_values_sql text\", returns: \"text\", security: \"invoker\" },\n { name: \"formula_eval\", args: \"p_organization_id uuid, p_expr jsonb, p_values jsonb, p_context jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"formula_field_keys\", args: \"p_organization_id uuid, p_expr jsonb\", returns: \"text[]\", security: \"invoker\" },\n { name: \"formula_node_kinds\", args: \"\", returns: \"TABLE(node text, min_args integer, max_args integer, result text, signature text, says text)\", security: \"invoker\" },\n { name: \"formula_parse\", args: \"p_organization_id uuid, p_table_id uuid, p_text text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"formula_result_kind\", args: \"p_organization_id uuid, p_expr jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"formula_value\", args: \"p_organization_id uuid, p_record_id uuid, p_field_data jsonb, p_values jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"freshness_verdict\", args: \"p_written_at timestamp with time zone, p_ceiling_seconds numeric\", returns: \"jsonb\", security: \"definer\" },\n { name: \"grid_layout\", args: \"p_organization_id uuid, p_table_id uuid, p_view_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"grid_layout_check\", args: \"p_layout jsonb, p_scope text DEFAULT 'view'::text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"guard_refusals_are_complete\", args: \"\", returns: \"TABLE(guard text, said text)\", security: \"invoker\" },\n { name: \"has_visibility\", args: \"p_user_id uuid, p_type text, p_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level\", returns: \"boolean\", security: \"definer\" },\n { name: \"has_visibility_at\", args: \"p_user_id uuid, p_type text, p_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level, p_organization_id uuid DEFAULT NULL::uuid, p_min_version bigint DEFAULT NULL::bigint\", returns: \"boolean\", security: \"definer\" },\n { name: \"hidden_field_notice\", args: \"p_field custom.record, p_action text DEFAULT 'read'::text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"history_actor\", args: \"p_tier text, p_document jsonb, p_actor_id uuid, p_people jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"history_changes\", args: \"p_organization_id uuid, p_table_id uuid, p_old jsonb, p_new jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"history_people\", args: \"p_organization_id uuid, p_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"history_prune\", args: \"p_organization_id uuid, p_scope text DEFAULT 'values'::text, p_table_id uuid DEFAULT NULL::uuid, p_dry_run boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"history_restore_body\", args: \"p_current jsonb, p_target jsonb, p_field_key text DEFAULT NULL::text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"history_restore_body\", args: \"p_current jsonb, p_target jsonb, p_field_key text, p_author jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"history_retention\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"history_retention_floor_raise\", args: \"p_organization_id uuid, p_days integer\", returns: \"integer\", security: \"definer\" },\n { name: \"history_retention_set\", args: \"p_organization_id uuid, p_table_id uuid, p_days integer\", returns: \"integer\", security: \"definer\" },\n { name: \"home_add\", args: \"p_organization_id uuid, p_table_id uuid, p_home_record_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"home_relations\", args: \"\", returns: \"TABLE(table_id uuid, home_record_id uuid, organization_id uuid, relation_id uuid)\", security: \"invoker\" },\n { name: \"hub_changed_by\", args: \"p_organization_id uuid, p_kind text, p_ids uuid[]\", returns: \"TABLE(id uuid, at timestamp with time zone, who text)\", security: \"definer\" },\n { name: \"inbound_addresses\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"inbound_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_label text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"inbound_domain\", args: \"p_organization_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"inbound_mail_land\", args: \"p_address text, p_mail jsonb, p_secret text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"inbound_mail_map\", args: \"p_organization_id uuid, p_table_id uuid, p_mail jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"inbound_set\", args: \"p_organization_id uuid, p_inbound_id uuid, p_enabled boolean\", returns: \"jsonb\", security: \"definer\" },\n { name: \"inbox_clear\", args: \"p_organization_id uuid, p_item_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"inbox_counts\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(organization_id uuid, organization_name text, waiting integer, snoozed integer, cleared integer, overdue integer, oldest_waiting_at timestamp with time zone)\", security: \"definer\" },\n { name: \"inbox_remind_tick\", args: \"\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"inbox_snooze\", args: \"p_organization_id uuid, p_item_id uuid, p_until timestamp with time zone\", returns: \"jsonb\", security: \"definer\" },\n { name: \"inbox_unclear\", args: \"p_organization_id uuid, p_item_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"inbox_unsnooze\", args: \"p_organization_id uuid, p_item_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"index_payload\", args: \"p_organization_id uuid, p_table_id uuid, p_limit integer DEFAULT 1000\", returns: \"TABLE(id uuid, searchable text)\", security: \"invoker\" },\n { name: \"intern_provenance\", args: \"p_data jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"io_cell\", args: \"p_organization_id uuid, p_field jsonb, p_word text, p_date_order text DEFAULT 'mdy'::text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"io_change_actor\", args: \"\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"io_change_fields\", args: \"p_keys text[], p_old jsonb, p_new jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"io_change_via\", args: \"\", returns: \"text\", security: \"invoker\" },\n { name: \"io_changed_field_ids\", args: \"p_organization_id uuid, p_table_id uuid, p_old jsonb, p_new jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"io_changed_keys\", args: \"p_old jsonb, p_new jsonb\", returns: \"text[]\", security: \"invoker\" },\n { name: \"io_comment_resolve\", args: \"p_organization_id uuid, p_comment_id uuid, p_resolved boolean DEFAULT true\", returns: \"boolean\", security: \"definer\" },\n { name: \"io_comment_write\", args: \"p_organization_id uuid, p_record_id uuid, p_body text, p_anchor jsonb DEFAULT '{}'::jsonb, p_parent_comment_id uuid DEFAULT NULL::uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"io_comments\", args: \"p_organization_id uuid, p_record_id uuid, p_include_resolved boolean DEFAULT false\", returns: \"TABLE(id uuid, body text, anchor jsonb, parent_comment_id uuid, created_by uuid, created_at timestamp with time zone, resolved_at timestamp with time zone, resolved_by uuid)\", security: \"definer\" },\n { name: \"io_csv_escape\", args: \"p_value text, p_delimiter text DEFAULT ','::text\", returns: \"text\", security: \"invoker\" },\n { name: \"io_csv_parse\", args: \"p_text text, p_delimiter text DEFAULT NULL::text\", returns: \"TABLE(row_number integer, cells text[])\", security: \"invoker\" },\n { name: \"io_export\", args: \"p_organization_id uuid, p_table_id uuid, p_columns text[] DEFAULT NULL::text[], p_limit integer DEFAULT 10000, p_required text DEFAULT 'viewer'::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_export_csv\", args: \"p_organization_id uuid, p_table_id uuid, p_columns text[] DEFAULT NULL::text[], p_limit integer DEFAULT 10000, p_delimiter text DEFAULT chr(44), p_required text DEFAULT 'viewer'::text\", returns: \"text\", security: \"definer\" },\n { name: \"io_import_begin\", args: \"p_organization_id uuid, p_table_id uuid, p_format text DEFAULT 'csv'::text, p_source_name text DEFAULT NULL::text, p_source_columns jsonb DEFAULT '[]'::jsonb, p_file_hash text DEFAULT NULL::text, p_policy jsonb DEFAULT '{}'::jsonb, p_dedupe_key text DEFAULT NULL::text, p_file_bytes bigint DEFAULT NULL::bigint, p_force boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_import_declare_columns\", args: \"p_organization_id uuid, p_table_id uuid, p_rows jsonb, p_mapping jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_import_finish\", args: \"p_organization_id uuid, p_import_id uuid, p_unmapped text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_import_forget\", args: \"p_organization_id uuid, p_import_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"io_import_open\", args: \"p_organization_id uuid, p_table_id uuid, p_format text DEFAULT 'csv'::text, p_source_name text DEFAULT NULL::text, p_source_columns jsonb DEFAULT '[]'::jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"io_import_plan\", args: \"p_organization_id uuid, p_table_id uuid, p_columns jsonb DEFAULT '[]'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_import_report\", args: \"p_organization_id uuid, p_import_id uuid, p_state text DEFAULT NULL::text, p_limit integer DEFAULT 100, p_offset integer DEFAULT 0\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_import_rows\", args: \"p_organization_id uuid, p_import_id uuid, p_rows jsonb, p_mapping jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_imports\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_limit integer DEFAULT 25\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_infer_column\", args: \"p_organization_id uuid, p_table_id uuid, p_header text, p_samples jsonb DEFAULT '[]'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"io_infer_type\", args: \"p_samples jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"io_money_unit\", args: \"p_word text\", returns: \"text\", security: \"invoker\" },\n { name: \"io_outbox_announce\", args: \"\", returns: \"trigger\", security: \"definer\" },\n { name: \"io_outbox_backlog\", args: \"p_consumer text, p_event_key text, p_older_than interval DEFAULT '00:00:00'::interval\", returns: \"TABLE(organization_id uuid, waiting bigint, oldest timestamp with time zone, last_carried timestamp with time zone)\", security: \"definer\" },\n { name: \"io_outbox_broadcast_stmt\", args: \"\", returns: \"trigger\", security: \"definer\" },\n { name: \"io_outbox_consumed_by\", args: \"p_event_id uuid, p_consumer text, p_consumed_at timestamp with time zone\", returns: \"boolean\", security: \"invoker\" },\n { name: \"io_outbox_drain\", args: \"p_organization_id uuid, p_consumer text, p_limit integer DEFAULT 100, p_event_key text DEFAULT 'records.changed'::text\", returns: \"TABLE(outbox_id uuid, record_id uuid, table_id uuid, operation text, changed_field_ids jsonb, actor jsonb, occurred_at timestamp with time zone)\", security: \"definer\" },\n { name: \"io_outbox_last_consumed\", args: \"p_consumer text, p_event_key text, p_organization_id uuid\", returns: \"timestamp with time zone\", security: \"invoker\" },\n { name: \"io_outbox_pending_organizations\", args: \"p_consumer text, p_event_key text\", returns: \"SETOF uuid\", security: \"definer\" },\n { name: \"io_outbox_per_consumer\", args: \"\", returns: \"boolean\", security: \"invoker\" },\n { name: \"io_outbox_rearm\", args: \"p_organization_id uuid, p_dedupe_key text\", returns: \"void\", security: \"definer\" },\n { name: \"io_outbox_release\", args: \"p_organization_id uuid, p_consumer text, p_older_than interval DEFAULT '00:15:00'::interval\", returns: \"integer\", security: \"definer\" },\n { name: \"io_outbox_release_claimed\", args: \"p_organization_id uuid, p_consumer text, p_ids uuid[]\", returns: \"integer\", security: \"definer\" },\n { name: \"io_outbox_subscribe\", args: \"p_consumer text, p_event_key text\", returns: \"timestamp with time zone\", security: \"definer\" },\n { name: \"io_proposal_accept\", args: \"p_organization_id uuid, p_import_id uuid, p_column text, p_type text DEFAULT NULL::text, p_label text DEFAULT NULL::text\", returns: \"uuid\", security: \"definer\" },\n { name: \"io_proposal_reject\", args: \"p_organization_id uuid, p_import_id uuid, p_column text\", returns: \"boolean\", security: \"definer\" },\n { name: \"io_proposal_spec\", args: \"p_proposal jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"io_record_changed\", args: \"\", returns: \"trigger\", security: \"definer\" },\n { name: \"io_record_changed_stmt_delete\", args: \"\", returns: \"trigger\", security: \"definer\" },\n { name: \"io_record_changed_stmt_insert\", args: \"\", returns: \"trigger\", security: \"definer\" },\n { name: \"io_record_changed_stmt_update\", args: \"\", returns: \"trigger\", security: \"definer\" },\n { name: \"io_relation_candidate\", args: \"p_organization_id uuid, p_table_id uuid, p_words text[]\", returns: \"uuid\", security: \"invoker\" },\n { name: \"io_restore\", args: \"p_organization_id uuid, p_record_id uuid, p_version integer\", returns: \"integer\", security: \"definer\" },\n { name: \"io_restore\", args: \"p_organization_id uuid, p_record_id uuid, p_version integer, p_author jsonb\", returns: \"integer\", security: \"definer\" },\n { name: \"io_revisions\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(version integer, changed_at timestamp with time zone, changed_by uuid, summary text, operation text, changed_fields jsonb)\", security: \"definer\" },\n { name: \"io_sample_words\", args: \"p_samples jsonb\", returns: \"TABLE(word text)\", security: \"invoker\" },\n { name: \"io_value_shape\", args: \"p_envelope jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"io_workflow_chain\", args: \"\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"is_a_retirement\", args: \"p_old_deleted timestamp with time zone, p_new_deleted timestamp with time zone, p_old_data jsonb, p_new_data jsonb, p_old_table uuid, p_new_table uuid, p_old_org uuid, p_new_org uuid, p_old_class text, p_new_class text\", returns: \"boolean\", security: \"invoker\" },\n { name: \"ladder_replanners\", args: \"p_roots text[] DEFAULT ARRAY['custom.has_visibility'::text, 'custom.effective_level'::text, 'custom.reaches_directly'::text, 'custom.visible_set'::text]\", returns: \"TABLE(fn text, lang text, why text, remedy text)\", security: \"definer\" },\n { name: \"level_floor\", args: \"\", returns: \"permission_level\", security: \"definer\" },\n { name: \"levels_of\", args: \"p_user_id uuid, p_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"levels_raised_by_a_less_specific_rung\", args: \"\", returns: \"TABLE(organization_id uuid, organization_name text, member_id uuid, member_email text, record_id uuid, addressed_level permission_level, answered_level permission_level)\", security: \"definer\" },\n { name: \"list_door_disagreements\", args: \"p_pretend text DEFAULT NULL::text, p_only_organization uuid DEFAULT NULL::uuid, p_sample integer DEFAULT 200\", returns: \"TABLE(organization_id uuid, organization_name text, member_id uuid, table_id uuid, record_id uuid, door text, why text)\", security: \"invoker\" },\n { name: \"list_door_disagreements\", args: \"p_pretend text, p_only_organization uuid, p_sample integer, p_exhaustive boolean\", returns: \"TABLE(organization_id uuid, organization_name text, member_id uuid, table_id uuid, record_id uuid, door text, why text)\", security: \"invoker\" },\n { name: \"list_portals\", args: \"p_organization_id uuid, p_archived text DEFAULT 'active'::text\", returns: \"TABLE(portal_id uuid, title text, slug text, client_table_id uuid, client_table text, is_active boolean, tables integer, invited integer, signed_in integer, sign_in_method text, opened_at timestamp with time zone)\", security: \"definer\" },\n { name: \"list_portals_everywhere\", args: \"p_archived text DEFAULT 'active'::text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"listed_predicate_sql\", args: \"p_user uuid, p_organization_id uuid, p_table_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level, p_alias text DEFAULT 'r'::text\", returns: \"text\", security: \"invoker\" },\n { name: \"lookup_value\", args: \"p_organization_id uuid, p_record_id uuid, p_field_data jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"mask_document\", args: \"p_document jsonb, p_visible_keys text[], p_notices jsonb, p_by_id boolean DEFAULT false, p_key_ids jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"mask_document\", args: \"p_document jsonb, p_visible_keys text[], p_notices jsonb, p_by_id boolean DEFAULT false, p_key_ids jsonb DEFAULT '{}'::jsonb, p_declared_keys text[] DEFAULT NULL::text[]\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"mask_history_data\", args: \"p_data jsonb, p_mask jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"mask_says_withheld\", args: \"p_mask jsonb, p_key text\", returns: \"boolean\", security: \"invoker\" },\n { name: \"may_invite_outside\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"member_personal_tables\", args: \"p_organization_id uuid, p_person uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"member_records_take_over\", args: \"p_organization_id uuid, p_from uuid, p_to uuid, p_reason text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"merge_field_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"migrate_choice_keys\", args: \"p_organization_id uuid, p_table_id uuid, p_dry_run boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_delete\", args: \"p_organization_id uuid, p_record_id uuid, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_demote\", args: \"p_organization_id uuid, p_table_id uuid, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_extract_parent\", args: \"p_organization_id uuid, p_id uuid, p_parent_table_id uuid, p_moved_keys text[], p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_merge\", args: \"p_organization_id uuid, p_winner_id uuid, p_loser_id uuid, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_promote\", args: \"p_organization_id uuid, p_table_id uuid, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_purge\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_dry_run boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_purge_hard\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_compliance_reason text DEFAULT NULL::text, p_chunk integer DEFAULT 200, p_dry_run boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_purge_hard_request\", args: \"p_organization_id uuid, p_table_id uuid, p_compliance_reason text\", returns: \"void\", security: \"definer\" },\n { name: \"migrate_reclass\", args: \"p_organization_id uuid, p_id uuid, p_to text DEFAULT 'field'::text, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_rename\", args: \"p_organization_id uuid, p_id uuid, p_to text, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_reparent\", args: \"p_organization_id uuid, p_id uuid, p_parent_id uuid, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_retype\", args: \"p_organization_id uuid, p_id uuid, p_to text, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_split\", args: \"p_organization_id uuid, p_record_id uuid, p_moved_keys text[], p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrate_undo\", args: \"p_organization_id uuid, p_log_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"migrations\", args: \"p_organization_id uuid, p_target_id uuid DEFAULT NULL::uuid, p_limit integer DEFAULT 100\", returns: \"TABLE(id uuid, verb text, target_kind text, target_id uuid, note text, applied_at timestamp with time zone, applied_by uuid, undone_at timestamp with time zone)\", security: \"definer\" },\n { name: \"mirror_asks_the_whole_database\", args: \"\", returns: \"TABLE(schema_name text, table_name text, policy_name text, why text)\", security: \"invoker\" },\n { name: \"my_level\", args: \"p_organization_id uuid, p_id uuid, p_type text DEFAULT 'record'::text\", returns: \"permission_level\", security: \"definer\" },\n { name: \"my_levels\", args: \"p_organization_id uuid, p_ids jsonb, p_type text DEFAULT 'record'::text\", returns: \"TABLE(id uuid, level permission_level)\", security: \"definer\" },\n { name: \"organization_clear\", args: \"p_organization_id uuid, p_confirm text, p_and_destroy boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\n { name: \"organization_contents\", args: \"p_organization_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"organization_home_id\", args: \"p_organization_id uuid\", returns: \"uuid\", security: \"invoker\" },\n { name: \"organization_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"organization_pick_lists\", args: \"p_organization_id uuid\", returns: \"TABLE(id uuid, list_name text, description text, updated_at timestamp with time zone, lives_in text)\", security: \"definer\" },\n { name: \"organization_references\", args: \"p_kind text, p_organization_id uuid, p_row jsonb\", returns: \"TABLE(site text, what text, ref_id uuid, openable boolean)\", security: \"invoker\" },\n { name: \"owning_table\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"uuid\", security: \"invoker\" },\n { name: \"owning_table_gone\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"page_ceiling\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"integer\", security: \"invoker\" },\n { name: \"page_contract\", args: \"p_organization_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"page_size\", args: \"p_organization_id uuid, p_door text, p_limit integer, p_default integer DEFAULT NULL::integer, p_ceiling integer DEFAULT NULL::integer\", returns: \"integer\", security: \"invoker\" },\n { name: \"parity_field_types\", args: \"\", returns: \"TABLE(parity_type text, behavior text, made_of text)\", security: \"invoker\" },\n { name: \"parity_type\", args: \"p_field_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"parity_values\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(field_key text, field_id uuid, parity_type text, behavior text, unit text, format text, value jsonb, value_version integer, actor text, written_at timestamp with time zone)\", security: \"invoker\" },\n { name: \"per_value_access_words\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"person_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"phone_canonical\", args: \"p_text text\", returns: \"text\", security: \"invoker\" },\n { name: \"phone_display\", args: \"p_text text\", returns: \"text\", security: \"invoker\" },\n { name: \"phone_pattern\", args: \"\", returns: \"text\", security: \"invoker\" },\n { name: \"pick_list_create\", args: \"p_organization_id uuid, p_list_name text, p_description text DEFAULT NULL::text, p_items jsonb DEFAULT '[]'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pick_list_index\", args: \"p_organization_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pick_list_index_everywhere\", args: \"\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pin_agent_cells\", args: \"p_new jsonb, p_old jsonb, p_agent_keys text[]\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"pipeline_board\", args: \"p_organization_id uuid, p_table_id uuid, p_measure text DEFAULT NULL::text\", returns: \"TABLE(stage_key text, stage_label text, stage_position integer, cards bigint, total numeric, wip_limit integer, over_limit boolean)\", security: \"definer\" },\n { name: \"pipeline_board\", args: \"p_organization_id uuid, p_table_id uuid, p_measure text, p_filter jsonb\", returns: \"TABLE(stage_key text, stage_label text, stage_position integer, cards bigint, total numeric, wip_limit integer, over_limit boolean)\", security: \"definer\" },\n { name: \"pipeline_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pipeline_gate_preview\", args: \"p_organization_id uuid, p_table_id uuid, p_stage text, p_gate jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pipeline_move\", args: \"p_organization_id uuid, p_record_id uuid, p_to text, p_also jsonb DEFAULT '{}'::jsonb, p_expected_version integer DEFAULT NULL::integer\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pipeline_move_many\", args: \"p_organization_id uuid, p_moves jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pipeline_pending\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pipeline_read\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pipeline_transition_refusal\", args: \"p_organization_id uuid, p_record_id uuid, p_to text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"pipelines\", args: \"p_organization_id uuid\", returns: \"TABLE(table_id uuid, table_name text, stage_field text, stage_label text, stages integer, rules integer, broken text, updated_at timestamp with time zone, updated_by uuid)\", security: \"definer\" },\n { name: \"plural_of\", args: \"p_word text\", returns: \"text\", security: \"invoker\" },\n { name: \"portal_accents\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"portal_admits\", args: \"p_organization_id uuid, p_user_id uuid DEFAULT NULL::uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"portal_archive\", args: \"p_organization_id uuid, p_portal_id uuid, p_confirm_title text, p_reason text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_card\", args: \"p_organization_id uuid, p_portal_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_declare\", args: \"p_organization_id uuid, p_title text, p_client_table_id uuid, p_tables jsonb, p_portal_id uuid DEFAULT NULL::uuid, p_slug text DEFAULT NULL::text, p_sign_in_method text DEFAULT 'magic_link'::text, p_config jsonb DEFAULT NULL::jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"portal_field_map\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(field_id uuid, field_key text, field_type text, points_at uuid)\", security: \"definer\" },\n { name: \"portal_form\", args: \"p_organization_id uuid, p_portal_id uuid, p_form_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_form_submit\", args: \"p_organization_id uuid, p_portal_id uuid, p_form_id uuid, p_payload jsonb, p_client_key text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_invitation\", args: \"p_slug text, p_email text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_invite\", args: \"p_organization_id uuid, p_portal_id uuid, p_client_record_id uuid, p_email text, p_user_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_invite_accept\", args: \"p_token text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_me\", args: \"\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_preview\", args: \"p_organization_id uuid, p_portal_id uuid, p_principal_id uuid, p_table_id uuid\", returns: \"TABLE(record_id uuid, title text)\", security: \"definer\" },\n { name: \"portal_principal_bind\", args: \"p_organization_id uuid, p_principal_id uuid, p_user_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_public\", args: \"p_slug text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_record_title\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"text\", security: \"definer\" },\n { name: \"portal_restore\", args: \"p_organization_id uuid, p_portal_id uuid, p_confirm_title text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_revoke\", args: \"p_organization_id uuid, p_portal_id uuid, p_principal_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"portal_slug\", args: \"p_organization_id uuid, p_title text, p_portal_id uuid DEFAULT NULL::uuid\", returns: \"text\", security: \"definer\" },\n { name: \"portal_tables\", args: \"p_organization_id uuid\", returns: \"TABLE(portal_id uuid, table_id uuid, name text)\", security: \"definer\" },\n { name: \"portals\", args: \"p_organization_id uuid\", returns: \"TABLE(portal_id uuid, title text, slug text, client_table_id uuid, client_table text, is_active boolean, tables integer, invited integer, signed_in integer, sign_in_method text, opened_at timestamp with time zone)\", security: \"definer\" },\n { name: \"presentation_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"promote_field\", args: \"p_organization_id uuid, p_table_id uuid, p_field_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"promote_table\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"promoted_field_cap\", args: \"\", returns: \"integer\", security: \"invoker\" },\n { name: \"promoted_fields\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(field_id uuid, field_key text, parity_type text, is_unique boolean, value_path text, index_arm text, index_expr text, index_name text, indexable boolean, why_not text)\", security: \"invoker\" },\n { name: \"promoted_index_arm\", args: \"p_field_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"promoted_index_ddl\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(step integer, purpose text, statement text)\", security: \"invoker\" },\n { name: \"promoted_index_expr\", args: \"p_field_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"promoted_index_name\", args: \"p_table_id uuid, p_field_key text, p_unique boolean\", returns: \"text\", security: \"invoker\" },\n { name: \"promoted_query_sql\", args: \"p_organization_id uuid, p_table_id uuid, p_field_key text\", returns: \"text\", security: \"invoker\" },\n { name: \"promoted_read\", args: \"p_organization_id uuid, p_table_id uuid, p_field_key text, p_value text\", returns: \"SETOF uuid\", security: \"invoker\" },\n { name: \"promoted_value_path\", args: \"p_field_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"promotion_inline_ceiling\", args: \"\", returns: \"integer\", security: \"invoker\" },\n { name: \"protected_field_notice\", args: \"p_field custom.record\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"protected_field_query_refusal\", args: \"p_field_id uuid, p_verb text\", returns: \"text\", security: \"definer\" },\n { name: \"protected_field_rule\", args: \"p_token text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"protected_matches\", args: \"p_field_id uuid, p_value jsonb DEFAULT NULL::jsonb\", returns: \"TABLE(row_id uuid, value jsonb)\", security: \"definer\" },\n { name: \"protected_readers_problem\", args: \"p_token text, p_readers jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"protected_value\", args: \"p_token text, p_row_id uuid, p_field_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"protected_value_leaks\", args: \"p_field_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(place text, table_token text, field_key text, row_id uuid, ref text)\", security: \"definer\" },\n { name: \"protected_values\", args: \"p_organization_id uuid, p_token text, p_row_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"provenance_prune\", args: \"p_organization_id uuid DEFAULT NULL::uuid, p_dry_run boolean DEFAULT true, p_limit integer DEFAULT 200000\", returns: \"jsonb\", security: \"definer\" },\n { name: \"provenance_retention_days\", args: \"p_organization_id uuid\", returns: \"integer\", security: \"definer\" },\n { name: \"provenance_write\", args: \"p_organization_id uuid, p_conversation_id uuid, p_turn_id text, p_rows jsonb\", returns: \"integer\", security: \"definer\" },\n { name: \"publish_bind\", args: \"p_organization_id uuid, p_kind text, p_resource_id uuid, p_slug text, p_render_mode text DEFAULT 'page'::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"query_access_ids\", args: \"p_organization_id uuid, p_required text DEFAULT 'viewer'::text\", returns: \"uuid[]\", security: \"invoker\" },\n { name: \"query_across_homes\", args: \"p_organization_id uuid, p_table_id uuid, p_limit integer DEFAULT 50, p_offset integer DEFAULT 0, p_required text DEFAULT 'viewer'::text\", returns: \"TABLE(record_id uuid, home_record_id uuid, data jsonb, created_at timestamp with time zone)\", security: \"definer\" },\n { name: \"query_by_coordinates\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_coordinates jsonb DEFAULT '[]'::jsonb, p_limit integer DEFAULT 50, p_offset integer DEFAULT 0, p_required text DEFAULT 'viewer'::text\", returns: \"TABLE(record_id uuid, table_id uuid, data jsonb, coordinates_matched integer)\", security: \"definer\" },\n { name: \"query_can_see\", args: \"p_organization_id uuid, p_record_id uuid, p_required text DEFAULT 'viewer'::text\", returns: \"boolean\", security: \"definer\" },\n { name: \"query_hot_paths\", args: \"\", returns: \"TABLE(name text, statement text)\", security: \"invoker\" },\n { name: \"query_hot_paths_prepared\", args: \"\", returns: \"TABLE(name text, prepared boolean, generic_plans bigint)\", security: \"invoker\" },\n { name: \"query_is_store_owner\", args: \"\", returns: \"boolean\", security: \"invoker\" },\n { name: \"query_prepare_hot\", args: \"\", returns: \"integer\", security: \"invoker\" },\n { name: \"query_principal\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"query_record_as_of\", args: \"p_organization_id uuid, p_record_id uuid, p_recorded_at timestamp with time zone DEFAULT NULL::timestamp with time zone, p_world_on date DEFAULT NULL::date, p_required text DEFAULT 'viewer'::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"query_record_document\", args: \"p_principal uuid, p_row custom.record\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"query_relation_edges\", args: \"p_organization_id uuid, p_flavor text DEFAULT NULL::text, p_role text DEFAULT NULL::text\", returns: \"TABLE(parent_id uuid, child_id uuid, role text, flavor text)\", security: \"definer\" },\n { name: \"query_rollup\", args: \"p_organization_id uuid, p_roots uuid[], p_flavor text DEFAULT NULL::text, p_role text DEFAULT NULL::text, p_max_depth integer DEFAULT 33, p_required text DEFAULT 'viewer'::text\", returns: \"TABLE(record_id uuid, depth integer)\", security: \"definer\" },\n { name: \"query_rollup_sum\", args: \"p_organization_id uuid, p_roots uuid[], p_field_key text, p_flavor text DEFAULT NULL::text, p_role text DEFAULT NULL::text, p_max_depth integer DEFAULT 33, p_required text DEFAULT 'viewer'::text\", returns: \"numeric\", security: \"definer\" },\n { name: \"query_table_as_of\", args: \"p_organization_id uuid, p_table_id uuid, p_recorded_at timestamp with time zone DEFAULT NULL::timestamp with time zone, p_world_on date DEFAULT NULL::date, p_limit integer DEFAULT 50, p_offset integer DEFAULT 0, p_required text DEFAULT 'viewer'::text\", returns: \"TABLE(record_id uuid, data jsonb)\", security: \"definer\" },\n { name: \"query_table_homes\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"SETOF uuid\", security: \"definer\" },\n { name: \"query_visibility_parity\", args: \"p_organization_id uuid\", returns: \"TABLE(side text, container_type text, container_id uuid, item_type text, item_id uuid, stored_level permission_level, derived_level permission_level, reason text)\", security: \"definer\" },\n { name: \"query_visible_ids\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid, p_required text DEFAULT 'viewer'::text\", returns: \"SETOF uuid\", security: \"definer\" },\n { name: \"reachable_from\", args: \"p_organization_id uuid, p_roots uuid[]\", returns: \"TABLE(record_id uuid, depth integer, via text)\", security: \"invoker\" },\n { name: \"reaches_directly\", args: \"p_user_id uuid, p_type text, p_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level\", returns: \"boolean\", security: \"definer\" },\n { name: \"read_door_carried_ids\", args: \"p_user uuid, p_organization_id uuid, p_table_id uuid, p_required permission_level, OUT o_ids uuid[], OUT o_containers integer\", returns: \"record\", security: \"definer\" },\n { name: \"read_door_granted_ids\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"uuid[]\", security: \"definer\" },\n { name: \"read_door_ladder_ceiling\", args: \"\", returns: \"integer\", security: \"invoker\" },\n { name: \"read_door_parity\", args: \"p_organization_id uuid, p_table_id uuid, p_user uuid, p_required permission_level, p_sample integer\", returns: \"TABLE(record_id uuid, set_based boolean, per_row boolean, verdict text)\", security: \"definer\" },\n { name: \"read_mask\", args: \"p_organization_id uuid, p_record_id uuid, p_action text DEFAULT 'read'::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"read_mask_at\", args: \"p_record_id uuid, p_level_given boolean, p_level permission_level, p_action text DEFAULT 'read'::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"read_mask_for\", args: \"p_user_id uuid, p_organization_id uuid, p_table_id uuid, p_level permission_level, p_action text DEFAULT 'read'::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"read_paths_outside_the_door\", args: \"\", returns: \"TABLE(object_name text, why text)\", security: \"invoker\" },\n { name: \"read_record\", args: \"p_organization_id uuid, p_record_id uuid, p_by_id boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\n { name: \"read_records\", args: \"p_organization_id uuid, p_table_id uuid, p_by_id boolean DEFAULT false, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0\", returns: \"TABLE(id uuid, document jsonb, level permission_level)\", security: \"definer\" },\n { name: \"read_records_archived\", args: \"p_organization_id uuid, p_table_id uuid, p_lane text DEFAULT 'org'::text, p_by_id boolean DEFAULT false, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0\", returns: \"TABLE(id uuid, document jsonb, level permission_level, archived_at timestamp with time zone, archived_by uuid, archived_by_name text)\", security: \"definer\" },\n { name: \"read_records_by_ids\", args: \"p_organization_id uuid, p_table_id uuid, p_record_ids uuid[], p_by_id boolean DEFAULT false\", returns: \"TABLE(id uuid, document jsonb, level permission_level)\", security: \"definer\" },\n { name: \"read_records_in_view_order\", args: \"p_organization_id uuid, p_view_id uuid, p_by_id boolean DEFAULT false, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0, p_filter jsonb DEFAULT NULL::jsonb\", returns: \"TABLE(id uuid, document jsonb, level permission_level, \\\"position\\\" numeric)\", security: \"definer\" },\n { name: \"read_records_matching\", args: \"p_organization_id uuid, p_table_id uuid, p_filter jsonb DEFAULT '{}'::jsonb, p_by_id boolean DEFAULT false, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0\", returns: \"TABLE(id uuid, document jsonb, level permission_level)\", security: \"definer\" },\n { name: \"read_records_page\", args: \"p_organization_id uuid, p_table_id uuid, p_filter jsonb DEFAULT '{}'::jsonb, p_search text DEFAULT NULL::text, p_sort jsonb DEFAULT '[]'::jsonb, p_view_id uuid DEFAULT NULL::uuid, p_by_id boolean DEFAULT false, p_limit integer DEFAULT 50, p_offset integer DEFAULT 0, p_time_zone text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"realtime_topic_admits\", args: \"p_topic text\", returns: \"boolean\", security: \"definer\" },\n { name: \"record_aggregate\", args: \"p_organization_id uuid, p_table_id uuid, p_group_by jsonb DEFAULT '[]'::jsonb, p_measures jsonb DEFAULT '[]'::jsonb, p_bucket jsonb DEFAULT NULL::jsonb, p_filter jsonb DEFAULT '{}'::jsonb, p_limit integer DEFAULT 200, p_required text DEFAULT 'viewer'::text, p_compare jsonb DEFAULT NULL::jsonb, p_search text DEFAULT NULL::text, p_time_zone text DEFAULT NULL::text\", returns: \"TABLE(groups jsonb, measures jsonb, row_count bigint, prior_groups jsonb, prior_measures jsonb, prior_row_count bigint, delta jsonb, compare jsonb)\", security: \"definer\" },\n { name: \"record_aggregate_as_of\", args: \"p_organization_id uuid, p_table_id uuid, p_recorded_at timestamp with time zone, p_measure text DEFAULT 'count'::text, p_field_key text DEFAULT NULL::text, p_group_by text DEFAULT NULL::text, p_match jsonb DEFAULT '{}'::jsonb\", returns: \"TABLE(bucket text, result numeric, row_count bigint, not_numbers bigint, a_non_number text)\", security: \"definer\" },\n { name: \"record_applicability\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(rule_id uuid, rule_name text, rule_version integer, applies boolean, answer jsonb)\", security: \"invoker\" },\n { name: \"record_archiver\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"record_as_of\", args: \"p_organization_id uuid, p_record_id uuid, p_at timestamp with time zone\", returns: \"TABLE(state jsonb, replayed boolean)\", security: \"definer\" },\n { name: \"record_card\", args: \"p_viewer uuid, p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_carrying_edges\", args: \"p_id uuid, p_data_class text, p_data jsonb, p_deleted_at timestamp with time zone\", returns: \"TABLE(container_id uuid, item_id uuid, edge_role text)\", security: \"invoker\" },\n { name: \"record_change_actions\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_change_many\", args: \"p_organization_id uuid, p_table_id uuid, p_changes jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_changes_drain\", args: \"p_organization_id uuid, p_consumer text, p_limit integer DEFAULT 100\", returns: \"TABLE(event_id uuid, organization_id uuid, table_id uuid, record_id uuid, kind text, operation text, version integer, fields jsonb, changed_field_ids jsonb, actor jsonb, chain jsonb, op_id uuid, occurred_at timestamp with time zone, via text)\", security: \"definer\" },\n { name: \"record_delete\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"timestamp with time zone\", security: \"definer\" },\n { name: \"record_entity_edges\", args: \"p_organization_id uuid, p_id uuid, p_table_id uuid, p_data_class text, p_data jsonb, p_deleted_at timestamp with time zone\", returns: \"TABLE(target_type text, target_id uuid, edge_role text, field_id uuid, ord integer)\", security: \"invoker\" },\n { name: \"record_filter_sql\", args: \"p_filter jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"record_filter_sql\", args: \"p_organization_id uuid, p_table_id uuid, p_filter jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"record_headers\", args: \"p_organization_id uuid, p_ids uuid[]\", returns: \"TABLE(id uuid, table_id uuid, created_at timestamp with time zone, updated_at timestamp with time zone, version integer, deleted_at timestamp with time zone, mine boolean, created_by uuid)\", security: \"definer\" },\n { name: \"record_history\", args: \"p_organization_id uuid, p_record_id uuid, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0\", returns: \"TABLE(version integer, occurred_at timestamp with time zone, operation text, operation_label text, actor jsonb, changes jsonb, migration_id uuid, undoable boolean)\", security: \"definer\" },\n { name: \"record_platform_keys\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"record_relation_edges\", args: \"p_organization_id uuid, p_id uuid, p_table_id uuid, p_data_class text, p_data jsonb, p_deleted_at timestamp with time zone\", returns: \"TABLE(target_id uuid, edge_role text, field_id uuid, ord integer)\", security: \"invoker\" },\n { name: \"record_reparent\", args: \"p_organization_id uuid, p_record_id uuid, p_parent_id uuid\", returns: \"void\", security: \"definer\" },\n { name: \"record_resolve\", args: \"p_organization_id uuid, p_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_restore\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"void\", security: \"definer\" },\n { name: \"record_restore_preview\", args: \"p_organization_id uuid, p_record_id uuid, p_version integer, p_field_key text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_restore_version\", args: \"p_organization_id uuid, p_record_id uuid, p_version integer\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_restore_version\", args: \"p_organization_id uuid, p_record_id uuid, p_version integer, p_author jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_row_controls\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_row_controls_set\", args: \"p_organization_id uuid, p_record_id uuid, p_controls jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_runs\", args: \"p_organization_id uuid, p_record_id uuid, p_limit integer DEFAULT 50\", returns: \"TABLE(run_id uuid, kind text, name text, trigger_name text, status text, started_at timestamp with time zone, finished_at timestamp with time zone, steps integer, says text, ran_by uuid)\", security: \"definer\" },\n { name: \"record_scope_context\", args: \"p_organization_id uuid, p_record_id uuid, p_relations integer DEFAULT 12, p_history integer DEFAULT 15, p_siblings integer DEFAULT 8\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_search_sql\", args: \"p_organization_id uuid, p_table_id uuid, p_search text, p_alias text DEFAULT 'r'::text, p_time_zone text DEFAULT NULL::text\", returns: \"text\", security: \"invoker\" },\n { name: \"record_source_key\", args: \"p_table_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"record_source_keys\", args: \"p_table_id uuid\", returns: \"text[]\", security: \"invoker\" },\n { name: \"record_source_table\", args: \"p_key text\", returns: \"uuid\", security: \"invoker\" },\n { name: \"record_stage_pending\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_state_as_of\", args: \"p_record_id uuid, p_at timestamp with time zone\", returns: \"TABLE(state jsonb, replayed boolean)\", security: \"definer\" },\n { name: \"record_table\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"record_triggers\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(trigger_id uuid, name text, definition_id uuid, definition_name text, table_id uuid, event text, operations jsonb, field_ids jsonb, via jsonb, is_active boolean, last_fired_at timestamp with time zone, fire_count integer, updated_at timestamp with time zone)\", security: \"definer\" },\n { name: \"record_update\", args: \"p_organization_id uuid, p_record_id uuid, p_patch jsonb, p_expected_version integer DEFAULT NULL::integer\", returns: \"integer\", security: \"definer\" },\n { name: \"record_update_adding_choices\", args: \"p_organization_id uuid, p_record_id uuid, p_patch jsonb, p_add jsonb, p_expected_version integer DEFAULT NULL::integer\", returns: \"integer\", security: \"definer\" },\n { name: \"record_upsert\", args: \"p_organization_id uuid, p_table_id uuid, p_key text[], p_data jsonb, p_expected_version integer DEFAULT NULL::integer\", returns: \"uuid\", security: \"definer\" },\n { name: \"record_value_one\", args: \"p_organization_id uuid, p_record_id uuid, p_key text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"record_values\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"record_values_of\", args: \"p_row custom.record\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"record_values_step\", args: \"p_row custom.record, p_cache jsonb DEFAULT '{}'::jsonb, OUT o_doc jsonb, OUT o_cache jsonb\", returns: \"record\", security: \"invoker\" },\n { name: \"record_values_versioned\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(field_key text, field_id uuid, value jsonb, value_version integer, source jsonb, absent_reason text, actor text, on_behalf_of text, written_at timestamp with time zone, alternates jsonb)\", security: \"definer\" },\n { name: \"record_words\", args: \"p_organization_id uuid, p_record_id uuid, p_noun text DEFAULT NULL::text\", returns: \"text\", security: \"definer\" },\n { name: \"record_write\", args: \"p_organization_id uuid, p_table_id uuid, p_data jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"record_write_graph\", args: \"p_organization_id uuid, p_table_id uuid, p_parent jsonb, p_edges jsonb DEFAULT '[]'::jsonb, p_children jsonb DEFAULT '[]'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_write_graph_superseding\", args: \"p_organization_id uuid, p_table_id uuid, p_lock_key text, p_idempotence jsonb DEFAULT NULL::jsonb, p_parent jsonb DEFAULT NULL::jsonb, p_edges jsonb DEFAULT '[]'::jsonb, p_children jsonb DEFAULT '[]'::jsonb, p_chain jsonb DEFAULT '{\\\"mode\\\": \\\"first\\\"}'::jsonb, p_rows_state jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"record_write_many\", args: \"p_organization_id uuid, p_table_id uuid, p_rows jsonb[], p_ids uuid[] DEFAULT NULL::uuid[]\", returns: \"uuid[]\", security: \"definer\" },\n { name: \"records_search\", args: \"p_search text, p_limit integer DEFAULT 50, p_offset integer DEFAULT 0, p_table_ids uuid[] DEFAULT NULL::uuid[], p_organization_ids uuid[] DEFAULT NULL::uuid[], p_include_app_tables boolean DEFAULT false\", returns: \"TABLE(record_id uuid, table_id uuid, table_name text, name text, organization_id uuid, updated_at timestamp with time zone)\", security: \"definer\" },\n { name: \"refusals_claiming_a_level_never_asked\", args: \"\", returns: \"TABLE(function_name text, identity_args text, why text)\", security: \"invoker\" },\n { name: \"relation_carry\", args: \"p_organization_id uuid, p_container_id uuid, p_item_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"relation_edges_withdraw\", args: \"p_organization_id uuid, p_field_ids uuid[], p_why text\", returns: \"integer\", security: \"definer\" },\n { name: \"relation_halves_disagreements\", args: \"p_organization_id uuid DEFAULT NULL::uuid, p_record_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(organization_id uuid, record_id uuid, field_key text, field_id uuid, target_id uuid, direction text, remedy text, why text)\", security: \"definer\" },\n { name: \"relation_halves_repair\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"relation_kernel_record\", args: \"p_organization_id uuid, p_kernel_table_id uuid, p_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"relation_name_key\", args: \"p_text text\", returns: \"text\", security: \"invoker\" },\n { name: \"relation_names_match\", args: \"p_organization_id uuid, p_table_id uuid, p_names text[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"relation_own\", args: \"p_organization_id uuid, p_owner_id uuid, p_target_id uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"relation_restore\", args: \"p_organization_id uuid, p_relation_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"relation_target_card\", args: \"p_organization_id uuid, p_record_id uuid, p_via_key text DEFAULT NULL::text\", returns: \"TABLE(target_id uuid, target_organization_id uuid, is_foreign boolean, masked boolean, reader_level permission_level, card jsonb, why text)\", security: \"definer\" },\n { name: \"relation_target_external\", args: \"p_connection_token text, p_external_table text, p_external_key text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"relation_target_ours\", args: \"p_entity_token text, p_row_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"relation_targets\", args: \"p_organization_id uuid, p_record_id uuid, p_via_key text\", returns: \"SETOF uuid\", security: \"definer\" },\n { name: \"relation_uncarry\", args: \"p_organization_id uuid, p_container_id uuid, p_item_id uuid\", returns: \"integer\", security: \"definer\" },\n { name: \"relation_value_target_ok\", args: \"p_organization_id uuid, p_field_id uuid, p_field_data jsonb, p_target_id uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"relation_words\", args: \"p_organization_id uuid, p_field_id uuid, p_value text\", returns: \"text\", security: \"definer\" },\n { name: \"relation_words_many\", args: \"p_organization_id uuid, p_field_id uuid, p_record_ids uuid[]\", returns: \"TABLE(record_id uuid, words text, archived boolean)\", security: \"definer\" },\n { name: \"reopen_declared_doors\", args: \"\", returns: \"TABLE(reopened text)\", security: \"definer\" },\n { name: \"required_epoch\", args: \"p_container_type text, p_container_id uuid, p_item_type text, p_item_id uuid\", returns: \"bigint\", security: \"definer\" },\n { name: \"resolve_context\", args: \"p_entity_type text, p_entity_id uuid, p_record_ids uuid[] DEFAULT NULL::uuid[], p_table_ids uuid[] DEFAULT NULL::uuid[], p_system_item_refs text[] DEFAULT NULL::text[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"resolve_first_match\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"resolve_id\", args: \"p_organization_id uuid, p_id uuid\", returns: \"uuid\", security: \"invoker\" },\n { name: \"retired_actor_words\", args: \"\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"reverse_columns\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(key text, label text, source_field_id uuid, source_field_key text, source_field_label text, source_table_id uuid, source_table_name text, cardinality text, read_only boolean)\", security: \"definer\" },\n { name: \"reverse_links_many\", args: \"p_organization_id uuid, p_table_id uuid, p_field_id uuid, p_record_ids uuid[], p_limit integer DEFAULT 10, p_offset integer DEFAULT 0\", returns: \"TABLE(record_id uuid, total integer, links jsonb)\", security: \"definer\" },\n { name: \"rollup_value\", args: \"p_organization_id uuid, p_record_id uuid, p_field_data jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"row_actions\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"row_sits_in_a_personal_table\", args: \"p_type text, p_organization_id uuid, p_id uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"row_template_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_spec jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"row_templates\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(template_id uuid, name text, table_id uuid, \\\"values\\\" jsonb, created_at timestamp with time zone, updated_at timestamp with time zone)\", security: \"definer\" },\n { name: \"rule_applies\", args: \"p_organization_id uuid, p_rule_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"rule_context\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"rule_declare\", args: \"p_organization_id uuid, p_spec jsonb, p_rule_id uuid DEFAULT NULL::uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"rule_dependency_edges\", args: \"p_organization_id uuid, p_row custom.record DEFAULT NULL::custom.record\", returns: \"TABLE(needs text, needed text)\", security: \"invoker\" },\n { name: \"rule_eval\", args: \"p_organization_id uuid, p_expr jsonb, p_values jsonb, p_context jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"rule_field_key\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"rule_field_label\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"rule_filter_node_sql\", args: \"p_organization_id uuid, p_table_id uuid, p_node jsonb, p_map jsonb, p_visible text[]\", returns: \"text\", security: \"invoker\" },\n { name: \"rule_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"rule_members\", args: \"p_organization_id uuid, p_rule_id uuid\", returns: \"SETOF custom.record\", security: \"invoker\" },\n { name: \"rule_members_visible\", args: \"p_organization_id uuid, p_rule_id uuid, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0\", returns: \"TABLE(id uuid, document jsonb, level permission_level)\", security: \"definer\" },\n { name: \"rule_membership\", args: \"p_organization_id uuid, p_rule_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"rule_node_kinds\", args: \"\", returns: \"TABLE(node text, evaluated_by text, note text)\", security: \"invoker\" },\n { name: \"rule_restore\", args: \"p_organization_id uuid, p_rule_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"rule_run\", args: \"p_organization_id uuid, p_rule_id uuid, p_values jsonb, p_context jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"rule_sql_op\", args: \"p_op text, p_a jsonb, p_b jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"rule_truth\", args: \"p_answer jsonb\", returns: \"boolean\", security: \"invoker\" },\n { name: \"rule_uses\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"rule_version\", args: \"p_organization_id uuid, p_rule_id uuid\", returns: \"integer\", security: \"invoker\" },\n { name: \"said\", args: \"p_value text, p_when_there_is_none text\", returns: \"text\", security: \"invoker\" },\n { name: \"scope_item_row_of\", args: \"p_field custom.record\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"scope_item_value_type\", args: \"p_field jsonb, p_carried jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"scope_items_of\", args: \"p_org uuid, p_table uuid\", returns: \"SETOF custom.record\", security: \"invoker\" },\n { name: \"scope_member_reaches\", args: \"p_user_id uuid, p_record_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level\", returns: \"boolean\", security: \"invoker\" },\n { name: \"scope_row_of\", args: \"p_rec custom.record\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"scope_rows_of\", args: \"p_org uuid, p_types uuid[] DEFAULT NULL::uuid[]\", returns: \"TABLE(id uuid, table_id uuid, type_sort integer, sort_order integer, name text, type_doc jsonb, row_doc jsonb)\", security: \"invoker\" },\n { name: \"scope_setting_back\", args: \"p_value jsonb, p_behavior text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"scope_table_provision\", args: \"p_organization_id uuid, p_item_id uuid, p_scope_id uuid, p_home_id uuid DEFAULT NULL::uuid\", returns: \"uuid\", security: \"definer\" },\n { name: \"scope_type_row_of\", args: \"p_table custom.record\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"scope_value_columns\", args: \"p_org uuid, p_field jsonb, p_value_type text, p_value jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"seen_among\", args: \"p_user_id uuid, p_ids uuid[]\", returns: \"uuid[]\", security: \"definer\" },\n { name: \"sensitivity_rank\", args: \"p_sensitivity text\", returns: \"integer\", security: \"invoker\" },\n { name: \"set_table_confidential_arman_explicitly_approved\", args: \"p_table_id uuid, p_readers jsonb, p_arman_words text, p_approved_on date, p_maker_is_reader boolean DEFAULT NULL::boolean\", returns: \"jsonb\", security: \"definer\" },\n { name: \"share_access\", args: \"p_organization_id uuid, p_subject_id uuid\", returns: \"TABLE(principal_kind text, principal_id uuid, principal_label text, level permission_level, reason text, reason_detail text, via_type text, via_id uuid, revocable boolean)\", security: \"definer\" },\n { name: \"share_grant\", args: \"p_organization_id uuid, p_subject_id uuid, p_principal_kind text, p_principal_id uuid, p_level permission_level DEFAULT 'viewer'::permission_level\", returns: \"jsonb\", security: \"definer\" },\n { name: \"share_lane_set\", args: \"p_organization_id uuid, p_subject_id uuid, p_choice text, p_level permission_level DEFAULT NULL::permission_level\", returns: \"jsonb\", security: \"definer\" },\n { name: \"share_lanes\", args: \"\", returns: \"TABLE(choice text, lane text, discoverable boolean, label text, means text)\", security: \"definer\" },\n { name: \"share_levels\", args: \"\", returns: \"TABLE(level permission_level, ordinal integer, label text, means text)\", security: \"definer\" },\n { name: \"share_people\", args: \"p_organization_id uuid, p_subject_id uuid DEFAULT NULL::uuid, p_query text DEFAULT NULL::text, p_limit integer DEFAULT 25\", returns: \"TABLE(user_id uuid, email text, display_name text, membership text, already_at permission_level, already_why text)\", security: \"definer\" },\n { name: \"share_revoke\", args: \"p_organization_id uuid, p_subject_id uuid, p_principal_kind text, p_principal_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"share_subject_name\", args: \"p_organization_id uuid, p_type text, p_id uuid\", returns: \"text\", security: \"definer\" },\n { name: \"shared_only_disagreements\", args: \"p_pretend text DEFAULT NULL::text\", returns: \"TABLE(organization_id uuid, organization_name text, member_id uuid, record_id uuid, table_id uuid, ladder boolean, read_door boolean, rls_mirror boolean, why text)\", security: \"invoker\" },\n { name: \"shares_outside\", args: \"p_organization_id uuid\", returns: \"TABLE(invitation_id uuid, table_id uuid, table_name text, email text, level text, level_label text, status text, joined boolean, expired boolean, invited_at timestamp with time zone, expires_at timestamp with time zone, say text)\", security: \"definer\" },\n { name: \"sign_request_cancel\", args: \"p_organization_id uuid, p_request_id uuid, p_reason text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"sign_request_create\", args: \"p_organization_id uuid, p_render_id uuid, p_field_key text, p_signer_email text, p_signer_name text, p_expires_in interval DEFAULT '14 days'::interval\", returns: \"jsonb\", security: \"definer\" },\n { name: \"sign_request_decline\", args: \"p_token text, p_reason text DEFAULT NULL::text, p_ip text DEFAULT NULL::text, p_user_agent text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"sign_request_public\", args: \"p_token text, p_origin text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"sign_request_remind\", args: \"p_organization_id uuid, p_request_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"sign_request_sentence\", args: \"p_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"sign_request_sign\", args: \"p_token text, p_signed_name text, p_mark text, p_image text DEFAULT NULL::text, p_ip text DEFAULT NULL::text, p_user_agent text DEFAULT NULL::text, p_origin text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"sign_request_state\", args: \"p_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"sign_request_unchanged\", args: \"p_organization_id uuid, p_request_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"sign_requests\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(request_id uuid, render_id uuid, record_id uuid, field_key text, document_title text, signer_name text, signer_email text, signer_has_account boolean, state text, sentence text, document_version integer, document_hash text, sent_at timestamp with time zone, expires_at timestamp with time zone, viewed_at timestamp with time zone, signed_at timestamp with time zone, declined_at timestamp with time zone, invalidated_at timestamp with time zone, signature_id uuid, signature_mark text, reminder_count integer)\", security: \"definer\" },\n { name: \"sign_token_decode\", args: \"p_token text\", returns: \"bytea\", security: \"invoker\" },\n { name: \"sign_token_encode\", args: \"p_bytes bytea\", returns: \"text\", security: \"invoker\" },\n { name: \"silent_page_doors\", args: \"\", returns: \"TABLE(door text, why text)\", security: \"definer\" },\n { name: \"size_refusal\", args: \"p_organization_id uuid, p_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"source_next_pointer\", args: \"p_sources jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"source_pointer\", args: \"p_sources jsonb, p_source jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"stage_rule_enforcement\", args: \"p_organization_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"stage_rule_on_fail_kinds\", args: \"\", returns: \"TABLE(behaviour text, note text)\", security: \"invoker\" },\n { name: \"stamp_value_envelopes\", args: \"p_data jsonb, p_actor text, p_on_behalf_of text, p_at timestamp with time zone\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"status_groups_keyed\", args: \"p_organization_id uuid, p_options_table_id uuid, p_groups jsonb, p_kept jsonb, p_label text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"status_groups_of\", args: \"p_groups jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"storage_modes\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"store_census_pair_ceiling\", args: \"\", returns: \"integer\", security: \"invoker\" },\n { name: \"store_is_open\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"store_off_sentence\", args: \"p_organization_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"subscription_cadences\", args: \"p_organization_id uuid\", returns: \"text[]\", security: \"definer\" },\n { name: \"subscription_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_spec jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"subscription_mute\", args: \"p_organization_id uuid, p_rule_id uuid, p_muted boolean DEFAULT true\", returns: \"boolean\", security: \"definer\" },\n { name: \"subscription_preview\", args: \"p_organization_id uuid, p_rule_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"subscriptions\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(rule_id uuid, name text, table_id uuid, saved_view_id uuid, cadence text, schedule text, quiet_hours jsonb, channel text, recipient_user_id uuid, event_key text, muted boolean, mine boolean, i_may_mute boolean, last_sent_at timestamp with time zone, next_digest_at timestamp with time zone)\", security: \"definer\" },\n { name: \"table_add_rung\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"permission_level\", security: \"invoker\" },\n { name: \"table_archive\", args: \"p_organization_id uuid, p_table_id uuid, p_chunk integer DEFAULT 50, p_include_table boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_archive_deliberately\", args: \"p_organization_id uuid, p_table_id uuid, p_typed_slug text, p_reason text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_capacity\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_carries_its_rows\", args: \"p_user_id uuid, p_table_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level\", returns: \"boolean\", security: \"definer\" },\n { name: \"table_column_source\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"table_contents\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(record_id uuid, kind text, goes_at integer)\", security: \"invoker\" },\n { name: \"table_copies_in_progress\", args: \"\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_declare\", args: \"p_organization_id uuid, p_spec jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"table_decorate\", args: \"p_organization_id uuid, p_table_id uuid, p_path text[], p_value jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_decorations\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_dimensions\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_dimensions_set\", args: \"p_organization_id uuid, p_table_id uuid, p_overrides jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_duplicate\", args: \"p_table_id uuid, p_with_records boolean DEFAULT false, p_name text DEFAULT NULL::text, p_organization_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_duplicate_continue\", args: \"p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_ensure\", args: \"p_organization_id uuid, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_facts\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(table_id uuid, visibility text, mine boolean, kept_by_the_app boolean, kept_for text, offered_as_context boolean, keeper_group text, keeper_says text, used_in_kind text, used_in_id uuid, used_in_table_id uuid, foundation boolean)\", security: \"definer\" },\n { name: \"table_find\", args: \"p_organization_id uuid, p_slug text DEFAULT NULL::text, p_name text DEFAULT NULL::text, p_kept_for text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_from_example\", args: \"p_organization_id uuid, p_home_id uuid, p_example jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_has_a_visible_record\", args: \"p_user uuid, p_organization_id uuid, p_table_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"table_home\", args: \"p_table_id uuid, p_to_organization_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_is_foundation\", args: \"p_data jsonb\", returns: \"boolean\", security: \"invoker\" },\n { name: \"table_is_live\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"table_is_options_table\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"table_is_platform_context\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"boolean\", security: \"invoker\" },\n { name: \"table_kept_for_derived\", args: \"p_data jsonb, p_is_kernel boolean, p_is_options boolean\", returns: \"text\", security: \"invoker\" },\n { name: \"table_kept_out_of_lists\", args: \"p_kept_for text\", returns: \"boolean\", security: \"invoker\" },\n { name: \"table_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"table_kind_facts\", args: \"p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_list_everywhere\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_list_everywhere\", args: \"p_organization_id uuid, p_include_app_tables boolean\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"table_move\", args: \"p_table_id uuid, p_to_organization_id uuid, p_expected_version integer DEFAULT NULL::integer\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_placement\", args: \"p_organization_id uuid, p_table_id uuid, p_data jsonb, p_is_kernel boolean DEFAULT false\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"table_record_ceiling\", args: \"\", returns: \"integer\", security: \"invoker\" },\n { name: \"table_record_ceiling\", args: \"p_organization_id uuid\", returns: \"integer\", security: \"invoker\" },\n { name: \"table_restore\", args: \"p_organization_id uuid, p_table_id uuid, p_chunk integer DEFAULT 20\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_row_counts\", args: \"p_organization_id uuid, p_table_ids uuid[]\", returns: \"TABLE(table_id uuid, visible_rows bigint)\", security: \"definer\" },\n { name: \"table_row_defaults\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_row_defaults_apply\", args: \"p_organization_id uuid, p_table_id uuid, p_after uuid DEFAULT NULL::uuid, p_budget_ms integer DEFAULT 4000\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_row_defaults_set\", args: \"p_organization_id uuid, p_table_id uuid, p_defaults jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_rules\", args: \"p_organization_id uuid, p_table_id uuid, p_use text, p_record_type text DEFAULT NULL::text\", returns: \"SETOF custom.record\", security: \"invoker\" },\n { name: \"table_share_outside\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_share_outside_accept\", args: \"p_token text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_share_outside_for_me\", args: \"\", returns: \"TABLE(invitation_id uuid, organization_id uuid, organization text, table_id uuid, table_name text, level text, level_label text, token text, expires_at timestamp with time zone, say text)\", security: \"definer\" },\n { name: \"table_share_outside_grant\", args: \"p_organization_id uuid, p_table_id uuid, p_person text, p_level permission_level DEFAULT 'viewer'::permission_level\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_share_outside_invite\", args: \"p_organization_id uuid, p_table_id uuid, p_email text, p_level permission_level DEFAULT 'viewer'::permission_level\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_share_outside_resend\", args: \"p_organization_id uuid, p_invitation_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_share_outside_revoke\", args: \"p_organization_id uuid, p_invitation_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_stage_field\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"text\", security: \"definer\" },\n { name: \"table_storage\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"table_sync\", args: \"p_organization_id uuid, p_home_id uuid, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_transfer_owner\", args: \"p_table_id uuid, p_to_person uuid, p_reason text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_type_field\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"text\", security: \"definer\" },\n { name: \"table_unique_rule_fields\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"table_webhook_archive\", args: \"p_organization_id uuid, p_webhook_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"table_webhook_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_target_url text, p_events text[] DEFAULT NULL::text[], p_description text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"table_webhooks\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(webhook_id uuid, target_url text, description text, events text[], is_active boolean, last_attempt_at timestamp with time zone, last_success_at timestamp with time zone, consecutive_failures integer, owner_id uuid, created_at timestamp with time zone)\", security: \"definer\" },\n { name: \"table_work_kind\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"tables_at_home\", args: \"p_organization_id uuid, p_home_ids uuid[]\", returns: \"TABLE(table_id uuid, home_record_id uuid, kind text)\", security: \"definer\" },\n { name: \"tables_described_without_asking\", args: \"\", returns: \"TABLE(function_name text, identity_args text, why text)\", security: \"invoker\" },\n { name: \"tables_i_can_open\", args: \"\", returns: \"TABLE(table_id uuid, table_name text, organization_id uuid, organization_name text, member boolean, visibility text, updated_at timestamp with time zone)\", security: \"definer\" },\n { name: \"tables_listed_among\", args: \"p_organization_id uuid, p_tables uuid[]\", returns: \"SETOF uuid\", security: \"invoker\" },\n { name: \"tables_seen_among\", args: \"p_user_id uuid, p_organization_ids uuid[], p_among uuid[]\", returns: \"TABLE(organization_id uuid, id uuid, seen boolean)\", security: \"definer\" },\n { name: \"tables_seen_once_per_group\", args: \"p_user_id uuid, p_organization_ids uuid[]\", returns: \"TABLE(organization_id uuid, id uuid, seen boolean)\", security: \"definer\" },\n { name: \"tables_shared_with_me\", args: \"\", returns: \"TABLE(table_id uuid, organization_id uuid, organization text, table_name text, level text, level_label text, shared_at timestamp with time zone, opens boolean, say text)\", security: \"definer\" },\n { name: \"template_archive\", args: \"p_template_id uuid, p_restore boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\n { name: \"template_declare\", args: \"p_scope text, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"template_from_tables\", args: \"p_organization_id uuid, p_table_ids uuid[], p_include_rows boolean DEFAULT false, p_rows_per_table integer DEFAULT 25\", returns: \"jsonb\", security: \"definer\" },\n { name: \"template_install\", args: \"p_organization_id uuid, p_template_id uuid, p_budget_ms integer DEFAULT 4000\", returns: \"jsonb\", security: \"definer\" },\n { name: \"template_install_claim\", args: \"p_organization_id uuid, p_install_id uuid, p_kind text, p_label text, p_source_id uuid DEFAULT NULL::uuid, p_lease_seconds integer DEFAULT NULL::integer\", returns: \"jsonb\", security: \"definer\" },\n { name: \"template_install_note\", args: \"p_organization_id uuid, p_install_id uuid, p_kind text, p_id uuid, p_label text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"template_keep\", args: \"p_template_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"template_restore\", args: \"p_organization_id uuid, p_install_id uuid, p_budget_ms integer DEFAULT 4000\", returns: \"jsonb\", security: \"definer\" },\n { name: \"template_uninstall\", args: \"p_organization_id uuid, p_install_id uuid, p_budget_ms integer DEFAULT 4000\", returns: \"jsonb\", security: \"definer\" },\n { name: \"templates\", args: \"p_filter jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"text_head_bytes\", args: \"p_text text, p_bytes bigint\", returns: \"text\", security: \"invoker\" },\n { name: \"trg_associations_bump_visibility\", args: \"\", returns: \"trigger\", security: \"definer\" },\n { name: \"undeclared_keys\", args: \"p_organization_id uuid, p_table_id uuid, p_data jsonb\", returns: \"text[]\", security: \"invoker\" },\n { name: \"unresolved_sources_of\", args: \"p_sources jsonb, p_visible text[], p_by_id boolean DEFAULT false, p_key_ids jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"validate_custom_fields\", args: \"p_token text, p_organization_id uuid, p_values jsonb\", returns: \"void\", security: \"invoker\" },\n { name: \"validate_value_envelope\", args: \"p_organization_id uuid, p_fields custom.record[], p_data jsonb\", returns: \"void\", security: \"invoker\" },\n { name: \"validate_values\", args: \"p_organization_id uuid, p_fields custom.record[], p_values jsonb, p_record_type text DEFAULT NULL::text\", returns: \"void\", security: \"invoker\" },\n { name: \"value_alternate_keys\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"value_envelope_keys\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"value_envelope_ok\", args: \"p_data jsonb\", returns: \"boolean\", security: \"invoker\" },\n { name: \"value_envelope_refusal\", args: \"p_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"value_read\", args: \"p_organization_id uuid, p_record_id uuid, p_key text\", returns: \"TABLE(field_key text, field_id uuid, value jsonb, value_version integer, source jsonb, absent_reason text, actor text, on_behalf_of text, written_at timestamp with time zone, alternates jsonb)\", security: \"definer\" },\n { name: \"value_restore\", args: \"p_organization_id uuid, p_record_id uuid, p_field_key text, p_version integer\", returns: \"jsonb\", security: \"definer\" },\n { name: \"value_restore\", args: \"p_organization_id uuid, p_record_id uuid, p_field_key text, p_version integer, p_author jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"value_versions\", args: \"p_old jsonb, p_new jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"view_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_spec jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"view_designate\", args: \"p_organization_id uuid, p_table_id uuid, p_view_id uuid, p_layout text DEFAULT NULL::text\", returns: \"uuid\", security: \"definer\" },\n { name: \"view_keys\", args: \"\", returns: \"TABLE(path text, shape text, layouts text[], writer text, sentence text)\", security: \"invoker\" },\n { name: \"view_keys_check\", args: \"p_organization_id uuid, p_table_id uuid, p_set jsonb, p_old jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"view_look_read\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"view_look_set\", args: \"p_organization_id uuid, p_table_id uuid, p_view_id uuid, p_look jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"view_record_order_set\", args: \"p_organization_id uuid, p_view_id uuid, p_record_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n { name: \"views\", args: \"p_organization_id uuid, p_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(view_id uuid, name text, table_id uuid, filters jsonb, definition jsonb, created_at timestamp with time zone)\", security: \"definer\" },\n { name: \"visibility_ancestors\", args: \"p_item_type text, p_item_id uuid\", returns: \"TABLE(container_type text, container_id uuid, depth integer, max_level permission_level)\", security: \"definer\" },\n { name: \"visibility_as_of\", args: \"p_organization_id uuid, p_record_id uuid, p_at timestamp with time zone\", returns: \"TABLE(principal_kind text, principal_id uuid, level permission_level, through_kind text, through_id uuid, reason text, replayed boolean, held_from timestamp with time zone, held_to timestamp with time zone)\", security: \"definer\" },\n { name: \"visibility_cache_rebuild\", args: \"\", returns: \"integer\", security: \"definer\" },\n { name: \"visibility_parity\", args: \"\", returns: \"TABLE(side text, container_type text, container_id uuid, item_type text, item_id uuid, stored_level permission_level, derived_level permission_level, reason text)\", security: \"definer\" },\n { name: \"visibility_warm\", args: \"p_container_type text, p_container_id uuid\", returns: \"integer\", security: \"definer\" },\n { name: \"visible_predicate_sql\", args: \"p_user uuid, p_organization_id uuid, p_table_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level, p_alias text DEFAULT 'r'::text\", returns: \"text\", security: \"definer\" },\n { name: \"visible_record_ids\", args: \"p_user_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level\", returns: \"TABLE(id uuid)\", security: \"definer\" },\n { name: \"visible_set\", args: \"p_user uuid, p_organization_id uuid, p_table_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level, OUT o_all_visible boolean, OUT o_true_visibility platform.visibility[], OUT o_granted_all uuid[], OUT o_granted_visible uuid[], OUT o_carried_visible uuid[], OUT o_ladder_calls integer, OUT o_fallback boolean, OUT o_note text\", returns: \"record\", security: \"definer\" },\n { name: \"where_id_opens\", args: \"p_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"where_lists_live\", args: \"p_list_ids uuid[]\", returns: \"TABLE(list_id uuid, lives_in text, address text, why text)\", security: \"definer\" },\n { name: \"where_tables_live\", args: \"p_table_ids uuid[]\", returns: \"TABLE(table_id uuid, lives_in text, why text)\", security: \"definer\" },\n { name: \"whole_value_ceiling\", args: \"p_organization_id uuid\", returns: \"bigint\", security: \"invoker\" },\n { name: \"whole_value_complete\", args: \"p_organization_id uuid, p_record_id uuid, p_field_key text, p_file_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"whole_value_head\", args: \"p_text text\", returns: \"text\", security: \"invoker\" },\n { name: \"whole_value_park\", args: \"p_organization_id uuid, p_table_id uuid, p_record_id uuid, p_owner_id uuid, p_visibility platform.visibility, p_data jsonb, p_park jsonb\", returns: \"void\", security: \"invoker\" },\n { name: \"whole_value_pointer_of\", args: \"p_values jsonb, p_sources jsonb, p_key text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"whole_value_source\", args: \"p_text text, p_writer_src jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"whole_values_waiting\", args: \"p_organization_id uuid, p_record_ids uuid[]\", returns: \"TABLE(record_id uuid, field_key text, pointer text, value_version integer, sha256 text, bytes bigint, chars bigint, owner_id uuid, record_visibility text, table_id uuid, table_name text)\", security: \"definer\" },\n { name: \"widget_kernel_id\", args: \"\", returns: \"uuid\", security: \"invoker\" },\n { name: \"with_whole_value_pointers\", args: \"p_document jsonb, p_values jsonb, p_sources jsonb, p_visible text[], p_by_id boolean DEFAULT false, p_key_ids jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"withheld_marker\", args: \"p_mask jsonb, p_key text\", returns: \"jsonb\", security: \"invoker\" },\n { name: \"withheld_sentence\", args: \"p_mask jsonb, p_key text\", returns: \"text\", security: \"invoker\" },\n { name: \"work_approval_approvers\", args: \"p_organization_id uuid, p_subject_id uuid, p_approver_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(user_id uuid, name text, why text)\", security: \"definer\" },\n { name: \"work_approval_decide\", args: \"p_organization_id uuid, p_approval_id uuid, p_approve boolean, p_note text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_approval_kinds\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n { name: \"work_approval_may_decide\", args: \"p_organization_id uuid, p_approval_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"work_approval_read\", args: \"p_organization_id uuid, p_approval_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_approval_request\", args: \"p_organization_id uuid, p_subject_id uuid, p_change jsonb, p_note text DEFAULT NULL::text, p_approver_id uuid DEFAULT NULL::uuid, p_origin text DEFAULT 'person'::text, p_conversation_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_approval_withdrawal\", args: \"p_organization_id uuid, p_data jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"work_assign\", args: \"p_organization_id uuid, p_record_id uuid, p_assignee_user_id uuid, p_due_date timestamp with time zone DEFAULT NULL::timestamp with time zone, p_clear_due boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_assignment_fields\", args: \"p_options_table_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(key text, label text, spec jsonb)\", security: \"invoker\" },\n { name: \"work_decide_many\", args: \"p_organization_id uuid, p_decisions jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_has_assignment\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"work_inbox\", args: \"p_organization_id uuid DEFAULT NULL::uuid, p_limit integer DEFAULT 50, p_offset integer DEFAULT 0, p_include_decided boolean DEFAULT false, p_view text DEFAULT 'inbox'::text\", returns: \"TABLE(item_id uuid, kind text, origin text, title text, subject_id uuid, subject_kind text, summary text, state text, due_on timestamp with time zone, due_state text, actionable boolean, requested_by uuid, requested_by_name text, at timestamp with time zone, table_id uuid, table_name text, decided_by uuid, decided_by_name text, decided_at timestamp with time zone, outcome text, snoozed_until timestamp with time zone, cleared_at timestamp with time zone, snoozed_count integer, cleared_count integer, undo_seconds integer, undo_refusal text)\", security: \"definer\" },\n { name: \"work_instantiation_shape\", args: \"p_organization_id uuid, p_instantiation_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_list\", args: \"p_organization_id uuid DEFAULT NULL::uuid, p_flavour text DEFAULT 'mine'::text, p_include_finished boolean DEFAULT false, p_limit integer DEFAULT 100, p_offset integer DEFAULT 0\", returns: \"TABLE(record_id uuid, table_id uuid, table_name text, title text, assignee_id uuid, assignee_name text, assignee_user_id uuid, due_on timestamp with time zone, due_state text, status text, terminal boolean, assigned_by uuid, updated_at timestamp with time zone)\", security: \"definer\" },\n { name: \"work_person\", args: \"p_organization_id uuid, p_user_id uuid, p_create boolean DEFAULT true\", returns: \"uuid\", security: \"definer\" },\n { name: \"work_record_states\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"TABLE(state_id uuid, name text, sort integer, terminal boolean, is_current boolean, allowed boolean, refusal text)\", security: \"definer\" },\n { name: \"work_relation_kinds\", args: \"\", returns: \"TABLE(kind text, available boolean, why text)\", security: \"invoker\" },\n { name: \"work_set_state\", args: \"p_organization_id uuid, p_record_id uuid, p_state_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_slot_expire\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"integer\", security: \"definer\" },\n { name: \"work_slot_hold\", args: \"p_organization_id uuid, p_table_id uuid, p_slot_key text, p_holder text, p_ttl interval DEFAULT '00:15:00'::interval\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_slot_holds\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(hold_id uuid, slot_key text, holder text, expires_at timestamp with time zone, expired boolean)\", security: \"definer\" },\n { name: \"work_slot_index_name\", args: \"p_table_id uuid\", returns: \"text\", security: \"invoker\" },\n { name: \"work_slot_release\", args: \"p_organization_id uuid, p_hold_id uuid\", returns: \"boolean\", security: \"definer\" },\n { name: \"work_slots_declare\", args: \"p_organization_id uuid, p_name text, p_slug text, p_home_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_state_id\", args: \"p_organization_id uuid, p_table_id uuid, p_value text\", returns: \"uuid\", security: \"invoker\" },\n { name: \"work_states\", args: \"\", returns: \"TABLE(sort integer, name text, terminal boolean, next text[])\", security: \"invoker\" },\n { name: \"work_take_assignment\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_template_declare\", args: \"p_organization_id uuid, p_name text, p_graph jsonb\", returns: \"uuid\", security: \"definer\" },\n { name: \"work_template_instantiate\", args: \"p_organization_id uuid, p_template_id uuid, p_overrides jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_template_refusal\", args: \"p_graph jsonb\", returns: \"text\", security: \"invoker\" },\n { name: \"work_template_shape\", args: \"p_organization_id uuid, p_template_id uuid\", returns: \"jsonb\", security: \"definer\" },\n { name: \"work_templates\", args: \"p_organization_id uuid, p_limit integer DEFAULT 100\", returns: \"TABLE(template_id uuid, name text, nodes integer, relations integer, created_at timestamp with time zone)\", security: \"definer\" },\n { name: \"work_transition_refusal\", args: \"p_organization_id uuid, p_from_state_id uuid, p_to_state_id uuid\", returns: \"text\", security: \"definer\" },\n { name: \"work_whose_turn\", args: \"p_organization_id uuid, p_table_id uuid, p_include_finished boolean DEFAULT false\", returns: \"TABLE(record_id uuid, title text, assignee_id uuid, turn text, due_on timestamp with time zone, state text, status text, terminal boolean)\", security: \"definer\" },\n] as const;\n\n/** The campaign's own knobs, with the value the store resolves them to today. */\nexport const STORE_KNOBS = [\n { key: \"accessible_entity_ids_guard\", value: \"true\", type: \"boolean\" },\n { key: \"action_run_records_max\", value: \"5000\", type: \"integer\" },\n { key: \"agent_context_reads_the_copy\", value: \"true\", type: \"boolean\" },\n { key: \"agent_context_value_cap_bytes\", value: \"0\", type: \"integer\" },\n { key: \"agent_schema_changes\", value: \"\\\"ask\\\"\", type: \"string\" },\n { key: \"archive_confirm_over\", value: \"1000\", type: \"integer\" },\n { key: \"back_links\", value: \"true\", type: \"boolean\" },\n { key: \"batch_items_max\", value: \"500\", type: \"integer\" },\n { key: \"choice_nudge\", value: \"\\\"ask\\\"\", type: \"string\" },\n { key: \"closed_custom_field_tables\", value: \"[\\\"party\\\"]\", type: \"json\" },\n { key: \"code_paths_enabled\", value: \"true\", type: \"boolean\" },\n { key: \"consumer_chat_seeding_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"consumer_checkout_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"consumer_context_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"consumer_education_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"consumer_extension_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"consumer_grid_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"consumer_retirement_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"consumer_saved_ai_outputs_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"consumer_scopes_enabled\", value: \"false\", type: \"boolean\" },\n { key: \"containment_depth_ceiling\", value: \"16\", type: \"integer\" },\n { key: \"context_copy_following\", value: \"true\", type: \"boolean\" },\n { key: \"cross_organization_links\", value: \"false\", type: \"boolean\" },\n { key: \"data_home_default_kind\", value: \"\\\"all\\\"\", type: \"string\" },\n { key: \"data_home_default_order\", value: \"\\\"updated\\\"\", type: \"enum\" },\n { key: \"data_home_default_scope\", value: \"\\\"all\\\"\", type: \"enum\" },\n { key: \"data_home_default_view\", value: \"\\\"table\\\"\", type: \"enum\" },\n { key: \"decision_undo_seconds\", value: \"5\", type: \"integer\" },\n { key: \"decoration_rules_max\", value: \"50\", type: \"integer\" },\n { key: \"decorations_max_bytes\", value: \"262144\", type: \"integer\" },\n { key: \"document_letterhead\", value: \"{}\", type: \"json\" },\n { key: \"document_max_bytes\", value: \"1048576\", type: \"integer\" },\n { key: \"enrichment_batch_ceiling\", value: \"200\", type: \"integer\" },\n { key: \"enrichment_confidence_floor\", value: \"0.6\", type: \"number\" },\n { key: \"enrichment_cost_cap_cents\", value: \"2000\", type: \"integer\" },\n { key: \"enrichment_model\", value: \"\\\"claude-fable-5-latest\\\"\", type: \"string\" },\n { key: \"enrichment_sensitivity_ceiling\", value: \"\\\"internal\\\"\", type: \"string\" },\n { key: \"entity_types_guard\", value: \"false\", type: \"boolean\" },\n { key: \"example_rows_max\", value: \"500\", type: \"integer\" },\n { key: \"export_rows_ceiling\", value: \"100000\", type: \"integer\" },\n { key: \"external_principal_enabled\", value: \"true\", type: \"boolean\" },\n { key: \"field_sensitivity_levels\", value: \"{\\\"edit\\\": {\\\"public\\\": \\\"editor\\\", \\\"internal\\\": \\\"editor\\\", \\\"restricted\\\": \\\"admin\\\", \\\"confidential\\\": \\\"admin\\\"}, \\\"read\\\": {\\\"public\\\": \\\"viewer\\\", \\\"internal\\\": \\\"viewer\\\", \\\"restricted\\\": \\\"admin\\\", \\\"confidential\\\": \\\"editor\\\"}}\", type: \"json\" },\n { key: \"form_draft_days\", value: \"30\", type: \"integer\" },\n { key: \"form_draft_max_bytes\", value: \"65536\", type: \"integer\" },\n { key: \"form_draft_saves_per_hour\", value: \"240\", type: \"integer\" },\n { key: \"form_redirect_domains\", value: \"[]\", type: \"json\" },\n { key: \"grid_layout\", value: \"{\\\"mode\\\": \\\"auto\\\", \\\"wrap\\\": false, \\\"row_height\\\": \\\"normal\\\", \\\"fit_max_columns\\\": 8, \\\"freeze_first_column\\\": false}\", type: \"json\" },\n { key: \"inbound_domain\", value: \"\\\"inbound.matrxserver.com\\\"\", type: \"string\" },\n { key: \"inbox_reminder_after_days\", value: \"3\", type: \"integer\" },\n { key: \"member_default_level\", value: \"\\\"viewer\\\"\", type: \"enum\" },\n { key: \"outside_invite_who\", value: \"\\\"org_admins_and_table_owners\\\"\", type: \"string\" },\n { key: \"page_size_ceiling\", value: \"1000\", type: \"integer\" },\n { key: \"protected_field_rules\", value: \"{\\\"hr_employee\\\": {\\\"arm\\\": \\\"hr.arm_write\\\", \\\"rule\\\": \\\"hr.custom_field_access\\\", \\\"readers\\\": [{\\\"field\\\": \\\"subject\\\"}, {\\\"capability\\\": \\\"hr.identity.read\\\"}, {\\\"capability\\\": \\\"hr.working_record.write\\\"}, {\\\"level\\\": \\\"editor\\\", \\\"capability\\\": \\\"hr.identity.write\\\"}]}, \\\"hr_candidate\\\": {\\\"arm\\\": \\\"hr.arm_write\\\", \\\"rule\\\": \\\"hr.custom_field_access\\\", \\\"readers\\\": [{\\\"field\\\": \\\"subject\\\"}, {\\\"capability\\\": \\\"hr.identity.read\\\"}, {\\\"capability\\\": \\\"hr.working_record.write\\\"}, {\\\"level\\\": \\\"editor\\\", \\\"capability\\\": \\\"hr.identity.write\\\"}]}, \\\"hr_position_assignment\\\": {\\\"arm\\\": \\\"hr.arm_write\\\", \\\"rule\\\": \\\"hr.custom_field_access\\\", \\\"readers\\\": [{\\\"field\\\": \\\"subject\\\"}, {\\\"capability\\\": \\\"hr.identity.read\\\"}, {\\\"capability\\\": \\\"hr.working_record.write\\\"}, {\\\"level\\\": \\\"editor\\\", \\\"capability\\\": \\\"hr.identity.write\\\"}]}, \\\"hr_training_assignment\\\": {\\\"arm\\\": \\\"hr.arm_write\\\", \\\"rule\\\": \\\"hr.custom_field_access\\\", \\\"readers\\\": [{\\\"field\\\": \\\"subject\\\"}, {\\\"capability\\\": \\\"hr.identity.read\\\"}, {\\\"capability\\\": \\\"hr.working_record.write\\\"}, {\\\"level\\\": \\\"editor\\\", \\\"capability\\\": \\\"hr.identity.write\\\"}]}}\", type: \"json\" },\n { key: \"provenance_retention_days\", value: \"30\", type: \"number\" },\n { key: \"row_action_steps_max\", value: \"60\", type: \"integer\" },\n { key: \"row_actions_max\", value: \"24\", type: \"integer\" },\n { key: \"sandbox_expanded_frame_height_px\", value: \"20000\", type: \"integer\" },\n { key: \"sandbox_frame_height_px\", value: \"4000\", type: \"integer\" },\n { key: \"sandbox_message_bytes\", value: \"65536\", type: \"integer\" },\n { key: \"sandbox_org_components\", value: \"true\", type: \"boolean\" },\n { key: \"scope_members_admitted\", value: \"true\", type: \"boolean\" },\n { key: \"scopes_written_in_the_store\", value: \"true\", type: \"boolean\" },\n { key: \"signup_provisioning_guard\", value: \"false\", type: \"boolean\" },\n { key: \"stage_rule_enforcement\", value: \"\\\"refuse\\\"\", type: \"enum\" },\n { key: \"table_record_ceiling\", value: \"150000\", type: \"integer\" },\n { key: \"table_sync_rows_max\", value: \"20000\", type: \"integer\" },\n { key: \"table_webhooks_max\", value: \"10\", type: \"integer\" },\n { key: \"time_zone\", value: \"\\\"UTC\\\"\", type: \"string\" },\n { key: \"value_max_bytes\", value: \"100000\", type: \"integer\" },\n { key: \"view_record_order_max\", value: \"20000\", type: \"integer\" },\n { key: \"week_start\", value: \"\\\"monday\\\"\", type: \"enum\" },\n { key: \"world_publish_enabled\", value: \"false\", type: \"boolean\" },\n] as const;\n\n/**\n * Every SQLSTATE the store's own function bodies raise, with the functions that\n * raise it. This is the list the client's refusal mapper is checked against: a\n * code the store can raise and the package cannot name is a hole, and the\n * real-door suite says so by name.\n */\nexport const STORE_REFUSAL_CODES = [\n { code: \"02000\", raised_by: \"_checklist_instantiate,_entity_change_file,_portal_config_judge,_portal_invite_payload,_read_record_with,_share_write_person,_table_share_invite_payload,checklist_declare,checklist_run,checklist_step_complete,checklist_step_refusal,checklist_template_shape,conversation_scope_bind,dashboard_delete,dashboard_restore,dashboard_run,doc_letterhead,doc_render_body,doc_render_document,doc_render_read,doc_sign,doc_signature_intact,doc_signature_read,doc_template_delete,doc_template_read,doc_template_restore,doc_template_save,enrich_pin,entity_field_protect_arman_explicitly_approved,entity_field_retire,entity_field_update,entity_record_read,entity_row_propose,entity_row_write,entity_value_write,external_history_event,external_rows,external_stub_upsert,external_writes_set,field_choice_usage,field_restore,field_update_rehoming_choices,form_archive,form_restore,io_restore,migrate_delete,migrate_extract_parent,migrate_merge,migrate_reclass,migrate_rename,migrate_reparent,migrate_retype,migrate_split,migrate_undo,organization_clear,portal_archive,portal_card,portal_declare,portal_form,portal_form_submit,portal_invite,portal_invite_accept,portal_preview,portal_principal_bind,portal_restore,portal_revoke,record_change_many,record_delete,record_restore,record_restore_preview,record_row_controls,record_row_controls_set,record_table,record_update,record_write_graph_superseding,relation_halves_repair,relation_restore,relation_uncarry,rule_restore,set_table_confidential_arman_explicitly_approved,share_access,share_grant,share_lane_set,share_people,share_revoke,sign_request_cancel,sign_request_create,sign_request_remind,sign_request_unchanged,table_archive,table_archive_deliberately,table_restore,table_row_defaults,table_row_defaults_apply,table_row_defaults_set,table_share_outside_accept,table_share_outside_grant,table_share_outside_invite,table_share_outside_resend,table_share_outside_revoke,template_from_tables,visibility_as_of,work_approval_decide,work_approval_read,work_approval_request,work_assign,work_record_states,work_set_state\" },\n { code: \"0A000\", raised_by: \"checklist_step_complete,entity_row_write,external_rows,external_source_declare,external_write_through,promote_field,promoted_index_expr,promoted_query_sql,promoted_read,read_records_page,rule_eval,rule_filter_node_sql,work_assign\" },\n { code: \"22003\", raised_by: \"context_resolve\" },\n { code: \"22004\", raised_by: \"_entity_change_file,_entity_custom_fields_guard,_io_outbox_claim,_portal_config_judge,_share_write_person,_value_envelope,actor_word,agg_assert_key,agg_compare_windows,agg_sql,anon_capture,anon_token_issue,anon_write,assert_client_may_reach,assert_scope_door,booking_declare,capture_submit,checklist_declare,context_resolve,context_template_define,context_type_write,dashboard_block_normalize,dashboard_declare,dashboard_window_sql,doc_render_write,doc_sign,doc_signature_write,doc_template_save,enrich_land,enrich_normalize,entity_field_protect_arman_explicitly_approved,entity_row_propose,external_history_event,external_rows,external_source_declare,external_stub_upsert,external_write_through,external_writes_set,field_history,form_declare,form_look_options,form_submit,home_add,inbox_snooze,io_comment_write,io_import_begin,io_infer_column,io_outbox_drain,io_outbox_release_claimed,io_outbox_subscribe,io_restore,migrate_choice_keys,migrate_purge,migrate_purge_hard,migrate_reclass,migrate_split,migrate_undo,organization_clear,organization_contents,pipeline_declare,pipeline_gate_preview,portal_declare,portal_form_submit,portal_invite,portal_principal_bind,provenance_retention_days,provenance_write,query_across_homes,query_by_coordinates,query_rollup,record_aggregate_as_of,record_delete,record_reparent,record_resolve,record_restore,record_update,record_upsert,record_write,record_write_graph,record_write_graph_superseding,record_write_many,relation_carry,relation_halves_repair,relation_own,row_template_declare,rule_declare,set_table_confidential_arman_explicitly_approved,share_grant,sign_request_create,sign_request_sign,subscription_declare,table_archive,table_archive_deliberately,table_declare,table_duplicate,table_move,table_restore,table_share_outside_grant,table_share_outside_invite,template_declare,value_restore,view_declare,view_designate,view_look_read,view_look_set,whole_value_complete,work_approval_decide,work_approval_request,work_template_declare\" },\n { code: \"22007\", raised_by: \"_template_date,agg_parse_moment,dashboard_window_sql\" },\n { code: \"22012\", raised_by: \"formula_eval,rule_eval,rule_sql_op\" },\n { code: \"22023\", raised_by: \"_action_check,_booking_availability,_ctx_dataset_field_holds,_ctx_reference_value_holds,_ctx_store_scope,_ctx_tree_part,_decorations_check,_entity_change_file,_entity_custom_fields_guard,_form_look_judge,_fx_date,_fx_num,_fx_regex,_fx_unit,_fxp_level,_fxp_resolve,_fxp_tokens,_portal_config_judge,_rule_eval_seated,_table_dimensions_check,_take_op_id,_template_bind,_value_envelope,_view_field_key,_view_key_value,_work_shape_guard,_write_via_mark,action_run,actor_word,agent_change_trust,agg_assert_key,agg_calendar,agg_compare_windows,agg_sql,anon_token_issue,booking_declare,containment_parent,context_scope_write,context_scopes,context_template_define,context_type_write,context_values,count_records_archived,dashboard_block_normalize,dashboard_run,dashboard_target_field_assert,dashboard_window_sql,data_home,data_home_changed_by,doc_render_body,doc_render_write,doc_signature_write,drill_resolve,enrich_declare,enrich_land,enrich_normalize,enrich_pin,entity_fields_across,entity_read_mask,entity_reference_rows,entity_reference_search,entity_reference_words,entity_row_write,entity_value_write,external_history_event,external_source_declare,external_stub_upsert,external_write_through,field_access,field_history,field_update,form_declare,form_draft_save,formula_eval,formula_parse,grid_layout_check,hub_changed_by,inbound_domain,inbox_snooze,io_export,io_import_begin,io_import_finish,io_import_plan,io_import_report,io_proposal_accept,list_portals,listed_predicate_sql,member_records_take_over,migrate_merge,migrate_reclass,my_levels,organization_clear,page_size,pick_list_create,pin_agent_cells,pipeline_move,pipeline_move_many,portal_declare,portal_form_submit,provenance_write,publish_bind,query_by_coordinates,query_rollup,query_rollup_sum,read_records_archived,read_records_in_view_order,read_records_page,record_aggregate_as_of,record_change_many,record_filter_sql,record_row_controls_set,record_search_sql,record_update,record_upsert,record_write_graph,record_write_graph_superseding,record_write_many,records_search,relation_carry,relation_names_match,row_template_declare,rule_eval,rule_filter_node_sql,rule_members,rule_members_visible,rule_sql_op,scope_table_provision,share_grant,share_lane_set,sign_request_create,sign_request_sign,subscription_declare,table_archive_deliberately,table_ensure,table_find,table_from_example,table_move,table_row_defaults_set,table_rules,table_share_outside_grant,table_sync,table_transfer_owner,table_webhook_declare,template_declare,template_from_tables,template_install_claim,template_install_note,templates,view_declare,view_keys_check,view_look_set,view_record_order_set,visibility_as_of,where_lists_live,where_tables_live,work_approval_request,work_decide_many,work_inbox,work_list,work_slot_hold\" },\n { code: \"23503\", raised_by: \"_action_check,_booking_availability,_checklist_instantiate,_containment_guard,_ctx_store_value,_decorations_check,_display_spec_for,_field_document_for,_field_type_parity_guard,_pipeline_stage_key,_record_rule_uses,action_declare,action_run,agg_digest_assemble,anon_publish,anon_rate_take,anon_token_issue,anon_write,assert_organization_wall,autonumber_backfill,booking_cancel,booking_confirm,booking_declare,booking_hold,booking_reschedule,capture_publish,checklist_declare,checklist_steps_table,comment_write,dashboard_declare,delete_rule,doc_sign,doc_template_save,enrich_declare,enrich_due,enrich_land,form_declare,form_draft_save,form_submit,grid_layout,home_add,inbound_declare,inbound_mail_land,inbound_set,io_comment_write,io_import_begin,io_import_finish,io_import_report,io_import_rows,io_proposal_accept,migrate_demote,migrate_promote,migrate_purge_hard,pipeline_board,pipeline_declare,pipeline_move,pipeline_read,pipeline_transition_refusal,promote_field,promote_table,read_records_in_view_order,read_records_page,record_applicability,record_reparent,record_write_graph_superseding,relation_carry,relation_own,resolve_first_match,row_template_declare,rule_applies,rule_declare,rule_eval,rule_filter_node_sql,rule_members,rule_members_visible,rule_run,sign_request_create,subscription_mute,subscription_preview,table_decorate,table_dimensions_set,table_from_example,table_webhook_archive,table_webhook_declare,view_declare,view_designate,view_look_set,view_record_order_set,whole_value_complete,work_set_state,work_take_assignment,work_template_instantiate\" },\n { code: \"23505\", raised_by: \"_ctx_store_item,_ctx_store_scope,_ctx_store_type,_portal_config_judge,_share_write_person,_unique_rule_holds,doc_sign,doc_signature_write,entity_field_declare,field_declare,field_restore,field_update,form_restore,home_add,inbound_declare,io_proposal_accept,relation_carry,relation_own,relation_restore,sign_request_cancel,sign_request_create,table_share_outside_resend,work_approval_decide,work_slot_hold\" },\n { code: \"23514\", raised_by: \"_checklist_instantiate,_checklist_step_guard,_containment_guard,_ctx_dataset_field_holds,_ctx_scope_parent_holds,_ctx_store_item,_ctx_value_fits_its_scope,_dated_values_guard,_derived_fields,_display_format_check,_display_spec_for,_entity_choice_keys,_entity_custom_fields_guard,_field_choices_save,_field_class_guard,_field_default_fitted,_field_document_for,_field_kind_shape_ok,_field_shape_guard,_field_type_parity_guard,_kind_value_ok,_merge_field_shape_guard,_merge_field_temporal_guard,_promoted_field_cap_guard,_record_rule_uses,_record_source_key_is_record,_relation_halves_agree,_relation_kernel_targets,_resolve_choice_words,_rule_shape_guard,_rule_topology_guard,_store_relation_edge_names_its_field,_table_columns_word_guard,_table_shape_guard,_undeclared_key_guard,_value_envelope,_with_display,_work_shape_guard,_workdoors_approval_guard,action_run,assert_columns_are_defined,assert_entity_is_organization_scoped,booking_declare,capture_publish,capture_sheet_declare,checklist_declare,checklist_step_complete,dashboard_restore,doc_sign,doc_signature_write,doc_template_restore,doc_template_save,entity_field_protect_arman_explicitly_approved,entity_field_retire,entity_field_update,entity_records_find,entity_table,entity_value_write,field_declare,field_restore,field_retire,field_update,field_update_rehoming_choices,form_restore,home_add,io_comment_write,io_import_rows,migrate_merge,migrate_purge_hard,portal_archive,portal_restore,record_restore,record_update_adding_choices,record_upsert,record_write_graph,record_write_graph_superseding,relation_carry,relation_halves_repair,relation_own,relation_restore,rollup_value,row_template_declare,rule_restore,sign_request_create,sign_request_sign,status_groups_keyed,status_groups_of,table_from_example,table_restore,validate_value_envelope,validate_values,whole_value_complete,work_set_state,work_slots_declare,work_take_assignment,work_template_instantiate\" },\n { code: \"40001\", raised_by: \"has_visibility_at,table_move,whole_value_complete\" },\n { code: \"42501\", raised_by: \"_agent_change_gate,_context_copy_fence,_copy_evaluation_note,_copy_evaluation_reimage,_copy_in_progress_guard,_doc_render_immutable,_doc_signature_immutable,_entity_change_file,_entity_custom_fields_guard,_field_definition_write,_field_write_door,_io_outbox_server_only,_portal_config_judge,_portal_principal_here,_read_record_with,_rule_definition_write,_share_write_person,_store_door,_table_dimensions_infer,_table_duplicate_step,_table_shape_guard,_template_call,_value_envelope,_workdoors_approval_guard,agent_change_trust,agent_table_claim,agg_fields_readable_assert,anon_capture,anon_inbound_land,anon_publish,anon_token_issue,anon_token_verify,anon_write,assert_client_may_change,assert_client_may_open,assert_client_may_reach,assert_may_know_table,assert_organization_admin,assert_scope_door,assert_store_door,booking_confirm,booking_declare,booking_hold,capture_submit,checklist_run,comment_write,context_item_archive,context_item_restore,context_item_write,context_resolve,context_scope_archive,context_scope_restore,context_scope_write,context_tags_set,context_type_archive,context_type_restore,context_type_write,conversation_scope_bind,conversation_scope_unbind,count_records_archived,dashboard_target_field_assert,doc_sign,enrich_declare,enrich_due,enrich_land,enrich_normalize,entity_field_declare,entity_field_retire,entity_field_update,entity_row_propose,entity_row_write,entity_value_write,external_write_through,field_restore,form_declare,form_draft_save,form_public_asks,form_submit,inbound_mail_land,inbox_clear,inbox_snooze,inbox_unclear,inbox_unsnooze,io_comment_resolve,io_comment_write,io_import_begin,io_import_finish,io_restore,member_personal_tables,migrate_purge,migrate_purge_hard,migrate_purge_hard_request,migrate_reclass,my_levels,organization_clear,organization_contents,portal_declare,portal_form,portal_form_submit,portal_invitation,portal_invite,portal_invite_accept,portal_principal_bind,promote_table,protected_matches,query_visibility_parity,read_record,read_records,read_records_archived,read_records_by_ids,read_records_matching,read_records_page,record_delete,record_row_controls,record_table,record_write_graph,relation_halves_disagreements,relation_halves_repair,resolve_context,reverse_links_many,scope_table_provision,share_grant,subscription_mute,subscription_preview,table_archive_deliberately,table_copies_in_progress,table_duplicate,table_duplicate_continue,table_kind_facts,table_move,table_row_defaults_apply,table_row_defaults_set,table_share_outside_accept,table_share_outside_grant,table_share_outside_invite,table_share_outside_resend,table_sync,table_transfer_owner,table_webhook_declare,template_declare,template_install,templates,view_declare,view_look_set,view_record_order_set,visibility_as_of,where_lists_live,where_tables_live,whole_value_complete,work_approval_decide,work_approval_read,work_approval_request,work_person\" },\n { code: \"42703\", raised_by: \"entity_table,portal_declare\" },\n { code: \"42883\", raised_by: \"_template_call\" },\n { code: \"42P17\", raised_by: \"_field_reads_what_it_reads,far_value\" },\n { code: \"53400\", raised_by: \"anon_rate_take,delete_cascade_closure,enrich_due,enrich_land,promote_field\" },\n { code: \"54000\", raised_by: \"_table_dimensions_check,action_run,data_home_changed_by,form_draft_save,hub_changed_by,pipeline_move_many,record_change_many,record_headers,relation_names_match,reverse_links_many,table_decorate,table_from_example,table_row_counts,table_sync,table_webhook_declare,view_record_order_set,work_decide_many\" },\n { code: \"54001\", raised_by: \"record_delete\" },\n { code: \"55000\", raised_by: \"_code_depends_refuse,_io_outbox_claim,entity_field_protect_arman_explicitly_approved,inbox_clear,inbox_snooze,io_outbox_release,io_outbox_subscribe,table_duplicate,table_ensure,table_move,template_install,template_restore,work_approval_decide,work_approval_request\" },\n { code: \"57014\", raised_by: \"formula_eval\" },\n { code: \"MXD01\", raised_by: \"_held_change_refusal\" },\n { code: \"MXD02\", raised_by: \"entity_row_propose\" },\n { code: \"P0001\", raised_by: \"action_run,context_scope_write\" },\n { code: \"P0002\", raised_by: \"inbox_clear,inbox_snooze,publish_bind,template_archive,template_install,template_install_claim,template_install_note,template_keep,template_restore,template_uninstall,whole_value_complete\" },\n { code: \"PT409\", raised_by: \"entity_row_write,record_change_many,record_update,record_upsert,record_write_graph_superseding\" },\n { code: \"PT428\", raised_by: \"_record_rule_uses\" },\n] as const;\n\n/** `platform.entity_types` — the registered tokens a Table or relation may name. */\nexport const ENTITY_TOKENS = [\n \"access_delta_probe\",\n \"access_delta_run\",\n \"access_request\",\n \"account_addon\",\n \"acquisition_block\",\n \"activity\",\n \"admin_audit_log\",\n \"admin_email_log\",\n \"admin_markdown_sample\",\n \"admin_user\",\n \"admission_config\",\n \"agent\",\n \"agent_card\",\n \"agent_definition_version\",\n \"agent_drift_alert\",\n \"agent_exemplar\",\n \"agent_mandate_note\",\n \"agent_prompt_remediation\",\n \"agent_run\",\n \"agent_run_stage\",\n \"agent_schedule\",\n \"agent_schedule_claim\",\n \"agent_shortcut\",\n \"agent_surface_binding\",\n \"agent_template\",\n \"agent_term_list\",\n \"agent_usage\",\n \"agent_user_kv\",\n \"ai_api\",\n \"ai_calls\",\n \"ai_endpoint\",\n \"ai_model\",\n \"ai_model_alias\",\n \"ai_offering\",\n \"ai_provider\",\n \"ai_setting\",\n \"ai_setting_profile\",\n \"ai_translation_cell\",\n \"ai_usage_executions\",\n \"ai_usage_hourly\",\n \"ai_usage_hourly_watermark\",\n \"analysis_result\",\n \"anon_form\",\n \"anon_function_birth_grandfather\",\n \"anon_hit\",\n \"anon_inbound\",\n \"anon_replay\",\n \"anon_submission\",\n \"anon_token\",\n \"api_field_warning\",\n \"api_request_log\",\n \"app\",\n \"app_config\",\n \"app_config_history\",\n \"app_definition_version\",\n \"app_error\",\n \"app_execution\",\n \"app_instance\",\n \"app_log\",\n \"app_log_muted_pattern\",\n \"app_log_norm_exception\",\n \"app_rate_limit\",\n \"app_setting\",\n \"app_sync_status\",\n \"approach\",\n \"artifact\",\n \"assessment\",\n \"assessment_item\",\n \"assessment_result\",\n \"assignment_session\",\n \"assist\",\n \"assist_producer_policy\",\n \"assist_producer_policy_history\",\n \"association_type\",\n \"assurance_level\",\n \"attempt\",\n \"audit_broken_functions\",\n \"audit_canonical_findings\",\n \"audit_exemption\",\n \"audit_function_deps\",\n \"audit_function_runtime_probe\",\n \"audit_m2m_candidates\",\n \"audit_refresh_log\",\n \"audit_stale_registry\",\n \"audit_unregistered_candidates\",\n \"base_entity_template\",\n \"batch_cost_event\",\n \"batch_provider_batch\",\n \"batch_work_item\",\n \"billing_capability\",\n \"billing_capability_limit\",\n \"billing_connect_account\",\n \"billing_coupon\",\n \"billing_coupon_redemption\",\n \"billing_customer\",\n \"billing_free_period_grant\",\n \"billing_plan\",\n \"billing_plan_limit\",\n \"billing_price\",\n \"billing_product\",\n \"billing_spend_approval\",\n \"billing_spend_guardrail\",\n \"billing_stripe_event\",\n \"billing_subscription\",\n \"billing_usage_ledger\",\n \"billing_usage_reset\",\n \"billing_user_plan\",\n \"block_state\",\n \"board\",\n \"browser_account_binding\",\n \"browser_action_event\",\n \"browser_authenticator_window\",\n \"browser_capture\",\n \"browser_control_request\",\n \"browser_handoff\",\n \"browser_login_attempt\",\n \"browser_login_recipe\",\n \"browser_profile\",\n \"browser_profile_checkpoint\",\n \"browser_run\",\n \"browser_site_observation\",\n \"browser_site_policy\",\n \"browser_stream_ticket\",\n \"build_lock\",\n \"calendar_event\",\n \"campaign_watch_ramp_gate_run\",\n \"campaign_watch_switch_outbox\",\n \"campaign_watch_switch_window\",\n \"canvas_comment\",\n \"canvas_comment_like\",\n \"canvas_item\",\n \"canvas_item_state\",\n \"canvas_like\",\n \"canvas_score\",\n \"canvas_view\",\n \"capture_window\",\n \"carrying_rule\",\n \"catalog_entries_history\",\n \"catalog_entry\",\n \"category\",\n \"change_type_default\",\n \"chat_user_usage_summary\",\n \"citations\",\n \"class_purchase\",\n \"classifier_revision_ledger\",\n \"client_callable_door\",\n \"client_callable_door_retirement\",\n \"client_excluded_column_unregistered\",\n \"cmp_entry\",\n \"cmp_feedback\",\n \"code_file\",\n \"code_folder\",\n \"code_repository\",\n \"coding_session\",\n \"coding_session_entry\",\n \"comment\",\n \"commerce_asset_allocation\",\n \"commerce_asset_grading\",\n \"commerce_asset_identifier\",\n \"commerce_asset_lot_event\",\n \"commerce_asset_mandate_result\",\n \"commerce_asset_price_factor\",\n \"commerce_asset_reshoot_request\",\n \"commerce_asset_review\",\n \"commerce_asset_unknown\",\n \"commerce_certified_printer\",\n \"commerce_cloud_sync_connection\",\n \"commerce_ebay_business_policy\",\n \"commerce_ebay_category\",\n \"commerce_ebay_category_aspect\",\n \"commerce_ebay_category_tree\",\n \"commerce_ebay_custom_policy\",\n \"commerce_ebay_inventory_item\",\n \"commerce_ebay_inventory_item_group\",\n \"commerce_ebay_inventory_item_group_member\",\n \"commerce_ebay_inventory_location\",\n \"commerce_ebay_listing\",\n \"commerce_ebay_marketplace_policy\",\n \"commerce_ebay_media_asset\",\n \"commerce_ebay_notification_destination\",\n \"commerce_ebay_notification_event\",\n \"commerce_ebay_notification_subscription\",\n \"commerce_ebay_notification_topic\",\n \"commerce_ebay_offer\",\n \"commerce_ebay_order\",\n \"commerce_ebay_order_line_item\",\n \"commerce_ebay_shipping_fulfillment\",\n \"commerce_ebay_store_category\",\n \"commerce_human_correction\",\n \"commerce_intake_artifact\",\n \"commerce_intake_asset\",\n \"commerce_intake_batch\",\n \"commerce_label_batch\",\n \"commerce_label_code\",\n \"commerce_marketplace_account\",\n \"commerce_marketplace_account_deletion_audit\",\n \"commerce_marketplace_api_call\",\n \"commerce_marketplace_rate_budget\",\n \"commerce_marketplace_site\",\n \"commerce_marketplace_sync_run\",\n \"commerce_prediction_outcome\",\n \"commerce_print_order\",\n \"commerce_product\",\n \"commerce_product_channel_ref\",\n \"commerce_product_media\",\n \"commerce_product_variant\",\n \"commerce_recall_audit\",\n \"communication_calendar_selected_snapshot_state\",\n \"communication_channel_readiness\",\n \"comparison_set\",\n \"component_group\",\n \"contact_medium\",\n \"contact_submission\",\n \"content_certification\",\n \"content_ir_kind\",\n \"content_ir_kind_component\",\n \"content_ir_kind_component_incident\",\n \"content_ir_kind_conformance\",\n \"content_ir_kind_edge\",\n \"content_ir_kind_example\",\n \"content_ir_kind_instance\",\n \"content_ir_kind_surface\",\n \"content_lane\",\n \"context_access_log\",\n \"context_item\",\n \"context_item_suggestion\",\n \"context_item_value\",\n \"context_value_refs\",\n \"conversation\",\n \"conversation_value\",\n \"courts\",\n \"credential_attachment\",\n \"credential_item\",\n \"credential_mutation_receipt\",\n \"crm_address\",\n \"crm_affiliation\",\n \"crm_blocklist_entry\",\n \"crm_contact_candidate\",\n \"crm_deal\",\n \"crm_deal_stage_event\",\n \"crm_enrichment_call\",\n \"crm_interaction\",\n \"crm_merge_candidate\",\n \"crm_outreach_list\",\n \"crm_outreach_list_member\",\n \"crm_party_merge\",\n \"crm_party_research\",\n \"crm_registry_ingest_run\",\n \"crm_registry_source\",\n \"crm_sending_claim\",\n \"crm_sending_event\",\n \"crm_sending_identity\",\n \"crm_sending_identity_check\",\n \"crm_sending_policy\",\n \"custom_agent_table_trust\",\n \"custom_agg_digest_checked\",\n \"custom_entity_definition\",\n \"custom_field_definition\",\n \"custom_field_target\",\n \"custom_io_outbox_consumer\",\n \"custom_io_outbox_consumption\",\n \"custom_record\",\n \"custom_share_tails_mine_repair\",\n \"custom_template\",\n \"custom_template_install\",\n \"cx_agent_memory\",\n \"cx_agent_plan\",\n \"cx_agent_task\",\n \"cx_code_edit\",\n \"cx_code_message_file\",\n \"cx_conversation_documents\",\n \"cx_media\",\n \"cx_observational_memory\",\n \"cx_observational_memory_event\",\n \"cx_pending_injection\",\n \"cx_request\",\n \"cx_request_snapshot\",\n \"cx_tool_trace\",\n \"cx_user_request\",\n \"cx_user_todo\",\n \"dashboard_saved_view\",\n \"data_rights_event\",\n \"data_store\",\n \"data_store_members\",\n \"dataset\",\n \"ddl_guard_log\",\n \"deck_suggestion\",\n \"definer_class_exemption\",\n \"definer_client_grant_grandfather\",\n \"definer_grant_baseline\",\n \"deprecated_relation\",\n \"derive_run\",\n \"dev_login_audit\",\n \"dict_entry\",\n \"dict_provider_publication\",\n \"dict_setting\",\n \"dm_conversation\",\n \"dm_message\",\n \"dm_participant\",\n \"doc_render\",\n \"doc_signature\",\n \"dockets\",\n \"document\",\n \"document_version\",\n \"domain_classification\",\n \"edge_payload_kind\",\n \"egress_device\",\n \"egress_pairing\",\n \"egress_ticket\",\n \"emails\",\n \"embedding_cache\",\n \"embeddings_google_gemini_2_1536\",\n \"embeddings_oai_3_small_1536\",\n \"embeddings_voyage_4_large_1024\",\n \"embeddings_voyage_code_3_1024\",\n \"endpoint_family_sweep_state\",\n \"engine_owner_task\",\n \"entity_grant\",\n \"entity_protected_value\",\n \"entity_protected_value_version\",\n \"entity_relationship\",\n \"entity_type\",\n \"esign_campaign\",\n \"esign_campaign_member\",\n \"esign_consent_disclosure\",\n \"esign_envelope\",\n \"esign_envelope_certificate\",\n \"esign_envelope_document\",\n \"esign_envelope_event\",\n \"esign_envelope_external_ref\",\n \"esign_envelope_signer\",\n \"esign_provider\",\n \"esign_provider_binding\",\n \"esign_signing_key\",\n \"execution_event_cursor\",\n \"extension_auth_code\",\n \"external_link\",\n \"external_source\",\n \"extract_sweep_state\",\n \"fc_card\",\n \"fc_detail\",\n \"fc_set\",\n \"feature_doc\",\n \"feature_knob\",\n \"feedback_comments\",\n \"feedback_user_messages\",\n \"field_component\",\n \"file\",\n \"file_analysis\",\n \"file_entities\",\n \"file_overrides\",\n \"file_page_annotations\",\n \"file_pages\",\n \"file_rag_job\",\n \"file_version\",\n \"files_account_tier\",\n \"files_machine_written_prefix\",\n \"files_sync_mapping\",\n \"files_user_account\",\n \"flashcard_data\",\n \"flashcard_history\",\n \"flashcard_sets\",\n \"flexible_data\",\n \"folder\",\n \"function_contract\",\n \"game_badge\",\n \"game_result\",\n \"game_room\",\n \"global_execution\",\n \"global_execution_checkpoint\",\n \"global_execution_control\",\n \"global_execution_event\",\n \"global_meter_entry\",\n \"global_origin\",\n \"global_request\",\n \"google_document\",\n \"growth_loop_event\",\n \"growth_loop_run\",\n \"growth_loop_stage_run\",\n \"guardian_link\",\n \"guest_conversion_audit\",\n \"guest_execution_log\",\n \"guest_executions\",\n \"guided_checklist_run\",\n \"heatmap_save\",\n \"hindsight_enrollment\",\n \"hindsight_finding\",\n \"hindsight_regression_case\",\n \"hindsight_replay\",\n \"hindsight_replay_step\",\n \"hindsight_review\",\n \"hr_access_audit\",\n \"hr_access_role\",\n \"hr_accommodation_request\",\n \"hr_ai_evidence\",\n \"hr_alert_routing_rule\",\n \"hr_application\",\n \"hr_approval_authority\",\n \"hr_approval_delegation\",\n \"hr_asset\",\n \"hr_asset_assignment\",\n \"hr_attendance_exception\",\n \"hr_auto_close_rule\",\n \"hr_availability\",\n \"hr_background_check\",\n \"hr_benefits_event\",\n \"hr_calculation_snapshot\",\n \"hr_candidate\",\n \"hr_candidate_conversion\",\n \"hr_candidate_message\",\n \"hr_careers_portal\",\n \"hr_checklist_item\",\n \"hr_checklist_run\",\n \"hr_checklist_template\",\n \"hr_checklist_template_item\",\n \"hr_compensation\",\n \"hr_corrective_action\",\n \"hr_course\",\n \"hr_course_version\",\n \"hr_credential\",\n \"hr_crew\",\n \"hr_deduction_code\",\n \"hr_department\",\n \"hr_derived_grant\",\n \"hr_disposition_event\",\n \"hr_earning_code\",\n \"hr_eeo_response\",\n \"hr_emergency_contact\",\n \"hr_employee\",\n \"hr_employee_private\",\n \"hr_employer_profile\",\n \"hr_employment\",\n \"hr_employment_pin\",\n \"hr_engagement\",\n \"hr_establishment\",\n \"hr_external_identity\",\n \"hr_field_policy\",\n \"hr_holiday\",\n \"hr_holiday_calendar\",\n \"hr_i9\",\n \"hr_i9_document\",\n \"hr_incident\",\n \"hr_incident_party\",\n \"hr_interview\",\n \"hr_interview_kit\",\n \"hr_job_title\",\n \"hr_jurisdiction\",\n \"hr_jurisdiction_rule\",\n \"hr_jurisdiction_rule_class\",\n \"hr_jurisdiction_rule_org_decision\",\n \"hr_jurisdiction_rule_test\",\n \"hr_kiosk_device\",\n \"hr_kiosk_session\",\n \"hr_labor_target\",\n \"hr_leave_case\",\n \"hr_leave_enrollment\",\n \"hr_leave_ledger\",\n \"hr_leave_policy\",\n \"hr_leave_request\",\n \"hr_legal_hold\",\n \"hr_legal_hold_item\",\n \"hr_location\",\n \"hr_new_hire_report\",\n \"hr_offer\",\n \"hr_opening\",\n \"hr_overtime_alert\",\n \"hr_overtime_alert_rule\",\n \"hr_overtime_preapproval\",\n \"hr_pay_group\",\n \"hr_pay_period\",\n \"hr_pay_period_employment\",\n \"hr_payroll_export\",\n \"hr_payroll_export_line\",\n \"hr_position_assignment\",\n \"hr_posting\",\n \"hr_posting_publication\",\n \"hr_provider_binding\",\n \"hr_provider_event\",\n \"hr_provisioning_result\",\n \"hr_punch\",\n \"hr_recalculation_batch\",\n \"hr_record_class\",\n \"hr_records_request\",\n \"hr_reference_check\",\n \"hr_reporting_line\",\n \"hr_requisition\",\n \"hr_restricted_note\",\n \"hr_retention_rule\",\n \"hr_role_assignment\",\n \"hr_schedule\",\n \"hr_schedule_change\",\n \"hr_schedule_guidance\",\n \"hr_schedule_template\",\n \"hr_schedule_template_shift\",\n \"hr_scorecard\",\n \"hr_separation\",\n \"hr_shift\",\n \"hr_shift_claim\",\n \"hr_staffing_requirement\",\n \"hr_survey\",\n \"hr_survey_invitation\",\n \"hr_survey_question\",\n \"hr_survey_response\",\n \"hr_tax_registration\",\n \"hr_tax_withholding\",\n \"hr_time_adjustment\",\n \"hr_training_assignment\",\n \"hr_training_attempt\",\n \"hr_transcript_entry\",\n \"hr_verification_letter_request\",\n \"hr_work_interval\",\n \"hr_workflow_binding\",\n \"hr_workflow_decision\",\n \"hr_workflow_definition\",\n \"hr_workflow_event\",\n \"hr_workflow_failure\",\n \"hr_workflow_flow_type\",\n \"hr_workflow_instance\",\n \"hr_workflow_step\",\n \"hr_workflow_step_definition\",\n \"hr_workweek\",\n \"html_extraction\",\n \"iam_access_audit\",\n \"iam_api_key\",\n \"iam_emergency_door_request\",\n \"iam_org_availability_key\",\n \"iam_read_lane_v2_rollout\",\n \"idempotency\",\n \"industry\",\n \"industry_curator\",\n \"infra_status\",\n \"ingest_runs\",\n \"integration_connection\",\n \"integration_connection_resource\",\n \"interview_decision_interview\",\n \"interview_decision_question\",\n \"interview_document_revision\",\n \"interview_hole\",\n \"interview_question\",\n \"interview_session\",\n \"interview_turn\",\n \"invitation\",\n \"invitation_code\",\n \"invitation_request\",\n \"io_comment\",\n \"io_contract\",\n \"io_import\",\n \"io_outbox\",\n \"item\",\n \"item_mastery\",\n \"judge_verdict\",\n \"jurisdiction_policy\",\n \"keyword_classification_queue\",\n \"kg_alert\",\n \"kg_chunk_entities\",\n \"kg_chunks\",\n \"kg_clusters\",\n \"kg_edges\",\n \"kg_entities\",\n \"kg_entity_aliases\",\n \"kg_suggestion_ack\",\n \"kg_sweep_queue\",\n \"kg_sweep_run\",\n \"kg_sweep_state\",\n \"kg_value_match\",\n \"knob_override\",\n \"knob_override_audit\",\n \"knob_rung_lock\",\n \"knob_scope_kind\",\n \"knob_write_door\",\n \"league_membership\",\n \"learn_doc\",\n \"library_doc\",\n \"lifecycle_archive\",\n \"lifecycle_archive_row\",\n \"lifecycle_audit\",\n \"lifecycle_entity_plan\",\n \"lifecycle_map_build\",\n \"lifecycle_reference_map\",\n \"lifecycle_run\",\n \"lifecycle_tier_ledger\",\n \"location\",\n \"mandate\",\n \"mandate_advance_batch_row\",\n \"mandate_binding\",\n \"mandate_candidate\",\n \"mandate_candidate_run\",\n \"mandate_candidate_run_payload\",\n \"mandate_goal_clauses\",\n \"mandate_observation\",\n \"mandate_reference\",\n \"mandate_scan\",\n \"mandate_treatment\",\n \"marketing_initiative\",\n \"masterwork_corpus_item\",\n \"masterwork_run\",\n \"masterwork_run_kind\",\n \"masterwork_source\",\n \"math_course_structure\",\n \"math_problem\",\n \"matrx_action_ledger\",\n \"mcp_config\",\n \"mcp_server\",\n \"mcp_user_conn\",\n \"media_capture_handoff\",\n \"media_catalog_setting\",\n \"media_library_item\",\n \"media_selection_item\",\n \"media_selection_job\",\n \"media_source_library\",\n \"meet_call_invite\",\n \"meet_chat_message\",\n \"meet_invitee\",\n \"meet_meeting\",\n \"meet_note\",\n \"meet_occurrence_override\",\n \"meet_participant\",\n \"meet_recording\",\n \"meet_transcript_segment\",\n \"membership\",\n \"membership_grant\",\n \"merge_field_provenance\",\n \"message\",\n \"message_template\",\n \"message_template_detail\",\n \"meta_excluded_schema\",\n \"meta_table_stats_history\",\n \"metadata_reserved_keys\",\n \"microservice_project\",\n \"migration_log\",\n \"mtx_media_heal_queue\",\n \"mtx_public_url_guard\",\n \"ner_shadow\",\n \"note\",\n \"note_folder\",\n \"notification\",\n \"notification_channel_preference\",\n \"notification_event_override\",\n \"notification_event_type\",\n \"notification_preference\",\n \"notification_submission\",\n \"notify_outsider_door_baseline\",\n \"oauth_handoff_claim\",\n \"opinion_clusters\",\n \"opinions\",\n \"ops_check_item\",\n \"ops_check_run\",\n \"ops_db_host_sample\",\n \"ops_issue_class\",\n \"ops_issue_event\",\n \"ops_proof_check\",\n \"ops_proof_run\",\n \"ops_proof_scenario\",\n \"org_admin_audit\",\n \"org_change_policy\",\n \"org_context_ledger\",\n \"org_industries\",\n \"org_member_control\",\n \"org_module_config\",\n \"org_plan\",\n \"organization\",\n \"organization_preferences\",\n \"organization_visibility_version\",\n \"output_feedback\",\n \"outreach_acceptance\",\n \"page_extraction_job\",\n \"page_extraction_page_run\",\n \"page_extraction_results\",\n \"page_extraction_runs\",\n \"page_intent_queue\",\n \"page_mapping_queue\",\n \"part_config\",\n \"part_config_sub\",\n \"party\",\n \"party_contact_point\",\n \"passkey_credential\",\n \"pb_claim_appeals_fd31de\",\n \"pb_insurance_claims_fd31de\",\n \"pc_article\",\n \"pc_episode\",\n \"pc_show\",\n \"pc_studio_run\",\n \"pc_studio_run_asset\",\n \"pdf_consolidation_log\",\n \"pdf_redaction_audit\",\n \"pdf_redaction_key_escrow\",\n \"permission_grant\",\n \"plan_cms_fill_item\",\n \"plan_cms_fill_job\",\n \"plan_entity\",\n \"plan_node\",\n \"plan_node_artifact\",\n \"plan_node_step\",\n \"plan_profile\",\n \"platform_action_request\",\n \"platform_actor_session\",\n \"platform_actor_token\",\n \"platform_actor_token_event\",\n \"platform_class_approval_by_arman\",\n \"platform_continued_access\",\n \"platform_cutover_census_run\",\n \"platform_cutover_evaluation_replaced\",\n \"platform_cutover_evaluation_write\",\n \"platform_cutover_seam\",\n \"platform_cutover_seam_measure\",\n \"platform_cutover_seam_press\",\n \"platform_dated_change\",\n \"platform_doors_only_pending_cutover\",\n \"platform_google_calendar_event_create_intent\",\n \"platform_google_task_create_intent\",\n \"platform_kernel_fingerprint_record\",\n \"platform_org_knob_override\",\n \"platform_outcome_event\",\n \"platform_outsider_consumer\",\n \"platform_provision_base_contract_pending\",\n \"platform_reachability\",\n \"platform_reachability_rebuild_pending\",\n \"platform_realtime_topic_prefix\",\n \"platform_reference_category\",\n \"platform_reference_declaration\",\n \"platform_repo\",\n \"platform_saved_view\",\n \"platform_schema\",\n \"platform_secure_delivery\",\n \"platform_share_link\",\n \"platform_strict_class_probe\",\n \"platform_user_knob_override\",\n \"podcast_race\",\n \"position\",\n \"processed_document\",\n \"processed_document_page\",\n \"product_capture_file\",\n \"product_capture_item\",\n \"product_capture_payload\",\n \"product_capture_product\",\n \"product_capture_question\",\n \"profile\",\n \"project\",\n \"prompt\",\n \"provider_account\",\n \"provider_account_credential\",\n \"provision\",\n \"provision_generate_target\",\n \"provision_grant\",\n \"provision_marker\",\n \"provision_rule_message\",\n \"provision_schema\",\n \"provision_shape_debt\",\n \"provision_spec\",\n \"provision_spec_grandfather\",\n \"provision_vocabulary\",\n \"provlock_recall_visits_all8u5\",\n \"purpose\",\n \"quiz_session\",\n \"rag_ingest_run\",\n \"rag_library_audit_log\",\n \"rate_limit_buckets\",\n \"reachability_pending\",\n \"recompute_queue\",\n \"record\",\n \"record_alias\",\n \"redaction_mapping\",\n \"research_analysis\",\n \"research_content\",\n \"research_context_bundle\",\n \"research_document\",\n \"research_intent\",\n \"research_keyword\",\n \"research_media\",\n \"research_source\",\n \"research_synthesis\",\n \"research_tag\",\n \"research_template\",\n \"research_topic\",\n \"retention_policy\",\n \"retrieval_audit\",\n \"review_queue\",\n \"route_manifest_entry\",\n \"row_version\",\n \"rulebook\",\n \"runtime_operation_stream\",\n \"runtime_operation_stream_batch\",\n \"sandbox_instance\",\n \"sch_agent_task\",\n \"sch_run\",\n \"sch_task\",\n \"sch_trigger\",\n \"schema_client_exposure\",\n \"schema_migration_ledger\",\n \"schema_migration_legacy\",\n \"schema_migration_slot_grandfather\",\n \"schema_templates\",\n \"scope\",\n \"scope_association_suggestion\",\n \"scope_dataset_instance\",\n \"scope_door_registry\",\n \"scope_item_value_suggestion\",\n \"scope_suggestion\",\n \"scope_type\",\n \"scrape_domain\",\n \"scrape_domain_settings\",\n \"scrape_failure_log\",\n \"scrape_parsed_page\",\n \"scrape_path_override\",\n \"scrape_path_pattern\",\n \"scrape_retry_queue\",\n \"search_item\",\n \"seo_ai_capability\",\n \"seo_ai_visibility_citation\",\n \"seo_ai_visibility_claim\",\n \"seo_ai_visibility_panel\",\n \"seo_ai_visibility_response\",\n \"seo_ai_visibility_signal\",\n \"seo_backlink\",\n \"seo_backlink_change_event\",\n \"seo_backlink_dimension_snapshot\",\n \"seo_backlink_observation\",\n \"seo_backlink_snapshot\",\n \"seo_change_assessment\",\n \"seo_change_event\",\n \"seo_change_item\",\n \"seo_change_metric\",\n \"seo_change_set\",\n \"seo_change_theory\",\n \"seo_collection_run\",\n \"seo_competitor\",\n \"seo_competitor_observation\",\n \"seo_competitor_opportunity\",\n \"seo_coverage_mention\",\n \"seo_coverage_tracker\",\n \"seo_dimension_value_matcher\",\n \"seo_engine_schedule\",\n \"seo_geo_place\",\n \"seo_gsc_dig_rule\",\n \"seo_keyword\",\n \"seo_keyword_class_rule\",\n \"seo_keyword_edge\",\n \"seo_keyword_facet\",\n \"seo_keyword_market\",\n \"seo_keyword_market_observation\",\n \"seo_keyword_place\",\n \"seo_keyword_saved_view\",\n \"seo_keyword_topic\",\n \"seo_landscape_brief\",\n \"seo_link_gap_domain\",\n \"seo_link_gap_match\",\n \"seo_map_facet\",\n \"seo_map_facet_value\",\n \"seo_map_topic\",\n \"seo_page_measurement_health\",\n \"seo_page_performance\",\n \"seo_pr_moment\",\n \"seo_provider_call\",\n \"seo_provider_task\",\n \"seo_rank_observation\",\n \"seo_rank_target\",\n \"seo_raw_payload\",\n \"seo_referring_domain_profile\",\n \"seo_reputation_case\",\n \"seo_search_performance_daily\",\n \"seo_serp_mention\",\n \"seo_serp_opportunity\",\n \"seo_serp_result\",\n \"seo_serp_snapshot\",\n \"seo_site_geo_area\",\n \"seo_site_keyword_offering\",\n \"seo_site_keyword_value\",\n \"seo_site_offering_value\",\n \"seo_site_topic_value\",\n \"seo_site_value_combo\",\n \"seo_site_value_worth\",\n \"seo_site_vocabulary\",\n \"seo_source_request\",\n \"seo_starter_pack\",\n \"seo_starter_pack_item\",\n \"seo_story_angle\",\n \"seo_topic\",\n \"seo_topical_map\",\n \"seo_tracker_story\",\n \"seo_web_analytics_daily\",\n \"share_link\",\n \"shareable_resource_registry\",\n \"shared_canvas_item\",\n \"short_link\",\n \"shortcut_category\",\n \"sign_in_fk_legacy\",\n \"skill\",\n \"skill_category\",\n \"skill_detail\",\n \"skill_render_definition\",\n \"sms_consent\",\n \"sms_conversation\",\n \"sms_message\",\n \"sms_message_media\",\n \"sms_notification\",\n \"sms_notification_preference\",\n \"sms_phone_number\",\n \"sms_rate_limits\",\n \"sms_webhook_logs\",\n \"soft_delete_cascade_job\",\n \"soft_delete_edge\",\n \"source_authority\",\n \"space_payload\",\n \"stage_ref_kind\",\n \"stamped_write_table\",\n \"structure\",\n \"structured_list\",\n \"studio_cleaned_segments\",\n \"studio_concept_items\",\n \"studio_documents\",\n \"studio_module_segments\",\n \"studio_raw_segments\",\n \"studio_recording_chunks\",\n \"studio_recording_segments\",\n \"studio_run\",\n \"studio_session\",\n \"studio_session_settings\",\n \"study_attempt\",\n \"study_goal\",\n \"study_media\",\n \"study_plan\",\n \"study_plan_block\",\n \"study_plan_day\",\n \"study_reminder_context\",\n \"study_reminder_delivery\",\n \"study_session\",\n \"study_source_chunk\",\n \"study_streak\",\n \"study_structured_section\",\n \"superseded_policy\",\n \"surface\",\n \"system_announcement\",\n \"system_context_item\",\n \"system_error\",\n \"system_orgs\",\n \"system_write_failure\",\n \"t13_backfill_ledger\",\n \"t13_default_ledger\",\n \"t13_row_column_events\",\n \"tag\",\n \"task\",\n \"task_user_state\",\n \"taxonomy_node\",\n \"team\",\n \"template_context_items\",\n \"template_scope_types\",\n \"templates\",\n \"test_handset_inbox\",\n \"test_handset_verification\",\n \"thread\",\n \"tool\",\n \"tool_binding\",\n \"tool_bundle\",\n \"tool_call\",\n \"tool_definition_version\",\n \"tool_executor\",\n \"tool_surface_defaults\",\n \"tool_test_sample\",\n \"tool_ui\",\n \"tool_ui_incident\",\n \"tool_ui_version\",\n \"topic_placement_queue\",\n \"transcript\",\n \"trigger_event\",\n \"udt_dataset_fields\",\n \"udt_dataset_row_versions\",\n \"udt_dataset_rows\",\n \"udt_dataset_template\",\n \"udt_dataset_template_fields\",\n \"udt_document\",\n \"udt_document_snapshot\",\n \"udt_structured_list_items\",\n \"udt_workbook_snapshot\",\n \"ui_client\",\n \"ui_surface_agent_pref\",\n \"ui_surface_agent_role\",\n \"ui_surface_client_tool\",\n \"ui_surface_config\",\n \"ui_surface_item_type\",\n \"ui_surface_value\",\n \"ui_surface_write_target\",\n \"univer_payload\",\n \"unsubscribe_token\",\n \"uploads_inflight\",\n \"user\",\n \"user_achievement\",\n \"user_active_context\",\n \"user_analysis_preference\",\n \"user_email_preference\",\n \"user_entity_state\",\n \"user_feedback\",\n \"user_follows\",\n \"user_form_profile\",\n \"user_markdown_sample\",\n \"user_memory\",\n \"user_preference\",\n \"user_profile\",\n \"user_secret\",\n \"user_secret_audit\",\n \"user_secret_grant\",\n \"user_stat\",\n \"user_storage_usage\",\n \"user_surface_state\",\n \"vault_fill_approvals\",\n \"vault_fill_devices\",\n \"vault_fill_nonces\",\n \"visibility_cache\",\n \"visibility_epoch\",\n \"voice\",\n \"war_room\",\n \"wbx_demo\",\n \"wbx_guidance\",\n \"wbx_highlight\",\n \"wbx_pattern\",\n \"wbx_recipe\",\n \"wbx_screenshot\",\n \"wbx_seo_audit\",\n \"wc_claim\",\n \"wc_impairment_definition\",\n \"wc_injury\",\n \"wc_report\",\n \"web_analysis_item\",\n \"web_brand\",\n \"web_brand_asset\",\n \"web_brand_offering\",\n \"web_business_fact\",\n \"web_business_location\",\n \"web_channel_analytics_daily\",\n \"web_crawl_event\",\n \"web_crawl_preset\",\n \"web_crawl_schedule\",\n \"web_crawl_session\",\n \"web_crawl_url\",\n \"web_discovered_item\",\n \"web_finding\",\n \"web_gsc_page_stat\",\n \"web_link_edge\",\n \"web_listing_publisher\",\n \"web_location_listing\",\n \"web_news_item\",\n \"web_offering_template\",\n \"web_page\",\n \"web_page_content\",\n \"web_page_evidence\",\n \"web_page_sitemap\",\n \"web_property\",\n \"web_provider\",\n \"web_result\",\n \"web_screenshot\",\n \"web_site\",\n \"web_site_endpoint_rule\",\n \"web_site_item_config\",\n \"web_site_offering\",\n \"web_sitemap\",\n \"web_snapshot\",\n \"web_tag_manager_snapshot\",\n \"web_voice_fingerprint\",\n \"web_youtube_video\",\n \"webhook_deliveries\",\n \"webhook_dispatch_state\",\n \"webhooks\",\n \"wf_node_data_slot\",\n \"work_claim\",\n \"work_item\",\n \"workbook\",\n \"worker_heartbeat\",\n \"workflow\",\n \"workflow_card\",\n \"workflow_checkpoint\",\n \"workflow_comparison\",\n \"workflow_definition_version\",\n \"workflow_idempotency\",\n \"workflow_job\",\n \"workflow_node_events\",\n \"workflow_node_outcome\",\n \"workflow_plan\",\n \"workflow_plan_event\",\n \"workflow_plan_sample\",\n \"workflow_recovery_audit\",\n \"workflow_run\",\n \"workflow_run_cost\",\n \"workflow_run_facts\",\n \"workflow_run_log\",\n \"workflow_runtime_surface\",\n \"workflow_template\",\n \"workflow_trigger\",\n \"workflow_trigger_fire\",\n \"workflow_work_item\",\n \"working_document\",\n \"write_guard_key\",\n \"youtube_quota_day\",\n \"youtube_search\",\n \"youtube_video\",\n] as const;\n\nexport type StoreRefusalCode = (typeof STORE_REFUSAL_CODES)[number][\"code\"];\nexport type StoreDoorName = (typeof STORE_DOORS)[number][\"name\"];\nexport type EntityToken = (typeof ENTITY_TOKENS)[number];\nexport type KernelTableName = (typeof KERNEL_TABLES)[number][\"name\"];\n","// src/templates/validate.ts — @ai-matrx/records (templates, internal)\n//\n// THE QUALITY GATE'S Q1 AND Q2, AS CODE — and the pieces the installer shares with it.\n//\n// resolveRelativeDates(spec, today) every \"@today±N…\" token → the store's date/moment text\n// storeAggregate(...) custom.record_aggregate over seed rows, its semantics exactly\n// toUseCase(spec) the five UseCase singulars, derived (never stated twice)\n// validateTemplate(spec, {agents}) Q1 law/shape/graph + Q2 capability, by sentence\n//\n// The mirrors were written from the store's own bodies, read on the clone 2026-10-02:\n// custom.agg_sql / agg_value_sql / record_filter_sql / dashboard_window_sql (aggregates and\n// filters), custom._table_dimensions_infer / _table_dimensions_check (Dimensions),\n// custom.doc_tokens / doc_render_body (merge fields), custom.portal_declare (names_via),\n// custom.io_import_begin (imports). A mirror that disagrees with its door is a defect in\n// the mirror: fix it here, never loosen a template to pass it.\n\nimport { tableSettingsProblems } from \"./confidential\";\nimport { extrasProblems } from \"./extras\";\nimport { DECLARABLE_FIELD_KINDS, PARITY_FIELD_TYPES, STORE_DOORS } from \"../store.generated\";\nimport type { AggregateFilter, AggregateMeasure } from \"../aggregate\";\nimport type { UseCase, UseCaseTable } from \"../use-cases/types\";\nimport { validateUseCase, type UseCaseProblem } from \"../use-cases/validate\";\nimport { findBannedLabel } from \"../use-cases/placeholders\";\n// payloads.ts holds the booking-columns check the validator also asks;\n// it imports nothing from here.\nimport { bookingColumnsProblem } from \"./payloads\";\nimport {\n CAPABILITY_WORDS,\n CHOICE_COLORS,\n ENTITY_REFERENCE_KINDS,\n DEFAULT_TEMPLATE_AGENT,\n INDUSTRY_GROUPS,\n RELATIVE_DATE,\n SHARED_BLOCKS,\n SHARED_BLOCK_IDS,\n STRENGTHS,\n TEACHES_FEATURES,\n TEMPLATE_AUDIENCES,\n TEMPLATE_JOBS,\n TEMPLATE_REFERENCE_DATE,\n TEMPLATE_SPEC_VERSION,\n TEMPLATE_VIEW_KINDS,\n type AgentSnapshotRow,\n type CapabilityWord,\n type SharedBlockId,\n type TemplateField,\n type TemplateSpec,\n type TemplateTable,\n type TemplateView,\n type WalkAction,\n type WalkMove,\n} from \"./types\";\n\n// ═════════════════════════════════════════════════════════════════════════════\n// Relative dates\n// ═════════════════════════════════════════════════════════════════════════════\n\nconst pad = (n: number, w = 2) => String(n).padStart(w, \"0\");\n\n/** The UTC offset (\"-04:00\") of a local wall-clock moment in an IANA zone. */\nexport function zoneOffset(localIso: string, timeZone: string): string {\n const [d, t = \"00:00\"] = localIso.split(\"T\");\n const [y, mo, da] = (d ?? \"\").split(\"-\").map(Number);\n const [h, mi] = t.split(\":\").map(Number);\n const guess = Date.UTC(y ?? 1970, (mo ?? 1) - 1, da ?? 1, h ?? 0, mi ?? 0);\n const read = (at: number) => {\n const part = new Intl.DateTimeFormat(\"en-US\", { timeZone, timeZoneName: \"longOffset\" })\n .formatToParts(new Date(at))\n .find((p) => p.type === \"timeZoneName\")?.value;\n const m = /GMT([+-])(\\d{2}):?(\\d{2})?/.exec(part ?? \"\");\n return m ? (m[1] === \"-\" ? -1 : 1) * (Number(m[2]) * 60 + Number(m[3] ?? 0)) : 0;\n };\n const minutes = read(guess - read(guess) * 60_000);\n const sign = minutes < 0 ? \"-\" : \"+\";\n return `${sign}${pad(Math.floor(Math.abs(minutes) / 60))}:${pad(Math.abs(minutes) % 60)}`;\n}\n\nfunction addToDay(today: string, sign: string, n: number, unit: string): string {\n const [y, m, d] = today.split(\"-\").map(Number) as [number, number, number];\n const k = sign === \"-\" ? -n : n;\n if (unit === \"d\" || unit === \"w\") {\n const at = new Date(Date.UTC(y, m - 1, d + (unit === \"w\" ? 7 * k : k)));\n return `${at.getUTCFullYear()}-${pad(at.getUTCMonth() + 1)}-${pad(at.getUTCDate())}`;\n }\n const months = unit === \"y\" ? 12 * k : k;\n const first = new Date(Date.UTC(y, m - 1 + months, 1));\n const last = new Date(Date.UTC(first.getUTCFullYear(), first.getUTCMonth() + 1, 0)).getUTCDate();\n return `${first.getUTCFullYear()}-${pad(first.getUTCMonth() + 1)}-${pad(Math.min(d, last))}`;\n}\n\nconst WEEKDAYS = [\"sun\", \"mon\", \"tue\", \"wed\", \"thu\", \"fri\", \"sat\"];\nconst WEEKDAY_NAMES = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nconst dayOfWeek = (day: string) => new Date(`${day}T00:00:00Z`).getUTCDay();\nconst shiftDays = (day: string, n: number) => addToDay(day, n < 0 ? \"-\" : \"+\", Math.abs(n), \"d\");\n\nfunction addBusinessDays(day: string, n: number): string {\n let d = day;\n let left = Math.abs(n);\n while (left > 0) {\n d = shiftDays(d, n < 0 ? -1 : 1);\n const w = dayOfWeek(d);\n if (w !== 0 && w !== 6) left -= 1;\n }\n return d;\n}\n\n/** One token → \"2026-10-08\" or \"2026-10-08T09:30:00-04:00\". `null` when it is not a token. */\nexport function resolveDateToken(token: string, today: string, timeZone: string): string | null {\n const m = RELATIVE_DATE.exec(token);\n if (!m) return null;\n let day = today;\n const anchor = m[1] ?? \"today\";\n if (anchor !== \"today\") {\n const name = anchor.replace(/^(last|next)-/, \"\");\n const monday = shiftDays(today, -((dayOfWeek(today) + 6) % 7));\n day = shiftDays(monday, (WEEKDAYS.indexOf(name) + 6) % 7 + (anchor.startsWith(\"last-\") ? -7 : anchor.startsWith(\"next-\") ? 7 : 0));\n }\n if (m[2]) {\n const n = Number(m[3]) * (m[2] === \"-\" ? -1 : 1);\n day = m[4] === \"b\" ? addBusinessDays(day, n) : addToDay(day, m[2], Number(m[3]), m[4] ?? \"d\");\n }\n if (m[5]) {\n const w = dayOfWeek(day);\n if (w === 6) day = shiftDays(day, 2);\n if (w === 0) day = shiftDays(day, 1);\n }\n if (m[6] === undefined) return day;\n const local = `${day}T${m[6]}:${m[7]}`;\n return `${local}:00${zoneOffset(local, timeZone)}`;\n}\n\n/** True when the token carries an explicit time of day. */\nexport function relativeHasTime(token: string): boolean {\n return RELATIVE_DATE.exec(token)?.[6] !== undefined;\n}\n\n/**\n * Every relative-date token anywhere in the spec, resolved against `today` (the install\n * day, \"YYYY-MM-DD\") in the business's time zone. Returns a copy; the input is untouched.\n */\nexport function resolveRelativeDates<T extends Pick<TemplateSpec, \"business\">>(spec: T, today: string): T {\n const tz = spec.business?.timezone || \"UTC\";\n const walk = (v: unknown): unknown => {\n if (typeof v === \"string\") return resolveDateToken(v, today, tz) ?? v;\n if (Array.isArray(v)) return v.map(walk);\n if (v && typeof v === \"object\") return Object.fromEntries(Object.entries(v).map(([k, x]) => [k, walk(x)]));\n return v;\n };\n return walk(spec) as T;\n}\n\n// ═════════════════════════════════════════════════════════════════════════════\n// custom.record_aggregate, mirrored\n// ═════════════════════════════════════════════════════════════════════════════\n\n/** An exact decimal as a fraction, so nothing is rounded (Postgres numeric is exact). */\ninterface Q {\n n: bigint;\n d: bigint;\n}\nconst gcd = (a: bigint, b: bigint): bigint => (b === 0n ? (a < 0n ? -a : a) : gcd(b, a % b));\nconst q = (n: bigint, d: bigint): Q => {\n if (d < 0n) [n, d] = [-n, -d];\n const g = gcd(n, d) || 1n;\n return { n: n / g, d: d / g };\n};\nconst qAdd = (a: Q, b: Q) => q(a.n * b.d + b.n * a.d, a.d * b.d);\nconst qCmp = (a: Q, b: Q) => (a.n * b.d === b.n * a.d ? 0 : a.n * b.d < b.n * a.d ? -1 : 1);\n\n/** `text::numeric` as Postgres reads it, or null when Postgres would refuse the cast. */\nexport function parseNumeric(text: string): Q | null {\n const m = /^\\s*([+-]?)(\\d*)(?:\\.(\\d*))?(?:[eE]([+-]?\\d+))?\\s*$/.exec(text);\n if (!m || (!m[2] && !m[3])) return null;\n const frac = m[3] ?? \"\";\n let n = BigInt(`${m[1] === \"-\" ? \"-\" : \"\"}${m[2] || \"0\"}${frac}` || \"0\");\n let d = 10n ** BigInt(frac.length);\n const e = Number(m[4] ?? 0);\n if (e > 0) n *= 10n ** BigInt(e);\n if (e < 0) d *= 10n ** BigInt(-e);\n return q(n, d);\n}\n\n/** Exact and terminating → a JS number, else null (the answer could not be written exactly). */\nfunction qToNumber(v: Q): number | null {\n let d = v.d;\n while (d % 2n === 0n) d /= 2n;\n while (d % 5n === 0n) d /= 5n;\n if (d !== 1n) return null;\n let k = 0n;\n while ((10n ** k) % v.d !== 0n) k += 1n;\n const neg = v.n < 0n;\n const scaled = ((neg ? -v.n : v.n) * 10n ** k) / v.d;\n const scale = Number(k);\n const s = scaled.toString().padStart(scale + 1, \"0\");\n return Number(`${neg ? \"-\" : \"\"}${scale ? `${s.slice(0, -scale)}.${s.slice(-scale)}` : s}`);\n}\n\n/** `custom.agg_value_sql`: the Value envelope's `value` when there is one, else the key; as TEXT (`->>`). */\nexport function storeText(v: unknown): string | null {\n if (v === undefined || v === null) return null;\n if (typeof v === \"object\" && !Array.isArray(v) && \"value\" in (v as object)) return storeText((v as { value: unknown }).value);\n if (typeof v === \"string\") return v;\n if (typeof v === \"number\") return numberText(v);\n if (typeof v === \"boolean\") return String(v);\n return JSON.stringify(v);\n}\n\n/** A JSON number as jsonb `->>` prints it: plain digits, never \"1e+21\" or \"1e-7\". */\nexport function numberText(n: number): string {\n const t = String(n);\n if (!/e/i.test(t)) return t;\n const m = /^(-?)(\\d)(?:\\.(\\d+))?e([+-]\\d+)$/i.exec(t);\n if (!m) return t;\n const digits = `${m[2]}${m[3] ?? \"\"}`;\n const exp = Number(m[4]) - (m[3]?.length ?? 0);\n if (exp >= 0) return `${m[1]}${digits}${\"0\".repeat(exp)}`;\n const pos = digits.length + exp;\n return pos > 0 ? `${m[1]}${digits.slice(0, pos)}.${digits.slice(pos)}` : `${m[1]}0.${\"0\".repeat(-pos)}${digits}`;\n}\n\n/** The day part of a stored date or moment (\"2026-10-05\"), or null. */\nfunction dayOfMoment(v: unknown): string | null {\n const t = storeText(v);\n return t && /^\\d{4}-\\d{2}-\\d{2}/.test(t) ? t.slice(0, 10) : null;\n}\n\n/** The value inside a Value envelope ({value: …}), or the value itself. */\nexport function unwrap(v: unknown): unknown {\n return v && typeof v === \"object\" && !Array.isArray(v) && \"value\" in (v as object) ? unwrap((v as { value: unknown }).value) : v;\n}\n\n/** A window bound (custom.dashboard_window_sql: `v_raw::timestamptz`, a bare date read in the session zone, UTC). */\nfunction boundMoment(raw: string): number | null {\n const text = raw.trim();\n if (!text) return null;\n const at = Date.parse(/^\\d{4}-\\d{2}-\\d{2}$/.test(text) ? `${text}T00:00:00Z` : text);\n return Number.isNaN(at) ? null : at;\n}\n\nexport interface SeedRow {\n key: string;\n values: Record<string, unknown>;\n archived?: boolean;\n}\n\n/** custom.record_filter_sql (flat map): scalar = TEXT equality, null = absent/JSON-null (never \"\"), object = half-open window. */\nexport function storeFilterMatches(row: SeedRow, filter: Record<string, AggregateFilter> | undefined, _timeZone: string): boolean {\n if (!filter) return true;\n return Object.entries(filter).every(([key, want]) => {\n const have = storeText(row.values[key]);\n if (want === null) return have === null;\n if (typeof want === \"object\") {\n // custom.dashboard_moment_sql: `nullif(value, '')::timestamptz` — a bare date is read in the\n // SESSION zone (UTC), not the organization's (that reading is agg_moment_sql's, for buckets).\n const at = have === null || have === \"\" ? null : boundMoment(have);\n if (at === null) return false;\n const w = want as { from?: string; to?: string };\n const from = w.from ? boundMoment(w.from) : null;\n const to = w.to ? boundMoment(w.to) : null;\n return (from === null || at >= from) && (to === null || at < to);\n }\n return have === String(want);\n });\n}\n\nexport type AggregateOutcome = { ok: true; value: number | null; exact: boolean } | { ok: false; says: string };\n\n/**\n * custom.record_aggregate for ONE measure over seed rows (live, non-archived), as the store\n * computes it: count(*); sum/avg/min/max/median over `nullif(text,'')::numeric` (a text that\n * is not a number is a refusal; no values at all is NULL, not 0); filled/empty/unique by\n * `nullif(text,'')`. Exact: an average that does not terminate is reported as inexact.\n */\n// ═════════════════════════════════════════════════════════════════════════════\n// Formula fields (custom.field_declare formula_text → custom.formula_parse / formula_eval)\n// ═════════════════════════════════════════════════════════════════════════════\n\n/** custom.formula_node_kinds(), the functions a formula may call (read on the clone 2026-10-03). */\nexport const FORMULA_FUNCTIONS = new Set([\n \"ABS\", \"AND\", \"ARRAYCOMPACT\", \"ARRAYJOIN\", \"AVERAGE\", \"BLANK\", \"CONCATENATE\", \"CONTAINS\", \"DATEADD\", \"DATEDIFF\",\n \"DATETIME_FORMAT\", \"DAY\", \"FIND\", \"IF\", \"ISBLANK\", \"LEFT\", \"LEN\", \"LOWER\", \"MAX\", \"MIN\", \"MONTH\", \"NOT\", \"OR\",\n \"REGEX_MATCH\", \"RIGHT\", \"ROUND\", \"SUBSTITUTE\", \"SUM\", \"SWITCH\", \"TODAY\", \"NOW\", \"TRIM\", \"UPPER\", \"WORKDAY\", \"YEAR\",\n]);\n\ntype FxTok = { t: \"ref\" | \"num\" | \"str\" | \"name\" | \"op\"; v: string };\nfunction fxTokens(text: string): FxTok[] | string {\n const out: FxTok[] = [];\n let i = 0;\n while (i < text.length) {\n const c = text[i]!;\n if (/\\s/.test(c)) i += 1;\n else if (c === \"{\") {\n const j = text.indexOf(\"}\", i);\n if (j < 0) return \"a { has no closing }\";\n out.push({ t: \"ref\", v: text.slice(i + 1, j).trim() });\n i = j + 1;\n } else if (c === \"'\" || c === '\"') {\n const j = text.indexOf(c, i + 1);\n if (j < 0) return \"a quoted word has no closing quote\";\n out.push({ t: \"str\", v: text.slice(i + 1, j) });\n i = j + 1;\n } else if (/[0-9.]/.test(c)) {\n const m = /^[0-9]*\\.?[0-9]+/.exec(text.slice(i))!;\n out.push({ t: \"num\", v: m[0] });\n i += m[0].length;\n } else if (/[A-Za-z_]/.test(c)) {\n const m = /^[A-Za-z_][A-Za-z_0-9]*/.exec(text.slice(i))!;\n out.push({ t: \"name\", v: m[0] });\n i += m[0].length;\n } else if (\"+-*/(),%\".includes(c)) {\n out.push({ t: \"op\", v: c });\n i += 1;\n } else return `\"${c}\" is not part of a formula`;\n }\n return out;\n}\n\ntype FxNode = { k: \"num\"; v: Q } | { k: \"str\"; v: string } | { k: \"ref\"; v: string } | { k: \"bin\"; op: string; a: FxNode; b: FxNode } | { k: \"neg\"; a: FxNode } | { k: \"call\"; f: string; args: FxNode[] };\n/** Parse a formula text, or say what is wrong with it. */\nexport function parseFormula(text: string): FxNode | string {\n const toks = fxTokens(text);\n if (typeof toks === \"string\") return toks;\n let p = 0;\n const peek = () => toks[p];\n const fail = (why: string): never => {\n throw new Error(why);\n };\n const expr = (): FxNode => {\n let a = term();\n while (peek()?.t === \"op\" && (peek()!.v === \"+\" || peek()!.v === \"-\")) {\n const op = toks[p++]!.v;\n a = { k: \"bin\", op, a, b: term() };\n }\n return a;\n };\n const term = (): FxNode => {\n let a = factor();\n while (peek()?.t === \"op\" && (peek()!.v === \"*\" || peek()!.v === \"/\" || peek()!.v === \"%\")) {\n const op = toks[p++]!.v;\n a = { k: \"bin\", op, a, b: factor() };\n }\n return a;\n };\n const factor = (): FxNode => {\n const tk = toks[p++];\n if (!tk) return fail(\"the formula ends too early\");\n if (tk.t === \"num\") return { k: \"num\", v: parseNumeric(tk.v)! };\n if (tk.t === \"str\") return { k: \"str\", v: tk.v };\n if (tk.t === \"ref\") return { k: \"ref\", v: tk.v };\n if (tk.t === \"op\" && tk.v === \"-\") return { k: \"neg\", a: factor() };\n if (tk.t === \"op\" && tk.v === \"(\") {\n const e = expr();\n if (toks[p++]?.v !== \")\") fail(\"a ( has no closing )\");\n return e;\n }\n if (tk.t === \"name\") {\n const f = tk.v.toUpperCase();\n if (!FORMULA_FUNCTIONS.has(f)) fail(`${tk.v} is not a formula function the store knows`);\n if (toks[p++]?.v !== \"(\") fail(`${f} is followed by its arguments in ( )`);\n const args: FxNode[] = [];\n if (peek()?.v !== \")\") {\n args.push(expr());\n while (peek()?.v === \",\") {\n p += 1;\n args.push(expr());\n }\n }\n if (toks[p++]?.v !== \")\") fail(`${f}( has no closing )`);\n return { k: \"call\", f, args };\n }\n return fail(`\"${tk.v}\" is out of place`);\n };\n try {\n const e = expr();\n if (p !== toks.length) return `\"${toks[p]!.v}\" is out of place`;\n return e;\n } catch (err) {\n return (err as Error).message;\n }\n}\n\n/** Every `{Label}` a formula reads. */\nexport function formulaRefs(n: FxNode): string[] {\n if (n.k === \"ref\") return [n.v];\n if (n.k === \"bin\") return [...formulaRefs(n.a), ...formulaRefs(n.b)];\n if (n.k === \"neg\") return formulaRefs(n.a);\n if (n.k === \"call\") return n.args.flatMap(formulaRefs);\n return [];\n}\n\n/**\n * custom.formula_eval for the part the gate mirrors exactly: + − × ÷ % (an empty value counts as\n * 0), ABS, and DATEDIFF (whole units, truncated toward zero). Anything else answers \"unsupported\",\n * and a question over it is refused rather than guessed.\n */\nexport function evalFormula(n: FxNode, valueOf: (label: string) => unknown): { ok: true; v: Q | null } | { ok: false; why: string } {\n const num = (x: FxNode): Q | { why: string } => {\n const r = evalFormula(x, valueOf);\n if (!r.ok) return { why: r.why };\n return r.v ?? q(0n, 1n);\n };\n switch (n.k) {\n case \"num\":\n return { ok: true, v: n.v };\n case \"str\":\n return { ok: false, why: \"it computes text\" };\n case \"ref\": {\n const t = storeText(valueOf(n.v));\n if (t === null || t === \"\") return { ok: true, v: null };\n const v = parseNumeric(t);\n return v ? { ok: true, v } : { ok: false, why: `{${n.v}} is not a number` };\n }\n case \"neg\": {\n const a = num(n.a);\n return \"why\" in a ? { ok: false, why: a.why } : { ok: true, v: q(-a.n, a.d) };\n }\n case \"bin\": {\n const a = num(n.a);\n const b = num(n.b);\n if (\"why\" in a) return { ok: false, why: a.why };\n if (\"why\" in b) return { ok: false, why: b.why };\n if (n.op === \"+\") return { ok: true, v: qAdd(a, b) };\n if (n.op === \"-\") return { ok: true, v: qAdd(a, q(-b.n, b.d)) };\n if (n.op === \"*\") return { ok: true, v: q(a.n * b.n, a.d * b.d) };\n if (b.n === 0n) return { ok: false, why: \"it divides by zero on a row\" };\n if (n.op === \"/\") return { ok: true, v: q(a.n * b.d, a.d * b.n) };\n return { ok: false, why: \"% is not mirrored\" };\n }\n case \"call\": {\n if (n.f === \"ABS\" && n.args.length === 1) {\n const a = num(n.args[0]!);\n return \"why\" in a ? { ok: false, why: a.why } : { ok: true, v: q(a.n < 0n ? -a.n : a.n, a.d) };\n }\n if (n.f === \"DATEDIFF\" && n.args.length === 3 && n.args[2]!.k === \"str\") {\n const ms = (x: FxNode) => (x.k === \"ref\" ? Date.parse(storeText(valueOf(x.v)) ?? \"\") : NaN);\n const a = ms(n.args[0]!);\n const b = ms(n.args[1]!);\n if (!Number.isFinite(a) || !Number.isFinite(b)) return { ok: false, why: \"DATEDIFF reads an empty or unreadable date on a row\" };\n const unit = { days: 86_400_000, hours: 3_600_000, minutes: 60_000 }[n.args[2]!.v];\n if (!unit) return { ok: false, why: \"DATEDIFF's unit is days, hours or minutes\" };\n return { ok: true, v: q(BigInt(Math.trunc((b - a) / unit)), 1n) };\n }\n return { ok: false, why: `${n.f} is not mirrored by the gate` };\n }\n }\n}\n\n/** A view's rows: its flat `filters` (equality, null, window) AND each `anyOf` (`where`: or of eq). */\nexport function viewMatches(row: SeedRow, view: { filters?: Record<string, AggregateFilter> | undefined; anyOf?: Record<string, string[]> | undefined }, timeZone: string): boolean {\n if (!storeFilterMatches(row, view.filters, timeZone)) return false;\n return Object.entries(view.anyOf ?? {}).every(([k, vals]) => {\n const t = storeText(row.values?.[k]);\n return t !== null && vals.includes(t);\n });\n}\n\nexport function storeAggregate(rows: SeedRow[], measure: AggregateMeasure, filter: Record<string, AggregateFilter> | undefined, timeZone: string): AggregateOutcome {\n const live = rows.filter((r) => !r.archived && storeFilterMatches(r, filter, timeZone));\n const op = measure.op;\n if (op === \"count\") return { ok: true, value: live.length, exact: true };\n if (!measure.key) return { ok: false, says: `A ${op} names the column it reads.` };\n const texts = live.map((r) => storeText(r.values[measure.key as string]));\n const present = texts.filter((t): t is string => t !== null && t !== \"\");\n if (op === \"filled\") return { ok: true, value: present.length, exact: true };\n if (op === \"empty\") return { ok: true, value: live.length - present.length, exact: true };\n if (op === \"unique\") return { ok: true, value: new Set(present).size, exact: true };\n const nums: Q[] = [];\n for (const t of present) {\n const v = parseNumeric(t);\n if (!v) return { ok: false, says: `\"${t}\" is not a number, so the store would refuse to ${op} \"${measure.key}\".` };\n nums.push(v);\n }\n if (!nums.length) return { ok: true, value: null, exact: true };\n let result: Q;\n if (op === \"sum\" || op === \"avg\") {\n result = nums.reduce(qAdd, q(0n, 1n));\n if (op === \"avg\") result = q(result.n, result.d * BigInt(nums.length));\n } else if (op === \"min\" || op === \"max\") {\n result = nums.reduce((a, b) => ((op === \"min\" ? qCmp(b, a) < 0 : qCmp(b, a) > 0) ? b : a));\n } else if (op === \"median\") {\n const s = [...nums].sort(qCmp);\n const mid = Math.floor(s.length / 2);\n result = s.length % 2 ? (s[mid] as Q) : q(qAdd(s[mid - 1] as Q, s[mid] as Q).n, qAdd(s[mid - 1] as Q, s[mid] as Q).d * 2n);\n } else return { ok: false, says: `\"${op}\" is not a measure the store computes.` };\n const value = qToNumber(result);\n return value === null ? { ok: true, value: Number(result.n) / Number(result.d), exact: false } : { ok: true, value, exact: true };\n}\n\n/** True when the JSON number `answer` is exactly `value` (no rounding either way). */\nfunction sameNumber(answer: number, value: number): boolean {\n const a = parseNumeric(String(answer));\n const b = parseNumeric(String(value));\n return !!a && !!b && qCmp(a, b) === 0;\n}\n\n// ═════════════════════════════════════════════════════════════════════════════\n// Field kinds\n// ═════════════════════════════════════════════════════════════════════════════\n\nconst BEHAVIOR_OF = new Map<string, string>([\n ...PARITY_FIELD_TYPES.map((t) => [t.parity_type as string, t.behavior as string] as [string, string]),\n ...DECLARABLE_FIELD_KINDS.map((k) => [k.kind as string, k.behavior as string] as [string, string]),\n [\"number\", \"range\"],\n [\"integer\", \"range\"],\n [\"decimal\", \"range\"],\n [\"float\", \"range\"],\n [\"long_text\", \"text\"],\n [\"string\", \"text\"],\n [\"text\", \"text\"],\n]);\nconst behaviorOf = (f: { parityType: string }) => BEHAVIOR_OF.get(f.parityType) ?? f.parityType;\nconst isDate = (f: { parityType: string }) => f.parityType === \"datetime\" || f.parityType === \"date\";\nconst isNumber = (f: { parityType: string }) => behaviorOf(f) === \"range\" && !isDate(f);\nconst isComputed = (f: { parityType: string }) => [\"formula\", \"lookup\", \"rollup\", \"autonumber\", \"created_time\", \"modified_time\"].includes(f.parityType);\nconst isChoice = (f: { parityType: string }) => [\"select\", \"multi_select\", \"list\"].includes(f.parityType);\nconst isRelation = (f: { parityType: string }) => behaviorOf(f) === \"relation\";\nconst SENSITIVITY_RANK = [\"public\", \"internal\", \"confidential\", \"restricted\"];\nconst CONTEXT_RANK = [\"include\", \"summarize\", \"on_request\", \"exclude\"];\n/** Stage names that say when something happened (their dates are never \"any\" without a reason). */\nexport const TIME_BOUND_STAGE = /\\b(?:no[- ]?show|completed?|done|seen|checked[- ]?in|arrived|delivered|shipped|paid|received|scheduled|booked|confirmed|dispatched|on[- ]site|in[- ]visit|overdue|in the chair|served|met|visited|visit|signed|closed|issued|sent|picked up|installed|first contact|contacted|demo(?: held| given| done)?|consult(?:ation)?|tour(?:ed)?|showing|shown|called|interview(?:ed)?|inspected|inspection)\\b/i;\n/** Stage names that end a record's journey. */\nconst TERMINAL_STAGE = /^(?:cancell?ed|no[- ]?show|lost|closed[- ]lost|declined|closed|withdrawn|fell off|rejected|void(?:ed)?|skipped|missed)$/i;\nconst CHART_BLOCK_KINDS = new Set([\"bar\", \"column\", \"line\", \"donut\"]);\nconst BUCKETS = [\"year\", \"quarter\", \"month\", \"week\", \"day\"];\nconst AGG_OPERATIONS = [\"count\", \"sum\", \"avg\", \"min\", \"max\", \"median\", \"filled\", \"empty\", \"unique\"];\nconst MEASURE_KEY = /^[a-zA-Z_][a-zA-Z0-9_]{0,62}$/;\n/** custom._field_document_for: a list link holds at most this many targets unless it declares relation_max. */\nconst STORE_LIST_RELATION_MAX = 25;\n\n/** The first of the field's own rules a value breaks, as a sentence; null when it obeys them all. */\nexport function ruleBreak(field: TemplateField, v: unknown): string | null {\n const t = storeText(v) ?? \"\";\n if (t === \"\") return null;\n if (field.choices?.length && !field.multi && typeof v === \"string\" && !field.choices.includes(v)) return `\"${v}\" is not one of \"${field.label}\"'s choices.`;\n for (const rule of field.rules ?? []) {\n if (rule.kind === \"min\" || rule.kind === \"max\") {\n const n = parseNumeric(t);\n const bound = parseNumeric(String(rule.value));\n if (n && bound && (rule.kind === \"min\" ? qCmp(n, bound) < 0 : qCmp(n, bound) > 0)) return `${t} breaks \"${field.label}\"'s rule: at ${rule.kind === \"min\" ? \"least\" : \"most\"} ${rule.value}.`;\n } else if (rule.kind === \"length\") {\n if (rule.value !== undefined && t.length > Number(rule.value)) return `\"${t}\" is longer than \"${field.label}\" allows (${rule.value}).`;\n if (rule.min !== undefined && t.length < rule.min) return `\"${t}\" is shorter than \"${field.label}\" allows (${rule.min}).`;\n } else if (rule.kind === \"pattern\" && rule.value !== undefined) {\n try {\n if (!new RegExp(String(rule.value)).test(t)) return `\"${t}\" does not match \"${field.label}\"'s own pattern.`;\n } catch {\n return `\"${field.label}\"'s pattern is not a pattern.`;\n }\n }\n }\n return null;\n}\n\n// ═════════════════════════════════════════════════════════════════════════════\n// Shared blocks and the derived UseCase\n// ═════════════════════════════════════════════════════════════════════════════\n\n/** A shared block's table as this template seeds it. */\nexport function blockTable(block: SharedBlockId, rows: TemplateSpec[\"sharedBlocks\"][number][\"rows\"]): TemplateTable {\n const b = SHARED_BLOCKS[block];\n return {\n token: b.table,\n name: b.name,\n labelSingular: b.labelSingular,\n labelPlural: b.labelPlural,\n type: \"entity\",\n display: \"grid\",\n weight: \"light\",\n ordered: false,\n titleField: b.titleField,\n describes: b.describes,\n fields: b.fields.map(({ sameAs: _sameAs, ...f }) => ({ ...f }) as TemplateField),\n rows,\n };\n}\n\n/** The template's own tables plus every shared block it seeds. */\nexport function allTables(spec: Pick<TemplateSpec, \"tables\" | \"sharedBlocks\">): TemplateTable[] {\n return [...(spec.tables ?? []), ...(spec.sharedBlocks ?? []).filter((s) => SHARED_BLOCKS[s.block]).map((s) => blockTable(s.block, s.rows ?? []))];\n}\n\nconst MERGE_TOKEN = /\\{\\{\\s*([^}]*?)\\s*\\}\\}/g;\n\nfunction plainFilter(filter: Record<string, AggregateFilter> | undefined): string | undefined {\n if (!filter) return undefined;\n return Object.entries(filter)\n .map(([k, v]) => (v === null ? `${k} is empty` : typeof v === \"object\" ? `${k} is in the window` : `${k} is ${String(v)}`))\n .join(\" and \");\n}\n\ntype Partial5 = Partial<Pick<UseCase, \"form\" | \"pipeline\" | \"dashboardQuestion\" | \"documentTemplate\" | \"notificationRule\">>;\n\nfunction deriveSingulars(spec: TemplateSpec): Partial5 {\n const out: Partial5 = {};\n const form = spec.forms?.[0];\n if (form) out.form = form;\n const stages = spec.extras?.find((e) => e.kind === \"stage_rules\");\n if (stages?.kind === \"stage_rules\") {\n const field = allTables(spec).find((t) => t.token === stages.table)?.fields.find((f) => f.key === stages.stageField);\n out.pipeline = {\n token: stages.token,\n name: stages.name,\n describes: stages.movesMessage ?? stages.name,\n table: stages.table,\n stageField: stages.stageField,\n stages: (field?.choices ?? Object.keys(stages.stages ?? {})).map((key) => ({ key, label: key, describes: stages.stages?.[key] ?? \"\" })),\n };\n }\n const q6 = spec.agent?.question;\n if (q6?.expect) {\n const op = q6.expect.measure.op;\n out.dashboardQuestion = {\n question: q6.ask,\n whyItMatters: q6.whyItMatters,\n table: q6.expect.table,\n aggregate: ([\"count\", \"sum\", \"avg\", \"min\", \"max\"].includes(op) ? op : \"count\") as \"count\",\n ...(q6.expect.measure.key ? { of: q6.expect.measure.key } : {}),\n ...(plainFilter(q6.expect.filter) ? { filter: plainFilter(q6.expect.filter) as string } : {}),\n answerUnit: q6.expect.unit,\n };\n }\n const doc = spec.extras?.find((e) => e.kind === \"document\");\n if (doc?.kind === \"document\") {\n const fields = allTables(spec).find((t) => t.token === doc.table)?.fields ?? [];\n const keys = [...new Set([...`${doc.title}\\n${doc.body}`.matchAll(MERGE_TOKEN)].map((m) => m[1] ?? \"\"))];\n out.documentTemplate = {\n token: doc.token,\n name: doc.name,\n describes: doc.describes,\n table: doc.table,\n title: doc.title,\n body: doc.body,\n mergeFields: keys.map((key) => ({ key, from: key, describes: fields.find((f) => f.key === key)?.label ?? key })),\n };\n }\n const note = spec.extras?.find((e) => e.kind === \"notification\");\n if (note?.kind === \"notification\") {\n out.notificationRule = { token: note.token, name: note.name, describes: note.describes, when: note.when, audience: note.audience, channel: note.channel, message: note.message };\n }\n return out;\n}\n\n/** A template seen as a use case: the five singulars are there when the template carries them. */\nexport type DerivedUseCase = Omit<UseCase, \"form\" | \"pipeline\" | \"dashboardQuestion\" | \"documentTemplate\" | \"notificationRule\"> & Partial5;\n\n/**\n * The template as a use case, for every existing use-case consumer: the singulars come from\n * forms[0], the first stage_rules, the agent's question, the first document and the first\n * notification WHEN the template has them. A template owes at least two extras (handoff §5),\n * not one of each kind, so a missing singular is simply absent — never an error.\n */\nexport function toUseCase(spec: TemplateSpec): DerivedUseCase {\n const singulars = deriveSingulars(spec);\n return {\n id: spec.id,\n useCase: spec.useCase,\n industry: spec.vertical,\n business: spec.business,\n cleanupTag: spec.cleanupTag,\n tables: allTables(spec) as UseCaseTable[],\n relationships: spec.relationships,\n provenance: spec.provenance,\n ...singulars,\n };\n}\n\n/** validateUseCase over the derived use case, minus the \"a use case owes a …\" lines a template does not owe. */\nexport function useCaseProblemsOf(spec: TemplateSpec): UseCaseProblem[] {\n return validateUseCase(toUseCase(spec) as unknown as UseCase).problems.filter((p) => !SINGULAR_OWES.has(p.at));\n}\n\n// ═════════════════════════════════════════════════════════════════════════════\n// Q2 — who provides each capability word\n// ═════════════════════════════════════════════════════════════════════════════\n\n/**\n * The layouts records-ui draws today — a MIRROR of `VIEW_LAYOUTS` in\n * `apps/shared/records-ui/src/views.ts` (records cannot import records-ui). A test reads\n * that file and fails when the two disagree.\n */\nexport const RECORDS_UI_VIEW_LAYOUTS = [\"grid\", \"kanban\", \"calendar\", \"gallery\", \"timeline\", \"list\"] as const;\n/** Mirror of records-ui `CalendarMode` (CalendarView.tsx). */\nexport const RECORDS_UI_CALENDAR_MODES = [\"month\", \"week\", \"day\", \"list\"] as const;\n/**\n * Field surfaces records-ui draws beyond the plain kinds, each checked against records-ui by\n * the suite: `rating` (a number with format rating — FieldFormatPicker), `signature` (drawn on\n * the form and seen as a drawing — docs.ts / SignBlock).\n */\nexport const RECORDS_UI_FIELD_SURFACES = [\"rating\", \"signature\"] as const;\n\nconst DOOR_FOR: Partial<Record<CapabilityWord, string>> = {\n form: \"form_declare\",\n // form_declare takes {field, ask, help, required} per question (read on the clone).\n \"form.question_text\": \"form_declare\",\n booking: \"booking_declare\",\n portal: \"portal_declare\",\n dashboard: \"dashboard_declare\",\n // dashboard_block_normalize accepts a per-block table_id.\n \"dashboard.multi_table\": \"dashboard_block_normalize\",\n drill_down: \"drill_resolve\",\n dimensions: \"table_dimensions_set\",\n digest: \"subscription_declare\",\n checklist: \"checklist_declare\",\n document: \"doc_template_save\",\n \"document.esign\": \"doc_sign\",\n notification: \"rule_declare\",\n stage_rules: \"pipeline_declare\",\n row_action: \"action_declare\",\n \"import.upsert\": \"io_import_begin\",\n \"archive.restore\": \"record_restore\",\n agent: \"agent_context\",\n \"view.kanban.swimlanes\": \"view_declare\",\n};\n\n/** Words nobody provides yet, and who owes them. */\nconst OWED_BY: Partial<Record<CapabilityWord, string>> = {\n automation: \"lane 11\",\n};\n\nexport interface CapabilityStatus {\n word: string;\n provided: boolean;\n by: string;\n}\n\nconst STORE_DOOR_NAMES = new Set(STORE_DOORS.map((d) => d.name as string));\nconst STORE_FIELD_KINDS = new Set<string>(BEHAVIOR_OF.keys());\n\nexport function capabilityStatus(word: string): CapabilityStatus {\n if (!(CAPABILITY_WORDS as readonly string[]).includes(word)) return { word, provided: false, by: \"nobody — not a capability word\" };\n const w = word as CapabilityWord;\n const owed = OWED_BY[w];\n if (owed) return { word, provided: false, by: owed };\n if (w === \"view.calendar.month\") {\n return (RECORDS_UI_CALENDAR_MODES as readonly string[]).includes(\"month\")\n ? { word, provided: true, by: \"records-ui CalendarView (month)\" }\n : { word, provided: false, by: \"lane 10\" };\n }\n if (w.startsWith(\"view.\") && w !== \"view.kanban.swimlanes\") {\n return (RECORDS_UI_VIEW_LAYOUTS as readonly string[]).includes(w.slice(5))\n ? { word, provided: true, by: \"records-ui VIEW_LAYOUTS\" }\n : { word, provided: false, by: \"lane 10\" };\n }\n if (w.startsWith(\"field.\")) {\n const kind = w.slice(6);\n if ((RECORDS_UI_FIELD_SURFACES as readonly string[]).includes(kind)) return { word, provided: true, by: \"records-ui field surfaces\" };\n return STORE_FIELD_KINDS.has(kind) ? { word, provided: true, by: \"custom.field_kinds()\" } : { word, provided: false, by: \"lane 10\" };\n }\n if (w === \"seed.attachments\") {\n return STORE_DOOR_NAMES.has(\"file_kernel_id\") && STORE_DOOR_NAMES.has(\"record_write\")\n ? { word, provided: true, by: \"plan.ts attachments step (custom.file_kernel_id + custom.record_write)\" }\n : { word, provided: false, by: \"the chair\" };\n }\n if (w === \"choice.colors\") return { word, provided: true, by: \"records-ui choiceLooks (display_format choices)\" };\n const door = DOOR_FOR[w];\n if (door) return STORE_DOOR_NAMES.has(door) ? { word, provided: true, by: `custom.${door}` } : { word, provided: false, by: \"the chair\" };\n return { word, provided: false, by: \"nobody — no provider mapped\" };\n}\n\n/** Every capability the spec USES. `requires` must equal this set — no less, no more. */\nexport function capabilitiesUsed(spec: TemplateSpec): Set<CapabilityWord> {\n const used = new Set<CapabilityWord>();\n for (const view of spec.views ?? []) {\n used.add(`view.${view.kind}` as CapabilityWord);\n if (view.kind === \"kanban\" && view.swimlaneBy) used.add(\"view.kanban.swimlanes\");\n if (view.kind === \"calendar\" && view.span === \"month\") used.add(\"view.calendar.month\");\n if (view.kind === \"gallery\") used.add(\"seed.attachments\");\n }\n if (spec.teaches === \"gallery\") used.add(\"seed.attachments\");\n for (const table of allTables(spec)) {\n for (const field of table.fields ?? []) {\n const word = `field.${field.parityType}`;\n if ((CAPABILITY_WORDS as readonly string[]).includes(word)) used.add(word as CapabilityWord);\n if (field.choiceColors && Object.keys(field.choiceColors).length) used.add(\"choice.colors\");\n if (field.format === \"rating\") used.add(\"field.rating\");\n if (field.format === \"signature\") used.add(\"field.signature\");\n }\n }\n if (spec.forms?.length) {\n used.add(\"form\");\n used.add(\"form.question_text\");\n }\n if (spec.dimensions?.length) used.add(\"dimensions\");\n if (spec.agent) used.add(\"agent\");\n for (const extra of spec.extras ?? []) {\n if (extra.kind === \"dashboard\") {\n used.add(\"dashboard\");\n if (extra.blocks.some((b) => b.table && b.table !== extra.table)) used.add(\"dashboard.multi_table\");\n } else if (extra.kind === \"document\") {\n used.add(\"document\");\n if (extra.signature) used.add(\"document.esign\");\n } else used.add(extra.kind as CapabilityWord);\n }\n for (const step of spec.walk ?? []) {\n if (step?.action?.kind === \"import\") used.add(\"import.upsert\");\n if (step?.action?.kind === \"archive\" || step?.action?.kind === \"restore\") used.add(\"archive.restore\");\n }\n return used;\n}\n\n// ═════════════════════════════════════════════════════════════════════════════\n// G6 — no real people\n// ═════════════════════════════════════════════════════════════════════════════\n\n/** The designated test numbers (aidream/designated_test_recipients.py): real handsets, never seed data. */\nexport const DESIGNATED_REAL_NUMBERS = [\"9498072145\", \"9496662578\", \"9497027626\"] as const;\n\nconst DIGIT_ZEROS = [0x0660, 0x06f0, 0x07c0, 0x0966, 0x09e6, 0x0a66, 0x0ae6, 0x0b66, 0x0be6, 0x0c66, 0x0ce6, 0x0d66, 0x0e50, 0x0ed0, 0x0f20, 0x1040, 0x17e0, 0x1810, 0xff10];\n\n/** Unicode digits → ASCII, every dash/hyphen → \"-\", every odd space → \" \" (so a disguised number reads as one). */\nexport function normalizeForPhones(text: string): string {\n return text\n .normalize(\"NFKC\")\n .replace(/\\p{Nd}/gu, (c) => {\n const cp = c.codePointAt(0) ?? 48;\n const zero = DIGIT_ZEROS.find((z) => cp >= z && cp <= z + 9);\n return zero === undefined ? c : String(cp - zero);\n })\n .replace(/[\\u2010-\\u2015\\u2212\\ufe58\\ufe63\\uff0d]/g, \"-\")\n .replace(/[\\u00a0\\u2000-\\u200b\\u202f\\u205f\\u3000]/g, \" \");\n}\n\n/** NANP with separators (or parentheses) — what a phone looks like inside prose. */\nconst NANP_IN_TEXT = /(?:\\+?1[\\s.-]?)?(?:\\((\\d{3})\\)[\\s.-]?|\\b(\\d{3})[\\s.-])(\\d{3})[\\s.-](\\d{4})\\b/g;\n/** NANP in a phone FIELD, where bare digits are a phone too. */\nconst NANP_IN_FIELD = /(?:\\+?1[\\s.-]?)?\\(?\\b(\\d{3})\\)?[\\s.-]?(\\d{3})[\\s.-]?(\\d{4})\\b/g;\n/** Any international number written with a country code other than +1. */\nconst INTL = /\\+(?!1\\b)(\\d{1,3})[\\s.-]?\\(?\\d[\\d\\s().-]{5,}\\d/g;\n/** Ofcom's drama ranges (UK numbers reserved for fiction), without spaces, after +44 or 0. */\nconst OFCOM_DRAMA = /^(?:207946(0\\d{3})|1214960\\d{3}|1314960\\d{3}|1134960\\d{3}|1614960\\d{3}|1174960\\d{3}|2890180\\d{3}|29\\d{2}0180\\d{3}|7700900\\d{3})$/;\n\nfunction nanpBad(area: string, exchange: string, line: string): boolean {\n const n = Number(line);\n return exchange !== \"555\" || n < 100 || n > 199 || (DESIGNATED_REAL_NUMBERS as readonly string[]).includes(`${area}${exchange}${line}`);\n}\n\n/**\n * Every number in `text` that is not fictional: a NANP number outside 555-0100…0199 (or a\n * designated real handset), or an international number outside the UK's Ofcom drama ranges.\n * `phoneField` = the text IS a phone value, so bare digits count; in prose a number needs\n * separators, so an NPI or an order number is never read as a phone.\n */\nexport function phonesOutsideFictionalRange(text: string, phoneField = false): string[] {\n const t = normalizeForPhones(text);\n const out: string[] = [];\n for (const m of t.matchAll(INTL)) {\n const digits = m[0].replace(/\\D/g, \"\");\n const cc = m[1] ?? \"\";\n const national = digits.slice(cc.length).replace(/^0/, \"\");\n if (!(cc === \"44\" && OFCOM_DRAMA.test(national))) out.push(m[0].trim());\n }\n const rest = t.replace(INTL, \" \");\n if (phoneField && /^\\s*0\\d[\\d\\s-]{8,}\\d\\s*$/.test(rest)) {\n const national = rest.replace(/\\D/g, \"\").replace(/^0/, \"\");\n if (!OFCOM_DRAMA.test(national)) out.push(rest.trim());\n return out;\n }\n for (const m of rest.matchAll(phoneField ? NANP_IN_FIELD : NANP_IN_TEXT)) {\n const [area, ex, line] = phoneField ? [m[1], m[2], m[3]] : [m[1] ?? m[2], m[3], m[4]];\n if (nanpBad(area ?? \"\", ex ?? \"\", line ?? \"\")) out.push(m[0].trim());\n }\n return out;\n}\n\n/** Public mail providers: real domains millions of real people use — never \"fictional\". */\nexport const PUBLIC_MAIL_DOMAINS = [\n \"gmail.com\", \"googlemail.com\", \"outlook.com\", \"hotmail.com\", \"live.com\", \"msn.com\", \"yahoo.com\", \"ymail.com\", \"icloud.com\", \"me.com\", \"mac.com\",\n \"aol.com\", \"proton.me\", \"protonmail.com\", \"pm.me\", \"zoho.com\", \"gmx.com\", \"gmx.net\", \"mail.com\", \"yandex.com\", \"fastmail.com\", \"hey.com\", \"tutanota.com\",\n \"comcast.net\", \"verizon.net\", \"att.net\", \"sbcglobal.net\", \"bellsouth.net\", \"cox.net\", \"qq.com\", \"163.com\", \"web.de\",\n] as const;\n\n/** Every domain an email, a website or a url in the text uses. */\nexport function domainsIn(text: string): string[] {\n const found = new Set<string>();\n for (const m of text.matchAll(/[a-z0-9._%+-]+@([a-z0-9-]+(?:\\.[a-z0-9-]+)+)/gi)) found.add((m[1] ?? \"\").toLowerCase());\n for (const m of text.matchAll(/\\bhttps?:\\/\\/([a-z0-9-]+(?:\\.[a-z0-9-]+)+)/gi)) found.add((m[1] ?? \"\").toLowerCase().replace(/^www\\./, \"\"));\n for (const m of text.matchAll(/\\bwww\\.([a-z0-9-]+(?:\\.[a-z0-9-]+)+)/gi)) found.add((m[1] ?? \"\").toLowerCase().replace(/\\.$/, \"\"));\n return [...found];\n}\n\n/** \"4127 Calloway Palm Way, Suite 6\" → \"Calloway Palm Way\"; no house number → null. */\nexport function numberedStreet(line: string): string | null {\n const m = /^\\s*\\d+[A-Za-z]?\\s+(.+?)\\s*(?:,.*|\\s+(?:suite|ste\\.?|unit|apt\\.?|#)\\s*.*)?$/i.exec(line);\n return m ? (m[1] ?? null) : null;\n}\n\n// ═════════════════════════════════════════════════════════════════════════════\n// The verdict\n// ═════════════════════════════════════════════════════════════════════════════\n\nexport type TemplateStatus = \"pass\" | \"fail\" | `waiting on ${string}`;\n\nexport interface TemplateVerdict {\n ok: boolean;\n status: TemplateStatus;\n problems: UseCaseProblem[];\n waiting: CapabilityStatus[];\n}\n\nexport interface ValidateOptions {\n /** templates/AGENTS.snapshot.json — the platform agents a template may copy. */\n agents?: AgentSnapshotRow[];\n /**\n * The rest of the library (every other template file), so a template copied from another can\n * be told it still carries that business's names, people or sentences.\n * G1 always passes it; a single-file check without it skips only this cross-file rule.\n */\n library?: { specs: TemplateSpec[]; signatures?: unknown };\n /**\n * \"gallery\" (default): a published platform template — the full bar.\n * \"describe\": a private one-off spec made from one sentence (the /make describe box). Its tables,\n * fields, links, forms, views and booking pages are held to the same rules; what only a gallery\n * card needs is not asked for — catalogue keys, strengths, provenance, the teaching walk, the agent,\n * seed rows and how the seed looks on screen — and `requires` is worked out, never written.\n */\n profile?: \"gallery\" | \"describe\";\n}\n\n/** Problem roots only a published gallery template owes (the describe profile does not ask for them). */\nconst GALLERY_ONLY_ROOTS = [\"catalogueId\", \"strengths\", \"teaches\", \"agent\", \"walk\", \"provenance\", \"requires\", \"persona\"];\n\n/** Every piece of text a person reads in the template, with where it sits. Keys and tokens are not text. */\nexport function templateText(spec: TemplateSpec): Array<[string, string]> {\n const out: Array<[string, string]> = [];\n const add = (at: string, v: unknown) => {\n if (typeof v === \"string\" && v.trim()) out.push([at, v]);\n };\n const b = spec.business;\n add(\"business.name\", b?.name);\n add(\"business.legalName\", b?.legalName);\n add(\"business.describes\", b?.describes);\n add(\"business.website\", b?.website);\n add(\"business.email\", b?.email);\n add(\"useCase\", spec.useCase);\n for (const t of allTables(spec)) {\n add(`tables (${t.token}).name`, t.name);\n add(`tables (${t.token}).labelPlural`, t.labelPlural);\n add(`tables (${t.token}).labelSingular`, t.labelSingular);\n add(`tables (${t.token}).describes`, t.describes);\n const byKey = new Map(t.fields.map((f) => [f.key, f]));\n for (const f of t.fields) {\n add(`tables (${t.token}).fields (${f.key}).label`, f.label);\n add(`tables (${t.token}).fields (${f.key}).help`, f.help);\n for (const c of f.choices ?? []) add(`tables (${t.token}).fields (${f.key}).choices`, c);\n }\n for (const r of t.rows) {\n for (const [k, v] of Object.entries(r.values ?? {})) {\n const f = byKey.get(k);\n if (f && !isRelation(f)) add(`tables (${t.token}).rows (${r.key}).${k}`, unwrap(v));\n }\n }\n }\n for (const v of spec.views ?? []) add(`views (${v.token}).name`, v.name);\n for (const f of spec.forms ?? []) {\n add(`forms (${f.token}).name`, f.name);\n add(`forms (${f.token}).describes`, f.describes);\n add(`forms (${f.token}).confirmation`, f.confirmation);\n add(`forms (${f.token}).submitLabel`, f.submitLabel);\n for (const q of f.fields ?? []) {\n add(`forms (${f.token}).fields (${q.fieldKey}).ask`, q.ask);\n add(`forms (${f.token}).fields (${q.fieldKey}).help`, q.help);\n }\n }\n const walkStrings = (at: string, v: unknown): void => {\n if (typeof v === \"string\") add(at, v);\n else if (Array.isArray(v)) v.forEach((x, i) => walkStrings(`${at}[${i}]`, x));\n else if (v && typeof v === \"object\") for (const [k, x] of Object.entries(v)) if (![\"token\", \"table\", \"kind\", \"field\", \"view\", \"path\", \"stageField\", \"dateField\", \"fieldKey\", \"key\", \"row\", \"form\", \"surface\", \"dedupeKey\", \"columns\", \"of\", \"groupBy\", \"stateKey\", \"clientTable\", \"namesVia\", \"visibleFields\", \"editableFields\", \"aboutTable\", \"ref\", \"role\", \"dependsOn\", \"requires\", \"by\"].includes(k)) walkStrings(`${at}.${k}`, x);\n };\n (spec.extras ?? []).forEach((e) => walkStrings(`extras (${e.token})`, e));\n (spec.walk ?? []).forEach((w, i) => {\n add(`walk[${i}].says`, w?.says);\n const a = w?.action as { kind?: string; rows?: string[][]; sourceName?: string } | undefined;\n if (a?.kind === \"import\") {\n add(`walk[${i}].action.sourceName`, a.sourceName);\n a.rows?.forEach((row, ri) => row.forEach((c) => add(`walk[${i}].action.rows[${ri}]`, c)));\n }\n });\n add(\"agent.name\", spec.agent?.name);\n add(\"agent.question.ask\", spec.agent?.question?.ask);\n add(\"agent.question.whyItMatters\", spec.agent?.question?.whyItMatters);\n for (const v of spec.agent?.variables ?? []) add(`agent.variables (${v.name}).describes`, v.describes);\n for (const f of spec.foundation ?? []) add(`foundation (${f.table}).keptFor`, f.keptFor);\n return out;\n}\n\n/** People named in a template: its team and its person-name columns. */\nexport function peopleOf(spec: TemplateSpec): string[] {\n const out = new Set<string>();\n for (const t of allTables(spec)) {\n const nameFields = t.fields.filter((f) => /(^|_)(full_)?name$|^(owner|patient|client|contact|person|member|customer)_?name$/.test(f.key));\n for (const f of nameFields) for (const r of t.rows) {\n const v = storeText(r.values?.[f.key]);\n if (v && /^[A-Z][a-z]+(?:[ -][A-Z][a-z'’-]+)+$/.test(v.trim())) out.add(v.trim());\n }\n }\n return [...out];\n}\n\n/** Prose a person reads (not row values): where copied sentences hide. */\nfunction proseOf(spec: TemplateSpec): Array<[string, string]> {\n return templateText(spec).filter(([at]) => !at.startsWith(\"tables (\"));\n}\n\nconst words8 = (text: string) => text.toLowerCase().replace(/\\{\\{[^}]*\\}\\}/g, \" \").split(/[^a-z0-9']+/).filter(Boolean);\n\n/**\n * FOREIGN TEXT: what belongs to ANOTHER template file — its business and legal name, its\n * domains, its people — and any run of eight or more words copied verbatim from its prose (a\n * persona, a document, a message, a question, a walk step). A template made by copying another\n * and renaming the obvious parts still carries a sentence of it; this finds it. A shared trade\n * word (\"patient\", \"pool\") is never foreign: two businesses in one trade speak alike.\n */\n/**\n * What another template contributes to the foreign-text rule, worked out ONCE per spec object: the library\n * check runs every file against every other, so rebuilding these per pair grew with the square of the library\n * (G1 passed 240 s at ~280 files on a loaded machine).\n */\nconst FOREIGN_INDEX = new WeakMap<TemplateSpec, { name: string; tokens: Array<[string, string]>; grams: Set<string> }>();\nfunction foreignIndexOf(other: TemplateSpec) {\n let ix = FOREIGN_INDEX.get(other);\n if (ix) return ix;\n const tokens: Array<[string, string]> = [];\n for (const v of [other.business?.name, other.business?.legalName]) if (v) tokens.push([v, \"its business name\"]);\n for (const d of other.provenance?.fictionalDomains ?? []) tokens.push([d, \"one of its domains\"]);\n for (const p of peopleOf(other)) tokens.push([p, \"one of its people\"]);\n const grams = new Set<string>();\n for (const [, v] of proseOf(other)) {\n const w = words8(v);\n for (let i = 0; i + 8 <= w.length; i += 1) grams.add(w.slice(i, i + 8).join(\" \"));\n }\n ix = { name: other.business?.name ?? other.id, tokens, grams };\n FOREIGN_INDEX.set(other, ix);\n return ix;\n}\n\nexport function foreignTextProblems(spec: TemplateSpec, library: { specs: TemplateSpec[]; signatures?: unknown }): UseCaseProblem[] {\n const problems: UseCaseProblem[] = [];\n const text = templateText(spec);\n const hay = text.map(([at, v]) => [at, v.toLowerCase()] as const);\n const all = hay.map(([, v]) => v).join(\"\\n\");\n const esc = (w: string) => w.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const find = (word: string) => {\n const lower = word.toLowerCase();\n if (!all.includes(lower)) return undefined; // cheap: most names are nowhere in this file\n const re = new RegExp(`(^|[^a-z0-9])${esc(lower)}($|[^a-z0-9])`);\n return hay.find(([, v]) => re.test(v));\n };\n const mine = proseOf(spec).map(([at, w]) => {\n const words = words8(w);\n const runs: string[] = [];\n for (let i = 0; i + 8 <= words.length; i += 1) runs.push(words.slice(i, i + 8).join(\" \"));\n return [at, runs] as const;\n });\n for (const other of library.specs) {\n if (!other || other.id === spec.id) continue;\n const { name, tokens, grams } = foreignIndexOf(other);\n for (const [word, what] of tokens) {\n const hit = find(word);\n if (hit) problems.push({ at: hit[0], says: `This still says \"${word}\", ${what} from the ${name} template. Write your own business's words.` });\n }\n for (const [at, runs] of mine) {\n const run = runs.find((r) => grams.has(r));\n if (run) problems.push({ at, says: `This copies \"${run}…\" word for word from the ${name} template. Write it in your own business's words.` });\n }\n }\n return problems;\n}\n\nexport const MAIN_TABLE_ROWS_MIN = 20;\nexport const MAIN_TABLE_ROWS_MAX = 50;\nexport const TABLES_MIN = 2;\nexport const TABLES_MAX = 8;\n/** At least this share of a table's rows carry a title nobody else has. */\nexport const TITLE_DISTINCT_SHARE = 0.9;\nconst SINGULAR_OWES = new Set([\"form\", \"pipeline\", \"dashboardQuestion\", \"documentTemplate\", \"notificationRule\"]);\nconst norm = (s: string) => s.toLowerCase().replace(/[^a-z0-9]+/g, \" \").trim();\n/** A field's label means one of `sameAs` when it is one, or carries one's distinctive word (\"Cell phone\" → cell). */\nconst SYNONYM_WORDS: Record<string, string[]> = {\n name: [\"name\"],\n role: [\"role\", \"title\", \"position\"],\n email: [\"email\", \"e-mail\", \"mail\"],\n phone: [\"phone\", \"mobile\", \"cell\"],\n // \"Service start\" or \"Start of season\" is not a hire date: only words that mean joining the team.\n start: [\"hired\", \"hire\", \"joined\"],\n};\nfunction labelMeans(f: { label: string }, sameAs: readonly string[]): boolean {\n const label = norm(f.label);\n if (sameAs.includes(label)) return true;\n const words = new Set(label.split(\" \"));\n return Object.values(SYNONYM_WORDS).some((group) => group.some((w) => words.has(w)) && sameAs.some((s) => group.some((w) => s.split(\" \").includes(w))));\n}\nconst sameJson = (a: unknown, b: unknown) => JSON.stringify(a) === JSON.stringify(b);\nconst sortedJson = (v: Record<string, unknown>) => JSON.stringify(Object.keys(v).sort().map((k) => [k, v[k]]));\nconst filled = (v: unknown) => storeText(v) !== null && storeText(v) !== \"\" && !(Array.isArray(v) && v.length === 0);\n\n/** Name columns that name a thing, never a person (the person-placeholder rule does not apply). */\nconst THING_NAME = /^(section|class|course|period|room|bay|item|job|role|team|pool|machine|program|plan|service|procedure|product|group|neighborhood|listing|grant|deal|bid|engagement|matter|account|company|route|site|location|project|event|campaign|unit|vehicle|truck|table|field|view|form)_name$/;\n\n/** Check one template. Every problem, not the first. */\nconst FILE_VALUE_RE = /^@file:([A-Za-z0-9_.-]+)$/;\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/** One platform picture as templates/ASSETS.json lists it (written by `pnpm templates:assets`). */\nexport interface TemplateAssetRow {\n key: string;\n fileId: string;\n name: string;\n mime: string;\n bytes: number;\n publishedToWeb: boolean;\n}\n\n/**\n * seed.attachments, as written: every `attachments` entry is whole, every attachment-field value is\n * \"@file:<key>\" naming one of them, and every listed picture is used. With `assets` (ASSETS.json),\n * each attachment must BE a library picture (same key and file id) that is published to the web —\n * a picture only its uploader can read would show members an empty card.\n */\nexport function attachmentProblems(\n raw: TemplateSpec & { attachments?: Array<Partial<TemplateAssetRow>> },\n assets?: TemplateAssetRow[],\n): UseCaseProblem[] {\n const out: UseCaseProblem[] = [];\n const say = (at: string, says: string) => out.push({ at, says });\n const listed = raw.attachments ?? [];\n if (raw.attachments !== undefined && !Array.isArray(raw.attachments)) {\n say(\"attachments\", \"attachments is a list of pictures from templates/ASSETS.json.\");\n return out;\n }\n const keys = new Set<string>();\n const library = assets ? new Map(assets.map((a) => [a.key, a])) : null;\n listed.forEach((a, i) => {\n const at = `attachments[${i}]`;\n if (!a.key || !/^[A-Za-z0-9_.-]+$/.test(a.key)) return say(`${at}.key`, \"Each picture has a key (letters, digits, _ . -).\");\n if (keys.has(a.key)) say(`${at}.key`, `\"${a.key}\" is listed twice.`);\n keys.add(a.key);\n if (!a.fileId || !UUID_RE.test(a.fileId)) say(`${at}.fileId`, `\"${a.key}\" needs the file id from templates/ASSETS.json.`);\n if (!a.name || !a.mime || typeof a.bytes !== \"number\") say(at, `\"${a.key}\" copies name, mime and bytes from templates/ASSETS.json.`);\n if (library) {\n const asset = library.get(a.key);\n if (!asset) say(`${at}.key`, `\"${a.key}\" is not a picture in templates/ASSETS.json.`);\n else if (asset.fileId !== a.fileId) say(`${at}.fileId`, `\"${a.key}\" names file ${a.fileId}, but templates/ASSETS.json has ${asset.fileId}.`);\n else if (asset.publishedToWeb !== true) say(`${at}.fileId`, `\"${a.key}\" is not published to the web, so members could not see it.`);\n }\n });\n const used = new Set<string>();\n for (const table of allTables(raw)) {\n const fileFields = new Set(table.fields.filter((f) => f.parityType === \"attachment\").map((f) => f.key));\n table.rows?.forEach((row, ri) => {\n for (const [key, rawValue] of Object.entries(row.values ?? {})) {\n const value = unwrap(rawValue);\n const items = Array.isArray(value) ? value : [value];\n for (const item of items) {\n if (typeof item !== \"string\") continue;\n const m = FILE_VALUE_RE.exec(item);\n const at = `tables (${table.token}).rows[${ri}].values.${key}`;\n if (!m) {\n if (fileFields.has(key) && item) say(at, `A file field holds \"@file:<key>\" from the template's attachments, not \"${item}\".`);\n continue;\n }\n if (!fileFields.has(key)) say(at, `\"${item}\" names a picture, but \"${key}\" is not a file field.`);\n else if (!keys.has(m[1]!)) say(at, `\"${item}\" names a picture the template's attachments do not list.`);\n used.add(m[1]!);\n }\n }\n });\n }\n for (const k of keys) if (!used.has(k)) say(\"attachments\", `\"${k}\" is listed but no row shows it.`);\n for (const view of raw.views ?? []) {\n if (view.kind !== \"gallery\") continue;\n const table = allTables(raw).find((t) => t.token === view.table);\n const seeded = (table?.rows ?? []).filter((r) => {\n const v = unwrap(r.values?.[view.coverField]);\n return (Array.isArray(v) ? v : [v]).some((x) => typeof x === \"string\" && FILE_VALUE_RE.test(x));\n }).length;\n if (table && seeded === 0) say(`views (${view.token})`, `The gallery \"${view.name}\" shows pictures, but no row has one in \"${view.coverField}\".`);\n }\n return out;\n}\n\nexport function validateTemplate(raw: TemplateSpec, options: ValidateOptions = {}): TemplateVerdict {\n const problems: UseCaseProblem[] = [];\n const say = (at: string, says: string) => problems.push({ at, says });\n // A rule about how the SEED looks on screen (charts with one bar, empty boards); a spec with no seed rows\n // under the describe profile does not owe it.\n const seedLooks = new WeakSet<UseCaseProblem>();\n const saySeed = (at: string, says: string) => {\n const p = { at, says };\n seedLooks.add(p);\n problems.push(p);\n };\n // A bar only a published gallery card owes (enough views, extras and cross-table reads to TEACH the store);\n // a one-off describe spec owes the person's own setup — \"one useful view\" (MANDATE-BRIEF-SENTENCE-TO-TEMPLATE).\n const galleryBar = new WeakSet<UseCaseProblem>();\n const sayGallery = (at: string, says: string) => {\n const p = { at, says };\n galleryBar.add(p);\n problems.push(p);\n };\n const tz = raw.business?.timezone || \"UTC\";\n const tablesRaw = allTables(raw);\n\n // ── relative dates (on the file as written; Value envelopes unwrapped) ─────\n const ISO_DAY = /\\b\\d{4}-\\d{2}-\\d{2}\\b/;\n // ── a checklist step is due a whole number of days from the checklist's start, 0 to ten years (the store refuses\n // a negative offset: T0615's pre-pour steps were \"due -3 days in\") ──\n for (const e of raw.extras ?? []) {\n if (e.kind !== \"checklist\") continue;\n for (const st of (e as { steps?: Array<{ ref?: string; dueDays?: number }> }).steps ?? []) {\n if (st.dueDays !== undefined && !(Number.isInteger(st.dueDays) && st.dueDays >= 0 && st.dueDays <= 3650)) {\n say(`extras (${(e as { token: string }).token}).steps (${st.ref ?? \"?\"}).dueDays`, `A step is due a whole number of days after the checklist starts, from 0 to 3650; ${st.dueDays} is not. Start the checklist earlier instead of counting backwards.`);\n }\n }\n }\n // ── a pattern rule's example passes its own pattern (the store refuses the field otherwise, FLD-3) ──\n for (const table of tablesRaw) {\n for (const f of table.fields) {\n for (const rule of (f.rules ?? []) as Array<{ kind?: string; value?: unknown; example?: unknown }>) {\n if (rule.kind !== \"pattern\" || typeof rule.value !== \"string\" || typeof rule.example !== \"string\") continue;\n let re: RegExp | null = null;\n try { re = new RegExp(rule.value); } catch { continue; }\n if (!re.test(rule.example)) say(`tables (${table.token}).fields (${f.key}).rules`, `\"${f.label}\" shows \"${rule.example}\" as the way to write it, and its own pattern refuses that. Make the example match the pattern.`);\n }\n }\n }\n // ── an email column holds an address the store's email rule accepts (one word, one @, a dotted domain) ──\n const EMAIL_SHAPE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n for (const table of tablesRaw) {\n for (const f of table.fields.filter((x) => x.parityType === \"email\" || x.format === \"email\")) {\n table.rows?.forEach((row) => {\n const v = unwrap(row.values?.[f.key]);\n if (typeof v === \"string\" && v !== \"\" && !EMAIL_SHAPE.test(v)) say(`tables (${table.token}).rows (${row.key}).${f.key}`, `\"${v}\" is not an email address the store will take (no spaces, one @, a dotted domain).`);\n });\n }\n }\n // ── a table's title column is made with the table (custom.table_from_example needs it there), and a column\n // with a default is declared later on its own (field_declare carries the default) — so a title takes none.\n for (const table of tablesRaw) {\n const tf = table.fields.find((f) => f.key === table.titleField);\n if (tf && tf.default !== undefined) say(`tables (${table.token}).fields (${tf.key})`, `\"${tf.label}\" names each ${table.labelSingular.toLowerCase()}, so it takes no default; ask it on the form instead.`);\n }\n // ── a link holds no more targets than the store lets it (custom._field_document_for: relation_max\n // defaults to 25 for a list, 1 for a single link; record_write refuses more — REC-51) ──\n for (const table of tablesRaw) {\n for (const f of table.fields.filter((x) => isRelation(x) && x.parityType !== \"attachment\")) {\n const max = f.relationMax ?? (f.multi ? STORE_LIST_RELATION_MAX : 1);\n table.rows?.forEach((row) => {\n const v = unwrap(row.values?.[f.key]);\n const n = Array.isArray(v) ? v.length : v === null || v === undefined || v === \"\" ? 0 : 1;\n if (n > max) say(`tables (${table.token}).rows (${row.key}).${f.key}`, `\"${f.label}\" links ${n} records, more than the ${max} it may hold. Set relationMax on the field (up to the real most), or link fewer.`);\n });\n }\n }\n for (const table of tablesRaw) {\n // Lane 10 FD: a table's own `foundation` is only an echo of the template's foundation list (the\n // one source the installers read): true or false, and saying what the list says.\n if (table.foundation !== undefined) {\n const listed = (raw.foundation ?? []).some((f) => f.table === table.token);\n if (typeof table.foundation !== \"boolean\") say(`tables (${table.token}).foundation`, \"foundation is true or false.\");\n else if (table.foundation !== listed) {\n say(\n `tables (${table.token}).foundation`,\n listed\n ? `\"${table.token}\" is in the foundation list; take foundation: false off the table.`\n : `\"${table.token}\" says foundation: true but is not in the foundation list; list it there.`,\n );\n }\n }\n const byKey = new Map(table.fields.map((f) => [f.key, f]));\n for (const f of table.fields) {\n if (f.absoluteDates && !isDate(f)) say(`tables (${table.token}).fields (${f.key})`, `absoluteDates belongs on a date field; \"${f.label}\" is ${f.parityType}.`);\n if (f.absoluteDates && !f.historicalReason?.trim()) say(`tables (${table.token}).fields (${f.key}).historicalReason`, `\"${f.label}\" holds absolute dates; say why they are history (\"date of birth\").`);\n }\n table.rows?.forEach((row, ri) => {\n for (const [key, rawValue] of Object.entries(row.values ?? {})) {\n const f = byKey.get(key);\n const value = unwrap(rawValue);\n if (!f || typeof value !== \"string\") continue;\n const at = `tables (${table.token}).rows[${ri}].values.${key}`;\n const relative = RELATIVE_DATE.test(value);\n if (isDate(f)) {\n const timed = relative ? relativeHasTime(value) : /T\\d{2}:\\d{2}/.test(value);\n if (timed && f.format !== \"datetime\") {\n say(at, `\"${f.label}\" holds a time of day (\"${value}\") but its format is ${f.format ? `\"${f.format}\"` : \"not set\"}, so the calendar would show it as all-day. Set the field's format to \"datetime\", or seed whole days.`);\n }\n if (f.absoluteDates) {\n if (relative) say(at, `\"${f.label}\" holds history (absoluteDates), so write the real date, not \"${value}\".`);\n else if (Number.isNaN(Date.parse(value))) say(at, `\"${value}\" is not a date.`);\n } else if (!relative) {\n say(at, `\"${value}\" is an absolute date. Write seed dates relative to install day (\"@today+3d\", \"@today-1w 09:30\"), or flag the field absoluteDates if it is history (a date of birth).`);\n }\n } else if (relative) say(at, `\"${value}\" is a relative date in \"${f.label}\", which is not a date field.`);\n else if (f.parityType === \"attachment\" && FILE_VALUE_RE.test(value)) continue;\n else if (value.startsWith(\"@\")) say(at, `\"${value}\" is not in the relative-date grammar (\"@today\", \"@today-3b 08:30\", \"@next-tue\", \"@today~b 10:00\").`);\n else if (ISO_DAY.test(value)) say(at, `\"${value}\" writes a calendar date into text, where it goes stale the day after install. Put the date in a date field (relative), or leave it out.`);\n }\n });\n }\n\n // ── seed.attachments: pictures come from the platform library, named by \"@file:<key>\" ──\n for (const p of attachmentProblems(raw)) say(p.at, p.says);\n\n const spec = resolveRelativeDates(raw, TEMPLATE_REFERENCE_DATE);\n\n // ── the shared law, shape and graph (validateUseCase over the derived use case) ──\n const derived = { ...spec, industry: spec.vertical, tables: allTables(spec), ...deriveSingulars(spec) } as unknown as UseCase;\n for (const p of validateUseCase(derived).problems) if (!SINGULAR_OWES.has(p.at)) problems.push(p);\n\n // ── lane 12 P7: Confidential tables and members-add-rows tables name real tables and fields ──\n for (const says of tableSettingsProblems(spec)) say(\"confidential\", says);\n\n // ── the catalogue keys ──────────────────────────────────────────────────────\n if (spec.specVersion !== TEMPLATE_SPEC_VERSION) say(\"specVersion\", `The file's schema version is ${TEMPLATE_SPEC_VERSION}; write \"specVersion\": ${TEMPLATE_SPEC_VERSION}.`);\n if (!/^T\\d{4}$/.test(spec.catalogueId ?? \"\")) say(\"catalogueId\", `\"${spec.catalogueId}\" should be the CATALOGUE.json row it realises, like \"T0042\".`);\n if (!(INDUSTRY_GROUPS as readonly string[]).includes(spec.industry)) say(\"industry\", `\"${spec.industry}\" is not one of the catalogue's industry groups: ${INDUSTRY_GROUPS.join(\", \")}.`);\n if (!spec.vertical?.trim()) say(\"vertical\", \"Name the practitioner's own vertical — 'Dental practice', 'Residential HVAC'.\");\n if (!(TEMPLATE_JOBS as readonly string[]).includes(spec.job)) say(\"job\", `\"${spec.job}\" is not one of the twelve jobs: ${TEMPLATE_JOBS.join(\", \")}.`);\n if (!(TEMPLATE_AUDIENCES as readonly string[]).includes(spec.audience)) say(\"audience\", `\"${spec.audience}\" is not one of: ${TEMPLATE_AUDIENCES.join(\", \")}.`);\n if (!(TEACHES_FEATURES as readonly string[]).includes(spec.teaches)) say(\"teaches\", `\"${spec.teaches}\" is not one of the sixteen features.`);\n if (!spec.strengths?.length) say(\"strengths\", \"Name at least one strength (S1–S5) this template leads with.\");\n for (const s of spec.strengths ?? []) if (!(STRENGTHS as readonly string[]).includes(s)) say(\"strengths\", `\"${s}\" is not one of: ${STRENGTHS.join(\", \")}.`);\n if (!Number.isInteger(spec.version) || spec.version < 1) say(\"version\", \"The content version is a whole number, 1 or more, bumped on every published change.\");\n if (!Array.isArray(spec.provenance?.sources)) say(\"provenance.sources\", \"List the sources the structure came from (an empty list says 'from domain knowledge').\");\n\n const own = spec.tables ?? [];\n const tables = allTables(spec);\n const byToken = new Map(tables.map((t) => [t.token, t]));\n const fieldOf = (table: string, key: string): TemplateField | undefined => byToken.get(table)?.fields.find((f) => f.key === key);\n const refWeek0 = [0, 1, 2, 3, 4, 5, 6].map((i) => shiftDays(TEMPLATE_REFERENCE_DATE, i));\n /** A lookup's or formula's value on one row, worked out the store's way, or why the gate cannot. */\n function computedOf(table: string, f: TemplateField, r: SeedRow, depth = 0): { ok: true; v: unknown } | { ok: false; why: string } {\n if (depth > 4) return { ok: false, why: \"it reads through too many computed fields\" };\n if (f.parityType === \"lookup\" && f.via && f.pick) {\n const target = fieldOf(table, f.via)?.relationTarget;\n const ref = r.values?.[f.via];\n const far = target ? byToken.get(target)?.rows.find((x) => x.key === (Array.isArray(ref) ? ref[0] : ref)) : undefined;\n const pf = target ? fieldOf(target, f.pick) : undefined;\n if (!far || !pf) return { ok: true, v: null };\n return isComputed(pf) ? computedOf(target!, pf, { key: far.key, values: far.values }, depth + 1) : { ok: true, v: far.values?.[f.pick] ?? null };\n }\n if (f.parityType === \"formula\" && f.formula) {\n const ast = parseFormula(f.formula);\n if (typeof ast === \"string\") return { ok: false, why: ast };\n let why: string | null = null;\n const r2 = evalFormula(ast, (label) => {\n const ff = byToken.get(table)?.fields.find((x) => x.label === label);\n if (!ff) return null;\n if (!isComputed(ff)) return r.values?.[ff.key];\n if (ff.parityType === \"lookup\" || ff.parityType === \"rollup\") {\n why = `it reads the ${ff.parityType} {${label}}, which the store currently reads as 0 in a formula`;\n return null;\n }\n const c = computedOf(table, ff, r, depth + 1);\n if (!c.ok) why = c.why;\n return c.ok ? c.v : null;\n });\n if (why) return { ok: false, why };\n if (!r2.ok) return r2;\n return { ok: true, v: r2.v === null ? null : (qToNumber(r2.v) ?? Number(r2.v.n) / Number(r2.v.d)) };\n }\n return { ok: false, why: `${f.parityType} is not worked out by the gate` };\n }\n /** Rows with several computed fields (a measure and its filter keys) filled in. */\n function withComputedKeys(table: string, keys: (string | undefined)[], rows: SeedRow[]): { rows: SeedRow[] } | { why: string } {\n let acc: { rows: SeedRow[] } | { why: string } = { rows };\n for (const k of keys) if (\"rows\" in acc) acc = withComputed(table, k, acc.rows);\n return acc;\n }\n /** A formula over STORED columns whose answer is a number (custom.formula_eval computes these correctly). */\n function isNumberish(table: string, f: TemplateField | undefined): boolean {\n if (!f) return false;\n if (isNumber(f)) return true;\n if (f.parityType !== \"formula\" || !f.formula) return false;\n const ast = parseFormula(f.formula);\n if (typeof ast === \"string\") return false;\n const refsStored = formulaRefs(ast).every((l) => {\n const rf = byToken.get(table)?.fields.find((x) => x.label === l);\n return !!rf && !isComputed(rf);\n });\n const NUMERIC = new Set([\"ABS\", \"ROUND\", \"SUM\", \"MIN\", \"MAX\", \"AVERAGE\", \"DATEDIFF\", \"YEAR\", \"MONTH\", \"DAY\", \"LEN\"]);\n const numeric = (n: typeof ast): boolean => n.k === \"num\" || n.k === \"bin\" || n.k === \"neg\" || (n.k === \"call\" && NUMERIC.has(n.f)) || (n.k === \"ref\" && isNumber(byToken.get(table)?.fields.find((x) => x.label === n.v) ?? { parityType: \"\" }));\n return refsStored && numeric(ast);\n }\n /** Rows with one computed field filled in, so custom.record_aggregate's answer over it can be mirrored. */\n function withComputed(table: string, key: string | undefined, rows: SeedRow[]): { rows: SeedRow[] } | { why: string } {\n const f = key ? fieldOf(table, key) : undefined;\n if (!f || !isComputed(f)) return { rows };\n const out: SeedRow[] = [];\n for (const r of rows) {\n const c = computedOf(table, f, r);\n if (!c.ok) return { why: `\"${f.label}\" is computed by the store and ${c.why}, so the gate cannot check the answer the store's way` };\n out.push({ ...r, values: { ...r.values, [f.key]: c.v } });\n }\n return { rows: out };\n }\n /**\n * What the seed itself says a stage carries: every seed row in stage X fills F and every row in\n * an earlier (unfinished) stage leaves it empty — at least two of each. Map stage → fields.\n */\n function inferredImplies(table: string, stageField: string): Map<string, string[]> {\n const out = new Map<string, string[]>();\n const t = byToken.get(table);\n const order = fieldOf(table, stageField)?.choices ?? [];\n if (!t) return out;\n order.forEach((x, ix) => {\n const inX = t.rows.filter((r) => storeText(r.values?.[stageField]) === x);\n const before = t.rows.filter((r) => {\n const j = order.indexOf(storeText(r.values?.[stageField]) ?? \"\");\n return j >= 0 && j < ix && !TERMINAL_STAGE.test(order[j]!);\n });\n if (inX.length < 2 || before.length < 2) return;\n const keys = t.fields.filter((f) => f.key !== stageField && !isComputed(f) && !f.required && !(isRelation(f) && (f.multi || (f.relationMax ?? 1) !== 1)) && inX.every((r) => filled(r.values?.[f.key])) && before.every((r) => !filled(r.values?.[f.key]))).map((f) => f.key);\n if (keys.length) out.set(x, keys);\n });\n return out;\n }\n /** A lookup is as sensitive as the strictest field it reads (its own declaration, or the far side's). */\n const effective = (table: string, f: TemplateField, depth = 0): { sensitivity: string; contextPolicy: string } => {\n let sens = f.sensitivity as string;\n let ctx = f.contextPolicy as string;\n if (f.parityType === \"lookup\" && f.via && f.pick && depth < 5) {\n const via = fieldOf(table, f.via);\n const far = via?.relationTarget ? fieldOf(via.relationTarget, f.pick) : undefined;\n if (via?.relationTarget && far) {\n const e = effective(via.relationTarget, far, depth + 1);\n if (SENSITIVITY_RANK.indexOf(e.sensitivity) > SENSITIVITY_RANK.indexOf(sens)) sens = e.sensitivity;\n if (CONTEXT_RANK.indexOf(e.contextPolicy) > CONTEXT_RANK.indexOf(ctx)) ctx = e.contextPolicy;\n }\n }\n return { sensitivity: sens, contextPolicy: ctx };\n };\n const agentReads = (table: string, f: TemplateField) => {\n const e = effective(table, f);\n return e.contextPolicy !== \"exclude\" && e.sensitivity !== \"restricted\";\n };\n\n // ── the floor ───────────────────────────────────────────────────────────────\n if (own.length < TABLES_MIN || own.length > TABLES_MAX) say(\"tables\", `A template installs ${TABLES_MIN}–${TABLES_MAX} related tables; this one has ${own.length}.`);\n const main = own[0];\n if (main && (main.rows.length < MAIN_TABLE_ROWS_MIN || main.rows.length > MAIN_TABLE_ROWS_MAX)) {\n say(`tables[0] (${main.token}).rows`, `The main table carries ${MAIN_TABLE_ROWS_MIN}–${MAIN_TABLE_ROWS_MAX} realistic rows; it has ${main.rows.length}.`);\n }\n\n // ── no two columns of one table share a label (the store refuses the second) ──\n for (const t of tables) {\n const seenLabels = new Map<string, string>();\n for (const f of t.fields) {\n const l = f.label.trim().toLowerCase();\n const twin = seenLabels.get(l);\n if (twin) say(`tables (${t.token}).fields (${f.key}).label`, `\"${f.label}\" is already the label of \"${twin}\" on \"${t.name}\"; the store refuses a second column with that name. Give each column its own label.`);\n else seenLabels.set(l, f.key);\n }\n }\n\n // ── fields and rows: colours, rules, distinctness, lookups ──────────────────\n let hasLookupOrRollup = false;\n tables.forEach((table) => {\n const tat = `tables (${table.token})`;\n table.fields.forEach((field) => {\n const at = `${tat}.fields (${field.key})`;\n if (isChoice(field) && field.choices?.length) {\n const colors = field.choices.map((c) => field.choiceColors?.[c]);\n field.choices.forEach((c, i) => {\n const color = colors[i];\n if (!color) say(`${at}.choiceColors`, `The choice \"${c}\" wears no colour. Give every choice one of: ${CHOICE_COLORS.join(\", \")}.`);\n else if (!(CHOICE_COLORS as readonly string[]).includes(color)) say(`${at}.choiceColors`, `\"${color}\" is not a colour the grid can paint.`);\n });\n for (const k of Object.keys(field.choiceColors ?? {})) if (!field.choices.includes(k)) say(`${at}.choiceColors`, `It colours \"${k}\", which is not one of the field's choices.`);\n // Distinct per choice up to the palette (7 colours today; the ruling's \"up to 8\"\n // is capped by what the grid can paint), every colour used above that.\n const distinct = new Set(colors.filter(Boolean)).size;\n const need = Math.min(field.choices.length, CHOICE_COLORS.length);\n if (distinct < need) say(`${at}.choiceColors`, `${field.choices.length} choices wear only ${distinct} distinct colour(s); each choice needs its own (${need}), so the board reads at a glance.`);\n }\n if (isNumber(field) && !isComputed(field)) {\n const kinds = new Set((field.rules ?? []).map((r) => r.kind));\n if (!kinds.has(\"min\") || !kinds.has(\"max\")) say(`${at}.rules`, `\"${field.label}\" is measured, so it declares the least and the most a real value can be (min and max rules).`);\n const seeds = table.rows.map((r) => parseNumeric(storeText(r.values?.[field.key]) ?? \"\")).filter((v): v is Q => !!v).map((v) => Number(v.n) / Number(v.d));\n if (seeds.length) {\n const hi = Math.max(...seeds);\n const lo = Math.min(...seeds);\n if (new Set(seeds).size < 2) say(`${at}`, `Every seed row holds the same ${field.label}; real records vary.`);\n for (const rule of field.rules ?? []) {\n const bound = Number(rule.value);\n if (rule.kind === \"max\" && hi > 0 && bound > 100 * hi) say(`${at}.rules`, `The most \"${field.label}\" allows (${rule.value}) is over 100× the largest real value (${hi}); write the real ceiling.`);\n if (rule.kind === \"min\" && bound < -1000 * Math.abs(lo)) say(`${at}.rules`, `The least \"${field.label}\" allows (${rule.value}) is far below any real value (${lo}); write the real floor.`);\n if (rule.kind === \"min\" && bound < 0 && lo >= 0) say(`${at}.rules`, `\"${field.label}\" allows negative values, and no real one is negative; the floor is 0 or above.`);\n }\n }\n }\n if (field.parityType === \"lookup\" || field.parityType === \"rollup\") {\n const via = field.via ? fieldOf(table.token, field.via) : undefined;\n if (!via || !isRelation(via) || !via.relationTarget) {\n say(`${at}.via`, `A ${field.parityType} reads THROUGH a relation field of this table; \"${field.via ?? \"(none)\"}\" is not one.`);\n } else {\n hasLookupOrRollup = true;\n if (!field.pick || !fieldOf(via.relationTarget, field.pick)) say(`${at}.pick`, `It reads \"${field.pick ?? \"(nothing)\"}\" on \"${via.relationTarget}\", which that table does not declare.`);\n if (field.parityType === \"rollup\" && !field.agg) say(`${at}.agg`, \"A rollup says how it adds up the far side.\");\n // custom.field_declare (FLD-11): a rollup aggregates MANY records, so its relation must be a list.\n if (field.parityType === \"rollup\" && !via.multi && (via.relationMax ?? 1) <= 1) say(`${at}.via`, `\"${field.label}\" adds up \"${via.label}\", which links one record. Make \"${via.label}\" a list (multi), or read its one value with a lookup.`);\n }\n }\n if (field.parityType === \"entity_reference\" && !field.allowedTypes?.length) say(`${at}.allowedTypes`, \"A column that points at the platform names the kinds it may point at.\");\n if (isRelation(field) && field.relationTarget && !byToken.has(field.relationTarget)) say(`${at}.relationTarget`, `It points at \"${field.relationTarget}\", which is neither a table nor a shared block of this template.`);\n });\n\n // seed rows obey their own rules\n const seen = new Map<string, string>();\n const titles = new Set<string>();\n table.rows.forEach((row, ri) => {\n const rat = `${tat}.rows[${ri}] (${row.key})`;\n const sig = sortedJson(row.values ?? {});\n const twin = seen.get(sig);\n if (twin) say(rat, `This row is identical to \"${twin}\" apart from its key. Every seed row is a different real record.`);\n seen.set(sig, row.key);\n for (const field of table.fields) {\n if (!isRelation(field) || !field.relationTarget || field.parityType === \"attachment\") continue;\n const target = byToken.get(field.relationTarget);\n const v = row.values?.[field.key];\n if (!target || v === undefined || v === null) continue;\n for (const ref of Array.isArray(v) ? v : [v]) {\n if (typeof ref === \"string\" && !target.rows.some((r) => r.key === ref)) say(`${rat}.values.${field.key}`, `It points at the row \"${ref}\", which does not exist in \"${field.relationTarget}\".`);\n }\n }\n const title = storeText(row.values?.[table.titleField]);\n if (title) titles.add(title.trim().toLowerCase());\n for (const field of table.fields) {\n const v = row.values?.[field.key];\n if (v === undefined || v === null || v === \"\") continue;\n for (const rule of field.rules ?? []) {\n const t = storeText(v) ?? \"\";\n if (rule.kind === \"min\" || rule.kind === \"max\") {\n const n = parseNumeric(t);\n const bound = parseNumeric(String(rule.value));\n if (n && bound && (rule.kind === \"min\" ? qCmp(n, bound) < 0 : qCmp(n, bound) > 0)) {\n say(`${rat}.values.${field.key}`, `${t} breaks its own rule: \"${field.label}\" is at ${rule.kind === \"min\" ? \"least\" : \"most\"} ${rule.value}.`);\n }\n } else if (rule.kind === \"length\") {\n if (rule.value !== undefined && t.length > Number(rule.value)) say(`${rat}.values.${field.key}`, `\"${t}\" is longer than \"${field.label}\" allows (${rule.value}).`);\n if (rule.min !== undefined && t.length < rule.min) say(`${rat}.values.${field.key}`, `\"${t}\" is shorter than \"${field.label}\" allows (${rule.min}).`);\n } else if (rule.kind === \"pattern\" && rule.value !== undefined) {\n let re: RegExp | null = null;\n try {\n re = new RegExp(String(rule.value));\n } catch {\n say(`${tat}.fields (${field.key}).rules`, `The pattern \"${rule.value}\" is not a pattern.`);\n }\n if (re && !re.test(t)) say(`${rat}.values.${field.key}`, `\"${t}\" does not match \"${field.label}\"'s own pattern.`);\n }\n }\n }\n });\n for (const field of table.fields) {\n if (!(field.rules ?? []).some((r) => r.kind === \"unique\")) continue;\n const vals = table.rows.map((r) => storeText(r.values?.[field.key])).filter((v): v is string => !!v).map((v) => v.trim().toLowerCase());\n if (new Set(vals).size !== vals.length) say(`${tat}.fields (${field.key})`, `\"${field.label}\" is unique, and two seed rows share a value.`);\n }\n if (table.rows.length >= 2 && titles.size < Math.ceil(table.rows.length * TITLE_DISTINCT_SHARE)) {\n say(`${tat}.rows`, `Only ${titles.size} of ${table.rows.length} rows have a title of their own; a list of look-alike names reads as generated.`);\n }\n });\n if (!hasLookupOrRollup) sayGallery(\"tables\", \"At least one relationship has to be read across: add a lookup or a rollup through a relation field.\");\n\n // ── the main table: every two rows are different records ────────────────────\n if (main) {\n const normTitle = (v: unknown) => (storeText(v) ?? \"\").toLowerCase().replace(/\\s+/g, \" \").trim();\n const rows = main.rows;\n const titleSeen = new Map<string, string>();\n for (let i = 0; i < rows.length; i += 1) {\n const a = rows[i]!;\n const nt = normTitle(a.values?.[main.titleField]);\n const twin = titleSeen.get(nt);\n const twinTitle = twin ? storeText(rows.find((r) => r.key === twin)?.values?.[main.titleField]) : null;\n const rosterTwin = (() => {\n if (!twin || !main.schedule) return false;\n const b0 = rows.find((r) => r.key === twin);\n const differs = (pred: (f: TemplateField) => boolean) => main.fields.some((f) => pred(f) && !sameJson(a.values?.[f.key] ?? null, b0?.values?.[f.key] ?? null));\n return differs(isDate) && differs(isRelation);\n })();\n if (twin && !rosterTwin) say(`tables[0] (${main.token}).rows[${i}] (${a.key})`, `Two ${main.labelPlural.toLowerCase()} are both called \"${storeText(a.values?.[main.titleField])}\" (the other reads \"${twinTitle}\"). Give each its own name.`);\n else titleSeen.set(nt, a.key);\n for (let j = i + 1; j < rows.length; j += 1) {\n const b = rows[j]!;\n const keys = new Set([...Object.keys(a.values ?? {}), ...Object.keys(b.values ?? {})]);\n let differ = 0;\n for (const k of keys) if (!sameJson(a.values?.[k] ?? null, b.values?.[k] ?? null)) differ += 1;\n if (differ < 3) say(`tables[0] (${main.token}).rows[${j}] (${b.key})`, `\"${storeText(b.values?.[main.titleField])}\" differs from \"${storeText(a.values?.[main.titleField])}\" in only ${differ} field(s); two real ${main.labelPlural.toLowerCase()} differ in at least three.`);\n }\n }\n }\n\n // ── governance ──────────────────────────────────────────────────────────────\n const fields = tables.flatMap((t) => t.fields);\n const ownFields = own.flatMap((t) => t.fields);\n if (!ownFields.some((f) => f.sensitivity !== \"internal\")) say(\"tables\", \"Every field says internal. Mark what is really confidential or restricted (a phone, a gate code, a diagnosis).\");\n else if (ownFields.filter((f) => f.sensitivity !== \"internal\").length < 0.2 * ownFields.length) {\n say(\"tables\", `Only ${ownFields.filter((f) => f.sensitivity !== \"internal\").length} of ${ownFields.length} fields say anything but internal; at least 20% of a real business's columns are public, confidential or restricted.`);\n }\n // S1 is shown by a governed field that holds real values and that a person meets on a view or a form.\n const governed = own.some((t) =>\n t.fields.some((f) => {\n if (!((f.sensitivity === \"restricted\" || f.sensitivity === \"confidential\") && f.contextPolicy === \"exclude\")) return false;\n const held = t.rows.filter((r) => filled(r.values?.[f.key])).length;\n const met =\n (spec.views ?? []).some((v) => v.table === t.token && !(v.hiddenFields ?? []).includes(f.key)) ||\n (spec.forms ?? []).some((fm) => fm.table === t.token && fm.fields.some((ff) => ff.fieldKey === f.key));\n return t.rows.length > 0 && held >= 0.8 * t.rows.length && met;\n }),\n );\n\n // ── shared blocks: seeded, referenced, never copied ─────────────────────────\n (spec.sharedBlocks ?? []).forEach((use, i) => {\n const at = `sharedBlocks[${i}]`;\n const block = SHARED_BLOCKS[use.block];\n if (!block) return say(`${at}.block`, `\"${use.block}\" is not a shared block: ${SHARED_BLOCK_IDS.join(\", \")}.`);\n if (own.some((t) => t.token === block.table)) say(at, `The template declares its own \"${block.table}\" table; the shared block is that table — drop the copy.`);\n if (!use.rows?.length) say(`${at}.rows`, \"Seed the block with this business's own people, so 'assigned to' columns are filled.\");\n if (!own.some((t) => t.fields.some((f) => isRelation(f) && f.relationTarget === block.table))) say(at, `Nothing points at \"${block.table}\"; reference the block with a relation field.`);\n });\n own.forEach((table, ti) => {\n for (const id of SHARED_BLOCK_IDS) {\n const block = SHARED_BLOCKS[id];\n // Similar by TYPE and by the words of the label: \"Cell phone\" is the block's Mobile,\n // \"Hired on\" its Start date, \"Technician name\" its Name.\n const hits = block.fields.filter((bf) => table.fields.some((f) => behaviorOf(f) === behaviorOf(bf) && labelMeans(f, bf.sameAs as readonly string[])));\n // A copy plays the TEAM's role: a hire/start date, pay, or staff roles on a table that is\n // nobody's contact list. A customer's contacts (name, role, email, phone on a table linked\n // to a client/customer/account) are the customer's people, not a copy of the team.\n const hired = hits.some((h) => h.key === \"start_date\");\n // \"Pay\" is what the business pays them (a wage, a pay rate) — never a candidate's asking salary.\n const paid = table.fields.some((f) => /(^|_)(pay|wage|wages|hourly_rate|pay_rate)($|_)/.test(f.key));\n // People who belong to some record of this business (a client, an account, a pool) are\n // that record's contacts; the team belongs to no record.\n const contactOfSomeone = table.fields.some((f) => isRelation(f) && f.relationTarget && f.relationTarget !== block.table && own.some((t) => t.token === f.relationTarget));\n const staffOnly = hired || (paid && hits.some((h) => h.key === \"role\")) || (hits.some((h) => h.key === \"role\") && !contactOfSomeone);\n if (hits.length >= block.copyThreshold && staffOnly) {\n say(`tables[${ti}] (${table.token})`, `This table copies the shared \"${id}\" block (${hits.map((h) => h.label).join(\", \")}). Seed the block in sharedBlocks and point a relation field at it.`);\n }\n }\n });\n\n // ── surface tokens are unique ───────────────────────────────────────────────\n const surfaces = new Map<string, { at: string; table?: string }>();\n const claim = (token: string, at: string, table?: string) => {\n if (surfaces.has(token)) say(at, `The token \"${token}\" is used by ${surfaces.get(token)?.at} too; every view, form and extra has its own.`);\n else surfaces.set(token, { at, ...(table ? { table } : {}) });\n };\n\n // ── views ───────────────────────────────────────────────────────────────────\n const views = spec.views ?? [];\n if (views.length < 3) sayGallery(\"views\", `A template shows at least three views; this one has ${views.length}.`);\n if (!views.some((v) => v.kind === \"grid\")) sayGallery(\"views\", \"One of the views is a grid — the table everyone recognises.\");\n views.forEach((view: TemplateView, i) => {\n const at = `views[${i}] (${view.token})`;\n claim(view.token, at, view.table);\n if (!(TEMPLATE_VIEW_KINDS as readonly string[]).includes(view.kind)) return say(`${at}.kind`, `\"${view.kind}\" is not a view kind.`);\n if (!byToken.has(view.table)) return say(`${at}.table`, `The view looks at \"${view.table}\", which this template does not declare.`);\n const need = (prop: string, key: string | undefined, ok: ((f: TemplateField) => boolean) | null, what: string) => {\n if (!key) return say(`${at}.${prop}`, `A ${view.kind} view needs ${what}.`);\n const f = fieldOf(view.table, key);\n if (!f) return say(`${at}.${prop}`, `\"${view.table}\" does not declare a field \"${key}\".`);\n if (ok && !ok(f)) say(`${at}.${prop}`, `\"${key}\" is a ${f.parityType} field; this needs ${what}.`);\n };\n if (view.kind === \"kanban\") {\n need(\"groupBy\", view.groupBy, isChoice, \"a choice field to make columns from\");\n if (view.swimlaneBy) {\n if (view.swimlaneBy === view.groupBy) say(`${at}.swimlaneBy`, \"Swimlanes cut across the columns, so they are never the column field itself.\");\n need(\"swimlaneBy\", view.swimlaneBy, null, \"a field to cut lanes by\");\n }\n if (view.measure) need(\"measure\", view.measure, (f) => isNumberish(view.table, f), \"a number field to total\");\n } else if (view.kind === \"calendar\") need(\"dateField\", view.dateField, isDate, \"a date field to place records by\");\n else if (view.kind === \"gallery\") need(\"coverField\", view.coverField, (f) => f.parityType === \"attachment\", \"a file field for each card's picture\");\n else if (view.kind === \"timeline\") {\n need(\"startField\", view.startField, isDate, \"a start date\");\n need(\"endField\", view.endField, isDate, \"an end date\");\n } else if (view.groupBy) need(\"groupBy\", view.groupBy, null, \"a field to group rows by\");\n for (const key of Object.keys(view.filters ?? {})) if (!fieldOf(view.table, key)) say(`${at}.filters.${key}`, `It filters on \"${key}\", which \"${view.table}\" does not declare.`);\n for (const [key, vals] of Object.entries(view.anyOf ?? {})) {\n const f = fieldOf(view.table, key);\n if (!f) {\n say(`${at}.anyOf.${key}`, `It filters on \"${key}\", which \"${view.table}\" does not declare.`);\n continue;\n }\n if (key in (view.filters ?? {})) say(`${at}.anyOf.${key}`, `\"${key}\" is in both filters and anyOf; keep it in one.`);\n if (!Array.isArray(vals) || vals.length < 2) say(`${at}.anyOf.${key}`, \"anyOf lists two or more values; one value is a plain filter.\");\n if (f.multi || f.parityType === \"multi_select\" || isRelation(f) || isComputed(f)) say(`${at}.anyOf.${key}`, `\"${f.label}\" is a list, a link or computed; anyOf compares one stored value.`);\n for (const v of vals ?? []) if (f.choices?.length && !f.choices.includes(v)) say(`${at}.anyOf.${key}`, `\"${v}\" is not one of \"${f.label}\"'s choices.`);\n }\n (view.sorts ?? []).forEach((s, si) => {\n if (!fieldOf(view.table, s.field)) say(`${at}.sorts[${si}]`, `It sorts by \"${s.field}\", which \"${view.table}\" does not declare.`);\n });\n for (const key of view.hiddenFields ?? []) if (!fieldOf(view.table, key)) say(`${at}.hiddenFields`, `It hides \"${key}\", which \"${view.table}\" does not declare.`);\n });\n for (const table of tables) {\n const defaults = views.filter((v) => v.table === table.token && v.isDefault).length;\n if (defaults > 1) say(\"views\", `\"${table.token}\" has ${defaults} default views; a table opens on one.`);\n }\n\n // ── forms ───────────────────────────────────────────────────────────────────\n const forms = spec.forms ?? [];\n if (!forms.length) say(\"forms\", \"A template carries at least one form with its questions written out.\");\n const checkQuestions = (at: string, table: string, questions: { fieldKey: string; ask: string }[] | undefined) => {\n if (!questions?.length) return say(at, \"It has to ask something.\");\n questions.forEach((qq, qi) => {\n if (!fieldOf(table, qq.fieldKey)) say(`${at}[${qi}]`, `It asks for \"${qq.fieldKey}\", which \"${table}\" does not declare.`);\n if (!qq.ask?.trim() || qq.ask.trim().length < 6) say(`${at}[${qi}].ask`, `Write the question as it is asked — \"What brings you in today?\" — not just the column name.`);\n });\n };\n forms.forEach((form, i) => {\n const at = `forms[${i}] (${form.token})`;\n claim(form.token, at, form.table);\n if (!byToken.has(form.table)) say(`${at}.table`, `The form collects into \"${form.table}\", which this template does not declare.`);\n else checkQuestions(`${at}.fields`, form.table, form.fields);\n if (!form.confirmation?.trim()) say(`${at}.confirmation`, \"Say what the person sees after they submit, in real words.\");\n });\n\n // ── dimensions, as custom._table_dimensions_check judges them ───────────────\n const pathsByTable = new Map<string, Set<string>>();\n (spec.dimensions ?? []).forEach((dim, i) => {\n const at = `dimensions[${i}] (${dim.table})`;\n const table = byToken.get(dim.table);\n if (!table) return say(`${at}.table`, `There is no table \"${dim.table}\" in this template.`);\n // custom._table_dimensions_infer(every field)\n const dimKeys = new Set<string>([\"created_at\", \"updated_at\"]);\n const inferredMeasures = new Set<string>([\"count\"]);\n for (const f of table.fields) {\n const b = behaviorOf(f);\n if (b === \"list\" && !f.multi && f.parityType !== \"multi_select\") dimKeys.add(f.key);\n else if (b === \"relation\" && f.parityType !== \"attachment\" && !f.multi && (f.relationMax ?? 1) === 1) dimKeys.add(f.key);\n else if (b === \"boolean\") dimKeys.add(f.key);\n else if (isDate(f)) dimKeys.add(f.key);\n else if (b === \"range\") {\n const ops = f.parityType === \"percent\" ? [\"avg\", \"min\", \"max\"] : [\"sum\", \"avg\", \"min\", \"max\"];\n for (const op of ops) inferredMeasures.add(`${op}_${f.key}`);\n inferredMeasures.add(`filled_${f.key}`);\n }\n }\n (dim.dimensions ?? []).forEach((d, di) => {\n if (!dimKeys.has(d.key)) say(`${at}.dimensions[${di}]`, `\"${d.key}\" is not a dimension of \"${dim.table}\". Its dimensions are: ${[...dimKeys].join(\", \")}.`);\n if (d.label !== undefined && (d.label.trim().length < 1 || d.label.trim().length > 80)) say(`${at}.dimensions[${di}]`, \"A dimension's name is 1 to 80 characters.\");\n });\n const newMeasures = new Set<string>();\n (dim.measures ?? []).forEach((m, mi) => {\n const mat = `${at}.measures[${mi}]`;\n if (!MEASURE_KEY.test(m.key)) say(mat, `\"${m.key}\" is not a measure key the store accepts.`);\n if (m.label !== undefined && (m.label.trim().length < 1 || m.label.trim().length > 80)) say(mat, \"A measure's name is 1 to 80 characters.\");\n if (inferredMeasures.has(m.key)) {\n if (m.op || m.of) say(mat, `\"${m.key}\" is worked out from the table's own column, so only its name can change, or it can be hidden.`);\n return;\n }\n if (!m.op || !AGG_OPERATIONS.includes(m.op) || (m.op as string) === \"count\") say(mat, `The measure \"${m.key}\" needs one of: ${AGG_OPERATIONS.filter((o) => o !== \"count\").join(\", \")}.`);\n const of = m.of ? fieldOf(dim.table, m.of) : undefined;\n if (!of) say(mat, `The measure \"${m.key}\" reads \"${m.of ?? \"(nothing)\"}\", which is not a column of \"${dim.table}\".`);\n // The store's dimension check (custom._table_dimensions_check) totals only a STORED number column\n // (type range, not a date): a formula, lookup or rollup is refused at install even when it is money.\n else if (m.op && [\"sum\", \"avg\", \"min\", \"max\", \"median\"].includes(m.op) && !(isNumber(of) && !isComputed(of))) say(mat, isComputed(of) ? `\"${m.of}\" is worked out, and a dimension totals only a number that is typed in; total the stored columns it is made from.` : `\"${m.of}\" is not a number, so it cannot be added up or averaged.`);\n if (newMeasures.has(m.key)) say(mat, `Two measures are both called \"${m.key}\".`);\n newMeasures.add(m.key);\n });\n const paths = new Set<string>(dimKeys.has(\"created_at\") ? [\"created_at\"] : []);\n for (const f of table.fields) if (isDate(f)) paths.add(f.key);\n (dim.paths ?? []).forEach((p, pi) => {\n if (!MEASURE_KEY.test(p.key) || !p.levels?.length) return say(`${at}.paths[${pi}]`, `A drill path has a key and at least one level, so \"${p.key}\" was not saved.`);\n for (const level of p.levels) {\n const [key, grain] = level.split(\":\");\n if (!key || !dimKeys.has(key) || (level.includes(\":\") && !BUCKETS.includes(grain ?? \"\"))) {\n say(`${at}.paths[${pi}]`, `The drill path \"${p.key}\" names \"${level}\", which is not a dimension of \"${dim.table}\" (a date takes :year, :quarter, :month, :week or :day).`);\n }\n }\n paths.add(p.key);\n });\n pathsByTable.set(dim.table, paths);\n for (const by of dim.default?.by ?? []) if (!dimKeys.has(by.split(\":\")[0] ?? \"\")) say(`${at}.default.by`, `The first screen groups by \"${by}\", which is not a dimension.`);\n for (const show of dim.default?.show ?? []) if (!inferredMeasures.has(show) && !newMeasures.has(show)) say(`${at}.default.show`, `The first screen shows \"${show}\", which is not a measure of this table.`);\n });\n\n // ── merge fields: only {{field_key}} of the one table (custom.doc_render_body) ──\n const checkMerge = (at: string, table: string, text: string) => {\n for (const m of text.matchAll(MERGE_TOKEN)) {\n const key = m[1] ?? \"\";\n const f = fieldOf(table, key);\n if (!f) say(at, `{{${key}}} does not resolve: the store merges only the fields of \"${table}\" (no today, no business details).`);\n else if (f.parityType === \"signature\") say(at, `{{${key}}} is a signature, and a signature never merges into the body.`);\n }\n };\n\n // ── extras ──────────────────────────────────────────────────────────────────\n const extras = spec.extras ?? [];\n if (extras.length < 2) sayGallery(\"extras\", `A template carries at least two extras; this one has ${extras.length}.`);\n const formTokens = new Set(forms.map((f) => f.token));\n const viewTokens = new Set(views.map((v) => v.token));\n const docTokens = new Set(extras.filter((e) => e.kind === \"document\").map((e) => e.token));\n const honestCharts = new Map<string, number>();\n const stageRules = new Map<string, Extract<TemplateSpec[\"extras\"][number], { kind: \"stage_rules\" }>>();\n extras.forEach((extra, i) => {\n const at = `extras[${i}] (${extra.kind}:${extra.token})`;\n const extraTable = \"table\" in extra ? extra.table : extra.kind === \"portal\" ? extra.clientTable : extra.kind === \"checklist\" ? extra.aboutTable : undefined;\n claim(extra.token, at, extraTable);\n const needTable = (table: string, prop = \"table\") => {\n if (byToken.has(table)) return true;\n say(`${at}.${prop}`, `It names \"${table}\", which this template does not declare.`);\n return false;\n };\n switch (extra.kind) {\n case \"booking\": {\n if (needTable(extra.table)) checkQuestions(`${at}.questions`, extra.table, extra.questions);\n const a = extra.availability;\n if (!a?.windows?.length) say(`${at}.availability`, \"A booking page offers at least one window of time.\");\n a?.windows?.forEach((w, wi) => {\n if (w.weekday < 0 || w.weekday > 6) say(`${at}.availability.windows[${wi}]`, \"A weekday is 0 (Sunday) to 6 (Saturday).\");\n if (!(w.from < w.to)) say(`${at}.availability.windows[${wi}]`, `\"${w.to}\" has to be later in the day than \"${w.from}\".`);\n });\n if (!a?.slotMinutes || a.slotMinutes < 5) say(`${at}.availability.slotMinutes`, \"Say how long one appointment is, in minutes.\");\n break;\n }\n case \"portal\": {\n needTable(extra.clientTable, \"clientTable\");\n if (!extra.tables?.length) say(`${at}.tables`, \"A portal shows its client at least one table.\");\n extra.tables?.forEach((pt, pi) => {\n const pat = `${at}.tables[${pi}]`;\n if (!needTable(pt.table, `tables[${pi}].table`)) return;\n const via = pt.namesVia ? fieldOf(pt.table, pt.namesVia) : undefined;\n if (!via || !isRelation(via) || via.relationTarget !== extra.clientTable) {\n say(pat, `namesVia must be the relation field of \"${pt.table}\" that points at the client table \"${extra.clientTable}\" — it is what makes \"only theirs\" answerable.`);\n }\n if (!pt.visibleFields?.length) say(pat, \"A portal table shows at least one field.\");\n for (const key of [...new Set([...(pt.visibleFields ?? []), ...(pt.editableFields ?? [])])]) {\n const f = fieldOf(pt.table, key);\n if (!f) {\n say(pat, `It shows \"${key}\", which \"${pt.table}\" does not declare.`);\n continue;\n }\n const e = effective(pt.table, f);\n // A portal shows a client only their own rows (namesVia), so their own confidential\n // details may go out; restricted fields and fields kept from the AI never do.\n if (e.sensitivity === \"restricted\" || e.contextPolicy === \"exclude\") {\n say(pat, `\"${f.label}\" is ${e.contextPolicy === \"exclude\" ? \"kept from the AI\" : \"restricted\"}${f.parityType === \"lookup\" ? \" (through what it looks up)\" : \"\"}; a portal shows a client fields up to confidential, never restricted or kept-from-AI ones.`);\n }\n }\n if (pt.namesVia && pt.editableFields?.includes(pt.namesVia)) say(pat, `\"${pt.namesVia}\" is what makes the records theirs, so a client can never edit it.`);\n for (const key of pt.editableFields ?? []) if (!pt.visibleFields?.includes(key)) say(pat, `\"${key}\" is editable in the portal but not visible there.`);\n });\n for (const f of extra.forms ?? []) if (!formTokens.has(f)) say(`${at}.forms`, `It offers the form \"${f}\", which this template does not declare.`);\n break;\n }\n case \"dashboard\": {\n needTable(extra.table);\n let charts = 0;\n extra.blocks?.forEach((b, bi) => {\n const table = b.table ?? extra.table;\n if (!byToken.has(table)) return say(`${at}.blocks[${bi}]`, `It reads \"${table}\", which this template does not declare.`);\n let honest = true;\n for (const m of b.measures ?? []) {\n const f = m.key ? fieldOf(table, m.key) : undefined;\n if (f && [\"sum\", \"avg\", \"min\", \"max\", \"median\"].includes(m.op) && !isNumberish(table, f)) {\n honest = false;\n say(`${at}.blocks[${bi}]`, `\"${b.title}\" takes the ${m.op} of \"${f.label}\", which is not a number.`);\n }\n }\n if (b.bucket) {\n const f = fieldOf(table, b.bucket.key);\n if (f && !isDate(f)) {\n honest = false;\n say(`${at}.blocks[${bi}]`, `\"${b.title}\" cuts time by \"${f.label}\", which is not a date.`);\n }\n }\n for (const g of b.groupBy ?? []) {\n const vals = new Set((byToken.get(table)?.rows ?? []).map((r) => storeText(r.values?.[g])).filter((v) => v !== null && v !== \"\"));\n if (fieldOf(table, g) && vals.size < 2) {\n honest = false;\n saySeed(`${at}.blocks[${bi}]`, `\"${b.title}\" groups by \"${g}\", which holds ${vals.size} distinct value(s) in the seed — a chart of one bar.`);\n }\n }\n if (honest && CHART_BLOCK_KINDS.has(b.kind)) charts += 1;\n for (const key of [\n ...(b.groupBy ?? []),\n ...(b.measures ?? []).map((m) => m.key).filter((k): k is string => !!k),\n ...(b.bucket ? [b.bucket.key] : []),\n ...(b.stateKey ? [b.stateKey] : []),\n ...Object.keys(b.filter ?? {}),\n ]) {\n if (!fieldOf(table, key)) say(`${at}.blocks[${bi}]`, `\"${b.title}\" reads \"${key}\", which \"${table}\" does not declare.`);\n }\n if (b.kind === \"stuck\" && !b.stateKey) say(`${at}.blocks[${bi}]`, \"A 'stuck' block names the field it watches.\");\n if (!b.title?.trim()) say(`${at}.blocks[${bi}]`, \"Every block has a title the owner reads.\");\n });\n honestCharts.set(extra.token, charts);\n const sigs = new Set<string>();\n for (const blk of extra.blocks ?? []) {\n const sig = JSON.stringify([blk.kind, blk.table ?? extra.table, blk.groupBy ?? [], blk.measures ?? [], blk.bucket ?? null, blk.filter ?? null]);\n if (sigs.has(sig)) say(`${at}.blocks`, `\"${blk.title}\" draws the same chart as another block on this dashboard.`);\n sigs.add(sig);\n }\n if (charts < 2) saySeed(`${at}.blocks`, `A dashboard here shows at least two honest charts (bar, column, line or donut over real numbers, dates and groups); this one has ${charts}.`);\n break;\n }\n case \"drill_down\":\n if (needTable(extra.table) && !pathsByTable.get(extra.table)?.has(extra.path)) say(`${at}.path`, `\"${extra.path}\" is not a drill path in the dimensions of \"${extra.table}\".`);\n break;\n case \"digest\":\n if (!viewTokens.has(extra.view)) say(`${at}.view`, `The digest sends the view \"${extra.view}\", which this template does not declare.`);\n if (![\"instant\", \"hourly\", \"daily\", \"weekly\"].includes(extra.cadence)) say(`${at}.cadence`, \"A digest is instant, hourly, daily or weekly.\");\n if (extra.cadence !== \"instant\" && !extra.schedule) say(`${at}.schedule`, \"Say when it goes out — 'monday 08:00'.\");\n break;\n case \"checklist\": {\n needTable(extra.aboutTable, \"aboutTable\");\n const roles = new Set((extra.roles ?? []).map((r) => r.role));\n const refs = new Set<string>();\n if (!extra.steps?.length) say(`${at}.steps`, \"A checklist has steps.\");\n extra.steps?.forEach((s, si) => {\n const sat = `${at}.steps[${si}] (${s.ref})`;\n if (refs.has(s.ref)) say(sat, `Two steps are both \"${s.ref}\".`);\n for (const dep of s.dependsOn ?? []) if (!refs.has(dep)) say(sat, `It waits for \"${dep}\", which is not a step above it.`);\n refs.add(s.ref);\n if (s.role && !roles.has(s.role)) say(sat, `It belongs to the role \"${s.role}\", which the checklist does not declare.`);\n const r = s.requires;\n if (r?.kind === \"form\" && !formTokens.has(r.form)) say(sat, `It is the form \"${r.form}\", which this template does not declare.`);\n if (r?.kind === \"document\" && !docTokens.has(r.document)) say(sat, `It is the document \"${r.document}\", which this template does not declare.`);\n if (r?.kind === \"record_field\" && !fieldOf(extra.aboutTable, r.key)) say(sat, `It needs \"${r.key}\" filled, which \"${extra.aboutTable}\" does not declare.`);\n });\n const t = extra.trigger;\n if (t && t.kind !== \"manual\" && needTable(t.table, \"trigger.table\") && t.kind === \"status_reached\") {\n if (!byToken.get(t.table)?.fields.some((f) => f.choices?.includes(t.status))) say(`${at}.trigger.status`, `No choice field of \"${t.table}\" has the status \"${t.status}\".`);\n }\n break;\n }\n case \"document\":\n if (!needTable(extra.table)) break;\n checkMerge(`${at}.title`, extra.table, extra.title ?? \"\");\n checkMerge(`${at}.body`, extra.table, extra.body ?? \"\");\n if ((extra.body ?? \"\").length < 80) say(`${at}.body`, \"Write the prose this business would really send, not a stub.\");\n if (!extra.describes?.trim()) say(`${at}.describes`, \"Say what the document is for.\");\n if (extra.signature && !fields.some((f) => f.parityType === \"signature\")) say(`${at}.signature`, \"A document sent for signature needs a signature field on its table.\");\n break;\n case \"notification\":\n if (!needTable(extra.when.table, \"when.table\")) break;\n if (extra.when.field && !fieldOf(extra.when.table, extra.when.field)) say(`${at}.when.field`, `\"${extra.when.table}\" does not declare a field \"${extra.when.field}\".`);\n if (extra.when.event === \"stage_entered\" && !byToken.get(extra.when.table)?.fields.some((f) => f.choices?.includes(extra.when.stage ?? \"\"))) {\n say(`${at}.when.stage`, `\"${extra.when.stage}\" is not a stage of \"${extra.when.table}\".`);\n }\n checkMerge(`${at}.message`, extra.when.table, extra.message ?? \"\");\n if (!extra.audience?.trim()) say(`${at}.audience`, \"Say who it reaches, in the business's own words.\");\n break;\n case \"stage_rules\": {\n if (!needTable(extra.table)) break;\n const stage = fieldOf(extra.table, extra.stageField);\n if (!stage?.choices?.length) {\n say(`${at}.stageField`, `\"${extra.stageField}\" has to be a choice field of \"${extra.table}\".`);\n break;\n }\n stageRules.set(`${extra.table}.${extra.stageField}`, extra);\n const stages = new Set(stage.choices);\n const known = (s: string, where: string) => {\n if (!stages.has(s)) say(`${at}.${where}`, `\"${s}\" is not one of \"${extra.stageField}\"'s choices.`);\n };\n for (const s of stage.choices) if (!extra.stages?.[s]?.trim()) say(`${at}.stages`, `Say what is true of a record sitting in \"${s}\".`);\n for (const s of Object.keys(extra.stages ?? {})) known(s, \"stages\");\n for (const t of extra.transitions ?? []) {\n known(t.from, \"transitions\");\n known(t.to, \"transitions\");\n }\n for (const [s, keys] of Object.entries(extra.requires ?? {})) {\n known(s, \"requires\");\n for (const k of keys) if (!fieldOf(extra.table, k)) say(`${at}.requires`, `Landing in \"${s}\" needs \"${k}\", which \"${extra.table}\" does not declare.`);\n }\n for (const s of Object.keys(extra.limits ?? {})) known(s, \"limits\");\n if (!extra.transitions?.length) say(`${at}.transitions`, \"List the moves the board allows (from → to); without them any card can jump to any stage.\");\n for (const [st, need] of Object.entries(extra.requiresChild ?? {})) {\n known(st, \"requiresChild\");\n const rel = fieldOf(need.table, need.relation);\n if (!rel || rel.relationTarget !== extra.table) say(`${at}.requiresChild`, `\"${need.table}.${need.relation}\" has to be a relation of \"${need.table}\" pointing at \"${extra.table}\".`);\n if (need.field && !fieldOf(need.table, need.field)) say(`${at}.requiresChild`, `\"${need.table}\" does not declare \"${need.field}\".`);\n }\n {\n const seedRows = (byToken.get(extra.table)?.rows ?? []).filter((r) => !(r as { archived?: boolean }).archived);\n for (const [st, keys] of Object.entries(extra.requires ?? {})) {\n for (const k of keys) {\n if (seedRows.length && seedRows.every((r) => filled(r.values?.[k]))) {\n say(`${at}.requires`, `\"${st}\" requires \"${k}\", but every seed row already has it, so the rule never refuses anything. Leave it empty on rows before \"${st}\".`);\n }\n }\n }\n for (const [x, keys] of inferredImplies(extra.table, extra.stageField)) {\n for (const k of keys) {\n const declared = (byToken.get(extra.table)?.statusImplies ?? []).some((r) => r.field === extra.stageField && r.when.includes(x) && (r.filled ?? []).includes(k));\n if (!declared) say(`${at}.stages`, `Every \"${x}\" row has \"${fieldOf(extra.table, k)?.label ?? k}\" and no earlier one does; declare it: statusImplies {field: \"${extra.stageField}\", when: [\"${x}\"], filled: [\"${k}\"]}.`);\n }\n }\n // A paid / done stage with its own date field: statusImplies keeps the two together.\n const implies = byToken.get(extra.table)?.statusImplies ?? [];\n for (const st of stage.choices) {\n for (const [stageWord, fieldWord] of [[/\\b(?:paid|settled)\\b/i, /^(?:paid|paid_on|paid_at|paid_date|date_paid|settled_on)$/], [/\\b(?:done|completed?|finished)\\b/i, /^(?:completed_on|completed_at|done_on|done_at|finished_on|finished_at|date_completed)$/]] as const) {\n if (!stageWord.test(st)) continue;\n for (const pf of byToken.get(extra.table)?.fields ?? []) {\n if (!fieldWord.test(pf.key)) continue;\n const covered = implies.some((r) => r.field === extra.stageField && r.when.includes(st) && (r.filled ?? []).includes(pf.key));\n if (!covered) say(`${at}.stages`, `\"${st}\" has its own \"${pf.label}\" field; add statusImplies {field: \"${extra.stageField}\", when: [\"${st}\"], filled: [\"${pf.key}\"]} so the two never disagree.`);\n }\n }\n }\n }\n for (const [st, rule] of Object.entries(extra.stageDates ?? {})) {\n const why = extra.anyBecause?.[st]?.trim() ?? \"\";\n if (rule === \"any\" && TIME_BOUND_STAGE.test(st) && why.split(/\\s+/).length < 6) {\n say(`${at}.anyBecause`, `\"${st}\" says when something happened, so its date is not \"any\" without a reason; say why in anyBecause (a sentence of six words or more), or give it past, today or future.`);\n }\n }\n for (const t of extra.transitions ?? []) {\n if (!TERMINAL_STAGE.test(t.from)) continue;\n const declared = (extra.reopen ?? []).find((r) => r.from === t.from && r.to === t.to);\n if (!declared || declared.because.trim().split(/\\s+/).length < 6) {\n say(`${at}.transitions`, `\"${t.from}\" → \"${t.to}\" moves a record out of a finished stage; declare it in reopen with the business reason (a rebooked guest, a revived deal), or drop it.`);\n }\n }\n break;\n }\n case \"row_action\":\n if (!needTable(extra.table)) break;\n if (!extra.name?.trim()) say(`${at}.name`, \"Name the button the way the staff would say it.\");\n if (extra.actionKind === \"update\") {\n if (!extra.steps?.length) say(`${at}.steps`, \"An update action writes at least one field.\");\n for (const step of extra.steps ?? []) {\n const f = fieldOf(extra.table, step.field);\n if (!f) say(`${at}.steps`, `It writes \"${step.field}\", which \"${extra.table}\" does not declare.`);\n else if (step.set === \"value\" && f.choices?.length && typeof step.value === \"string\" && !f.choices.includes(step.value)) say(`${at}.steps`, `\"${step.value}\" is not one of \"${step.field}\"'s choices.`);\n }\n } else if (!extra.prompt?.trim()) say(`${at}.prompt`, \"An agent action says what the record chat opens with.\");\n break;\n case \"automation\":\n if (needTable(extra.when.table, \"when.table\") && extra.when.field && !fieldOf(extra.when.table, extra.when.field)) say(`${at}.when.field`, `\"${extra.when.table}\" does not declare a field \"${extra.when.field}\".`);\n if (!extra.then?.trim()) say(`${at}.then`, \"Say what happens, in the business's words.\");\n break;\n default:\n say(at, `\"${(extra as { kind: string }).kind}\" is not an extra a template can carry.`);\n }\n });\n\n // ── the agent: snapshot, variables, and Q6 with the store's semantics ────────\n const agent = spec.agent;\n if (!agent) say(\"agent\", \"Every template ships one agent: a copy of a platform agent with its variables bound to these tables.\");\n else {\n const snap = options.agents;\n const row = snap?.find((a) => a.id === agent.platformAgent?.id);\n if (!snap) say(\"agent.platformAgent\", \"No agent catalogue snapshot was given, so the agent could not be checked (pass templates/AGENTS.snapshot.json).\");\n else if (!row) say(\"agent.platformAgent\", `\"${agent.platformAgent?.id}\" is not in the agent catalogue snapshot.`);\n else if (row.name !== agent.platformAgent.name) say(\"agent.platformAgent\", `The snapshot calls ${row.id} \"${row.name}\", not \"${agent.platformAgent.name}\".`);\n if (agent.platformAgent?.id !== DEFAULT_TEMPLATE_AGENT.id && (agent.agentReason?.trim().split(/\\s+/).length ?? 0) < 8) {\n say(\"agent.platformAgent\", `A template's agent is \"${DEFAULT_TEMPLATE_AGENT.name}\" (${DEFAULT_TEMPLATE_AGENT.id}); say in agentReason, in a full sentence of at least eight words, why this one needs \"${agent.platformAgent?.name}\" instead.`);\n }\n if (!agent.variables?.length) say(\"agent.variables\", \"An agent without variables is not an agent: bind at least one to a table.\");\n agent.variables?.forEach((v, vi) => {\n if (!byToken.has(v.table)) say(`agent.variables[${vi}]`, `It binds \"${v.name}\" to \"${v.table}\", which this template does not declare.`);\n if (row && !row.variables.includes(v.name)) say(`agent.variables[${vi}]`, `\"${row.name}\" has no variable \"${v.name}\"; its variables are: ${row.variables.join(\", \") || \"(none)\"}.`);\n });\n const qq = agent.question;\n if (!qq?.ask?.trim().endsWith(\"?\")) say(\"agent.question.ask\", \"Write the question a person would really type, ending in a question mark.\");\n if (!qq?.whyItMatters?.trim()) say(\"agent.question.whyItMatters\", \"Say what the owner does differently depending on the answer.\");\n const qt = qq?.expect ? byToken.get(qq.expect.table) : undefined;\n if (!qt) say(\"agent.question.expect.table\", `The answer is read from \"${qq?.expect?.table}\", which this template does not declare.`);\n else {\n const m = qq.expect.measure;\n if (![\"count\", \"sum\", \"avg\", \"min\", \"max\"].includes(m.op)) say(\"agent.question.expect.measure\", \"The scripted question is a count, sum, average, lowest or highest.\");\n if (m.op !== \"count\") {\n const f = m.key ? fieldOf(qt.token, m.key) : undefined;\n if (!f) say(\"agent.question.expect.measure\", `A ${m.op} names a field of \"${qt.token}\".`);\n else if (!agentReads(qt.token, f)) say(\"agent.question.expect.measure\", `The agent cannot read \"${f.label}\", so it can never answer a question about it.`);\n else if (isComputed(f)) {\n const w = withComputed(qt.token, f.key, qt.rows.map((r) => ({ key: r.key, values: r.values })));\n if (\"why\" in w) say(\"agent.question.expect.measure\", `${w.why}; ask about a stored field, a lookup, or + − × ÷ / DATEDIFF formula.`);\n }\n }\n const filter = qq.expect.filter;\n if (m.op === \"count\" && !Object.keys(filter ?? {}).length) say(\"agent.question.expect.filter\", \"\\\"How many rows are there\\\" teaches nothing; filter the count to a real question.\");\n for (const [key, want] of Object.entries(filter ?? {})) {\n const f = fieldOf(qt.token, key);\n if (!f) {\n say(\"agent.question.expect.filter\", `It filters on \"${key}\", which \"${qt.token}\" does not declare.`);\n continue;\n }\n if (!agentReads(qt.token, f)) say(\"agent.question.expect.filter\", `The agent cannot read \"${f.label}\", so it cannot filter by it.`);\n // custom.record_filter_sql reads a worked-out column the way the record read does\n // (agg_field_value_sql), so a lookup filters the store's way; the gate mirrors lookups.\n if (isComputed(f) && f.parityType !== \"lookup\") say(\"agent.question.expect.filter\", `\"${f.label}\" is computed by the store (${f.parityType}); filter on a stored field or a lookup.`);\n const rawWant = raw.agent?.question?.expect?.filter?.[key];\n if (rawWant !== null && typeof rawWant === \"object\") {\n for (const [k, bound] of Object.entries(rawWant as Record<string, unknown>)) {\n if (typeof bound !== \"string\" || !relativeHasTime(bound)) {\n say(\"agent.question.expect.filter\", `The window's ${k} is \"${String(bound)}\". Write it as a relative token with a time (\"@today-7d 00:00\"): an absolute bound goes stale, and a bare date is read in the server's zone, not the business's.`);\n }\n }\n }\n if (f.multi || f.parityType === \"multi_select\" || isRelation(f)) say(\"agent.question.expect.filter\", `\"${f.label}\" holds a list or a link; the store compares its whole stored text, so it cannot be a filter here.`);\n if (want !== null && typeof want === \"object\") {\n if (!isDate(f)) say(\"agent.question.expect.filter\", `A window filters a date; \"${f.label}\" is not one.`);\n for (const k of Object.keys(want)) if (k !== \"from\" && k !== \"to\") say(\"agent.question.expect.filter\", `\"${k}\" is not part of a window (from, to).`);\n }\n }\n const seed = qt.rows.map((r) => ({ key: r.key, values: r.values }));\n if (filter && Object.keys(filter).length && seed.length) {\n const share = (storeAggregate(seed, { op: \"count\" }, filter, tz) as { value: number }).value / seed.length;\n if (share >= 0.9) say(\"agent.question.expect.filter\", `The filter keeps ${Math.round(share * 100)}% of the rows, so the question is really \"how many are there\"; ask about a real slice.`);\n }\n const seedC = withComputedKeys(qt.token, [m.key, ...Object.keys(filter ?? {})], seed);\n if (\"why\" in seedC && Object.keys(filter ?? {}).some((k) => fieldOf(qt.token, k)?.parityType === \"lookup\")) say(\"agent.question.expect.filter\", `${seedC.why}.`);\n const outcome = storeAggregate(\"rows\" in seedC ? seedC.rows : seed, m, filter, tz);\n if (!outcome.ok) say(\"agent.question.expect.answer\", outcome.says);\n else if (outcome.value === null || outcome.value === 0) say(\"agent.question.expect.answer\", `The seed rows answer ${outcome.value === null ? \"nothing (null)\" : \"0\"}; ask a question whose answer is a real number.`);\n else if (!outcome.exact) say(\"agent.question.expect.answer\", \"The answer does not come out exact; ask a question whose answer is a whole decimal.\");\n else if (!sameNumber(qq.expect.answer, outcome.value)) {\n say(\"agent.question.expect.answer\", `The seed rows answer ${outcome.value}, but the file says ${qq.expect.answer}. The scripted answer must equal custom.record_aggregate exactly.`);\n }\n if (!qq.expect.unit?.trim()) say(\"agent.question.expect.unit\", \"Say what the number is: USD, visits, days.\");\n }\n }\n\n // ── Kits → Template merge: optional full bindings, extra agents, workflows, guide (./extras) ──\n for (const p of extrasProblems(raw, options.agents)) say(p.at, p.says);\n\n // ── the walk: simulated over the seed, every step non-vacuous ───────────────\n const state = new Map<string, SeedRow[]>(tables.map((t) => [t.token, t.rows.map((r) => ({ key: r.key, values: { ...r.values } }))]));\n const state0 = new Map<string, SeedRow[]>(tables.map((t) => [t.token, t.rows.map((r) => ({ key: r.key, values: r.values }))]));\n const rowIn = (table: string, key: string) => state.get(table)?.find((r) => r.key === key);\n const surfaceRows = (token: string): number | null => {\n const view = views.find((v) => v.token === token);\n if (view) return (state.get(view.table) ?? []).filter((r) => !r.archived && viewMatches(r, view, tz)).length;\n const s = surfaces.get(token);\n return s?.table ? (state.get(s.table) ?? []).filter((r) => !r.archived).length : null;\n };\n const walkLen = spec.walk?.length ?? 0;\n if (walkLen !== 3 && walkLen !== 4) say(\"walk\", \"The teaching card is three steps, plus an optional fourth that asks the agent.\");\n if (walkLen === 4 && spec.walk?.[3]?.action?.kind !== \"ask_agent\") say(\"walk[3]\", \"A fourth step is only ever the question to the agent (ask_agent).\");\n // ── status implies fields (statusImplies), on seed rows and after every walk change ──\n const coherent = (table: string, row: { key: string; values: Record<string, unknown> }, at: string) => {\n // A formula over stored columns is read the store's way; everything else is the stored value.\n const val = (k: string): unknown => {\n const f = fieldOf(table, k);\n if (f?.parityType === \"formula\") {\n const c = computedOf(table, f, row);\n return c.ok ? c.v : undefined;\n }\n return row.values?.[k];\n };\n for (const rule of byToken.get(table)?.statusImplies ?? []) {\n const st = storeText(row.values?.[rule.field]) ?? \"\";\n // A field a later stage reserves is empty while the row is still earlier and not finished.\n const order = fieldOf(table, rule.field)?.choices ?? [];\n const firstWhen = Math.min(...rule.when.map((w) => order.indexOf(w)).filter((n) => n >= 0));\n const here = order.indexOf(st);\n if (here >= 0 && Number.isFinite(firstWhen) && here < firstWhen && !TERMINAL_STAGE.test(st)) {\n for (const k of rule.filled ?? []) {\n // Only a date or a mark records that the stage happened; amounts and choices build up before it.\n if (!/^(?:datetime|date|checkbox|signature|attachment)$/.test(fieldOf(table, k)?.parityType ?? \"\")) continue;\n // An unticked box records nothing: only a ticked one says the stage happened.\n const v = row.values?.[k];\n if (fieldOf(table, k)?.parityType === \"checkbox\" ? v === true || v === \"true\" : filled(v)) say(at, `\"${row.key}\" is ${st}, but already has \"${fieldOf(table, k)?.label ?? k}\", which only a ${rule.when.join(\"/\")} record carries. Leave it empty until the record gets there.`);\n }\n }\n if (!rule.when.includes(st)) continue;\n for (const k of rule.filled ?? []) if (!filled(val(k))) say(at, `\"${row.key}\" is ${st}, so \"${fieldOf(table, k)?.label ?? k}\" is filled; it is empty.`);\n for (const [k, v] of Object.entries(rule.equals ?? {})) {\n const got = val(k) ?? null;\n const same = sameJson(got, v) || (typeof v === \"number\" && parseNumeric(storeText(got) ?? \"\") !== null && qCmp(parseNumeric(storeText(got) ?? \"\")!, parseNumeric(String(v))!) === 0);\n if (!same) say(at, `\"${row.key}\" is ${st}, so \"${fieldOf(table, k)?.label ?? k}\" is ${JSON.stringify(v)}; it is ${JSON.stringify(got)}.`);\n }\n }\n };\n const TERMINAL_STEMS: Array<[RegExp, RegExp]> = [\n [/^paid$/i, /(^|_)(paid|balance)(_|$)/],\n [/^signed$/i, /(^|_)(signed|signature)(_|$)/],\n [/^ordered$/i, /(^|_)ordered(_|$)/],\n [/^completed?$/i, /(^|_)completed?(_|$)/],\n [/^closed$/i, /(^|_)closed(_|$)/],\n [/^issued$/i, /(^|_)issued(_|$)/],\n [/^shipped$/i, /(^|_)shipped(_|$)/],\n [/^delivered$/i, /(^|_)delivered(_|$)/],\n [/^received$/i, /(^|_)received(_|$)/],\n [/^approved$/i, /(^|_)approved(_|$)/],\n [/^sent$/i, /(^|_)sent(_|$)/],\n ];\n for (const t of own) {\n for (const rule of t.statusImplies ?? []) {\n const sf = fieldOf(t.token, rule.field);\n if (!sf?.choices?.length) say(`tables (${t.token}).statusImplies`, `\"${rule.field}\" is not a choice field of \"${t.token}\".`);\n for (const w of rule.when) if (sf?.choices && !sf.choices.includes(w)) say(`tables (${t.token}).statusImplies`, `\"${w}\" is not one of \"${rule.field}\"'s choices.`);\n for (const k of [...(rule.filled ?? []), ...Object.keys(rule.equals ?? {})]) if (!fieldOf(t.token, k)) say(`tables (${t.token}).statusImplies`, `\"${k}\" is not a field of \"${t.token}\".`);\n }\n for (const r of t.rows) coherent(t.token, r, `tables (${t.token}).rows (${r.key})`);\n const statusField = t.fields.find((f) => isChoice(f) && /(^|_)(status|stage)$/.test(f.key));\n for (const c of statusField?.choices ?? []) {\n const stem = TERMINAL_STEMS.find(([word]) => word.test(c.trim()));\n if (!stem) continue;\n const named = t.fields.filter((f) => f.key !== statusField!.key && stem[1].test(f.key));\n const declared = (t.statusImplies ?? []).some((r) => r.field === statusField!.key && r.when.includes(c));\n if (named.length && !declared) say(`tables (${t.token}).statusImplies`, `\"${c}\" is a status and \"${t.token}\" has ${named.map((f) => `\"${f.label}\"`).join(\", \")}; say what \"${c}\" implies about ${named.length === 1 ? \"it\" : \"them\"} (statusImplies), so a ${c} row can never leave ${named.length === 1 ? \"it\" : \"them\"} empty or wrong.`);\n }\n }\n\n const refWeek = [0, 1, 2, 3, 4, 5, 6].map((i) => shiftDays(TEMPLATE_REFERENCE_DATE, i));\n /** The template's own cross-table rules (statusAgrees, withinParent, childDates) over the walk's current rows. */\n const crossBreaks = (): Map<string, string> => {\n const out = new Map<string, string>();\n const live = (token: string) => (state.get(token) ?? []).filter((r) => !r.archived);\n const day = (v: unknown) => {\n const t = storeText(v);\n return t?.startsWith(\"@\") ? (resolveDateToken(t, TEMPLATE_REFERENCE_DATE, tz) ?? \"\").slice(0, 10) || null : dayOfMoment(v);\n };\n const name = (token: string, r: SeedRow) => storeText(r.values?.[byToken.get(token)?.titleField ?? \"\"]) ?? r.key;\n for (const t of own) {\n const parent = (relation: string, r: SeedRow) => {\n const target = fieldOf(t.token, relation)?.relationTarget;\n const ref = r.values?.[relation];\n const pk = Array.isArray(ref) ? ref[0] : ref;\n return target ? { target, prow: live(target).find((x) => x.key === pk) } : { target: \"\", prow: undefined };\n };\n for (const r of live(t.token)) {\n for (const a of t.statusAgrees ?? []) {\n const st = storeText(r.values?.[a.field]) ?? \"\";\n if (!a.childStatus.includes(st)) continue;\n const { target, prow } = parent(a.relation, r);\n const ps = prow ? storeText(prow.values?.[a.parentField]) ?? \"\" : null;\n if (prow && ps !== null && !a.parentStatus.includes(ps)) out.set(`sa|${t.token}|${r.key}|${a.relation}|${st}|${ps}`, `\"${name(t.token, r)}\" is ${st}, so \"${name(target, prow)}\" should be ${a.parentStatus.join(\" or \")}, but it is \"${ps}\".`);\n }\n for (const w of t.withinParent ?? []) {\n if (w.unless && w.unless.values.includes(storeText(r.values?.[w.unless.field]) ?? \"\")) continue;\n const { target, prow } = parent(w.relation, r);\n const c = parseNumeric(storeText(r.values?.[w.field]) ?? \"\");\n const pv = prow ? parseNumeric(storeText(prow.values?.[w.parentField]) ?? \"\") : null;\n if (prow && c && pv && (w.op === \"<=\" ? qCmp(c, pv) > 0 : qCmp(c, pv) < 0)) out.set(`wp|${t.token}|${r.key}|${w.field}|${storeText(r.values?.[w.field])}|${storeText(prow.values?.[w.parentField])}`, `\"${name(t.token, r)}\" has ${w.field} ${storeText(r.values?.[w.field])}, ${w.op === \"<=\" ? \"above\" : \"below\"} \"${name(target, prow)}\"'s ${w.parentField} (${storeText(prow.values?.[w.parentField])}).`);\n }\n for (const d of t.childDates ?? []) {\n const { target, prow } = parent(d.relation, r);\n const c = day(r.values?.[d.field]);\n const pd = prow ? day(prow.values?.[d.parentField]) : null;\n if (prow && c && pd && c < pd) out.set(`cd|${t.token}|${r.key}|${d.field}|${c}|${pd}`, `\"${name(t.token, r)}\" has ${d.field} ${c}, before \"${name(target, prow)}\"'s ${d.parentField} ${pd}.`);\n }\n // A stage that needs a linked child has one.\n for (const rules of [...stageRules.values()].filter((x) => x.table === t.token)) {\n const st = storeText(r.values?.[rules.stageField]) ?? \"\";\n const need = rules.requiresChild?.[st];\n if (!need) continue;\n const kids = live(need.table).filter((c) => {\n const ref = c.values?.[need.relation];\n const linked = Array.isArray(ref) ? ref.includes(r.key) : ref === r.key;\n return linked && (!need.field || (need.in ?? []).includes(storeText(c.values?.[need.field]) ?? \"\"));\n });\n if (kids.length < (need.min ?? 1)) out.set(`rc|${t.token}|${r.key}|${st}|${kids.length}`, `\"${name(t.token, r)}\" is ${st}, which needs ${need.min ?? 1} linked ${byToken.get(need.table)?.labelSingular.toLowerCase() ?? need.table}${need.field ? ` in ${(need.in ?? []).join(\"/\")}` : \"\"}; it has ${kids.length}.`);\n }\n // A relation whose record must hold a valid credential on this row's date.\n for (const f of t.fields.filter((x) => x.eligible)) {\n const el = f.eligible!;\n const ref = r.values?.[f.key];\n const on = day(r.values?.[el.onDate]);\n for (const who of (Array.isArray(ref) ? ref : [ref]).filter((x) => x !== undefined && x !== null && x !== \"\")) {\n if (!on) continue;\n const ok = live(el.table).some(\n (c) =>\n (Array.isArray(c.values?.[el.relation]) ? (c.values?.[el.relation] as unknown[]).includes(who) : c.values?.[el.relation] === who) &&\n Object.entries(el.where ?? {}).every(([k, v]) => storeText(c.values?.[k]) === v) &&\n (day(c.values?.[el.until]) ?? \"\") >= on,\n );\n if (!ok) {\n const target = fieldOf(t.token, f.key)?.relationTarget ?? \"\";\n const prow = live(target).find((x) => x.key === who);\n out.set(`el|${t.token}|${r.key}|${f.key}|${String(who)}|${on}`, `\"${name(t.token, r)}\" (${on}) has ${f.label.toLowerCase()} \"${prow ? name(target, prow) : String(who)}\", who holds no ${byToken.get(el.table)?.labelSingular.toLowerCase() ?? el.table}${el.where ? ` (${Object.values(el.where).join(\", \")})` : \"\"} valid on that day.`);\n }\n }\n }\n }\n }\n return out;\n };\n const crossSeen = new Set(crossBreaks().keys());\n // The seed itself keeps the linked-child and eligibility rules (the walk is judged below).\n for (const [k, msg] of crossBreaks()) {\n const [kind, table, row] = k.split(\"|\");\n if (kind === \"rc\" || kind === \"el\") say(`tables (${table}).rows (${row})`, msg);\n }\n /** One row's stage move (a `move` step, or one row of a grouped `moves` step): its own table's rules. */\n /** `rawSet`: the step's `set` as WRITTEN (relative tokens), so the date rule resolves it per install weekday. */\n const moveOne = (a: WalkMove, at: string, rawSet?: Record<string, unknown>): boolean => {\n const row = rowIn(a.table, a.row);\n const f = fieldOf(a.table, a.field);\n if (!row || row.archived) say(`${at}.action`, `There is no live row \"${a.row}\" in \"${a.table}\".`);\n if (!f) say(`${at}.action`, `\"${a.table}\" does not declare a field \"${a.field}\".`);\n if (!row || !f) return false;\n if (!f.choices?.includes(a.to)) {\n say(`${at}.action`, `\"${a.to}\" is not one of \"${a.field}\"'s choices.`);\n return false;\n }\n const rules = stageRules.get(`${a.table}.${a.field}`);\n if (!rules) say(`${at}.action`, `\"${a.table}.${a.field}\" has no stage rules, so the store has no board to move it on (pipeline_move: \"no stage column\"). Move along a declared stage field, or edit the value.`);\n const from = storeText(row.values[a.field]);\n if (rules?.transitions?.length && !rules.transitions.some((t) => t.from === from && t.to === a.to)) {\n say(`${at}.action`, `The template's own stage rules do not allow \"${from}\" → \"${a.to}\".`);\n }\n // Fields that land with the move (pipeline_move's p_also): the same checks an edit gets.\n const landed: Record<string, unknown> = { ...row.values };\n for (const [key, value] of Object.entries(a.set ?? {})) {\n const sf = fieldOf(a.table, key);\n if (!sf) {\n say(`${at}.action`, `\"${a.table}\" does not declare a field \"${key}\".`);\n continue;\n }\n if (key === a.field) say(`${at}.action`, `\"${key}\" is the stage the move sets; leave it out of set.`);\n if (isComputed(sf)) say(`${at}.action`, `\"${sf.label}\" is computed by the store (${sf.parityType}); nobody types into it.`);\n const broken = ruleBreak(sf, value);\n if (broken) say(`${at}.action`, `${broken} The store would refuse this move.`);\n landed[key] = value;\n }\n for (const k of rules?.requires?.[a.to] ?? []) if (!filled(landed[k])) say(`${at}.action`, `Landing in \"${a.to}\" needs \"${k}\" filled, and \"${a.row}\" leaves it empty — set it in the move, or the store refuses it.`);\n const limit = rules?.limits?.[a.to];\n if (limit !== undefined) {\n const there = (state.get(a.table) ?? []).filter((r) => !r.archived && r.key !== a.row && storeText(r.values[a.field]) === a.to).length;\n if (there + 1 > limit) say(`${at}.action`, `\"${a.to}\" holds at most ${limit}; the move would make ${there + 1}.`);\n }\n // The stage's own date rule holds after the move, on every install weekday.\n const rule = rules?.dateField ? rules.stageDates?.[a.to] : undefined;\n if (rule === \"none\" && rules?.dateField) {\n const landedDate = a.set && rules.dateField in a.set ? a.set[rules.dateField] : row.values?.[rules.dateField];\n if (filled(landedDate)) say(`${at}.action`, `\"${a.to}\" is a stage with no date yet, and \"${a.row}\" carries a ${rules.dateField}. Move a row without one.`);\n } else if (rule && rule !== \"any\" && rules?.dateField) {\n const rawDate =\n a.set && rules.dateField in a.set\n ? (rawSet && rules.dateField in rawSet ? rawSet[rules.dateField] : a.set[rules.dateField])\n : tablesRaw.find((t) => t.token === a.table)?.rows.find((r) => r.key === a.row)?.values?.[rules.dateField];\n const off: string[] = [];\n for (const day of refWeek) {\n const d = typeof rawDate === \"string\" ? (resolveDateToken(rawDate, day, tz) ?? rawDate).slice(0, 10) : null;\n if (d && !(rule === \"past\" ? d <= day : rule === \"future\" ? d >= day : d === day)) off.push(WEEKDAY_NAMES[dayOfWeek(day)] ?? day);\n }\n if (off.length) say(`${at}.action`, `Moving \"${a.row}\" to \"${a.to}\" breaks that stage's date rule (its ${rules.dateField} must be ${rule === \"today\" ? \"today\" : `in the ${rule}`}) when installed on a ${off.join(\", \")}. Move a row whose date fits.`);\n }\n Object.assign(row.values, landed, { [a.field]: a.to });\n coherent(a.table, row, `${at}.action`);\n for (const pair of byToken.get(a.table)?.before ?? []) {\n const [x, y] = pair.map((k) => (k.includes(\".\") ? null : dayOfMoment(row.values[k])));\n if (x && y && x > y) say(`${at}.action`, `After this move ${pair[0]} (${x}) comes after ${pair[1]} (${y}).`);\n }\n for (const [k, needs] of inferredImplies(a.table, a.field)) {\n if (k === a.to) for (const fk of needs) if (!filled(row.values[fk])) say(`${at}.action`, `Every \"${a.to}\" row has \"${fieldOf(a.table, fk)?.label ?? fk}\", and no earlier one does; set it in the move.`);\n }\n return true;\n };\n\n const stepsSeen = new Set<string>();\n let showsS5 = false;\n const archivedRows = new Set<string>();\n (spec.walk ?? []).forEach((step, i) => {\n const at = `walk[${i}]`;\n if (!step.says?.trim()) say(`${at}.says`, \"Say the step in plain words — 'Drag Rosa to Scheduled'.\");\n const a: WalkAction | undefined = step.action;\n const sig = JSON.stringify(a);\n if (stepsSeen.has(sig)) say(`${at}.action`, \"This step repeats an earlier one; each step teaches something new.\");\n stepsSeen.add(sig);\n switch (a?.kind) {\n case \"open\":\n if (!surfaces.has(a.surface)) say(`${at}.action`, `It opens \"${a.surface}\", which is no view, form or extra of this template.`);\n break;\n case \"move\": {\n if (!moveOne(a, at, (raw.walk?.[i]?.action as { set?: Record<string, unknown> } | undefined)?.set)) break;\n const e = step.expect;\n if (!(e?.kind === \"value\" && e.table === a.table && e.row === a.row && e.field === a.field && sameJson(e.equals, a.to))) {\n say(`${at}.expect`, \"A move step asserts where the row it moved landed (a value on that row and field).\");\n }\n break;\n }\n case \"moves\": {\n const group = a.moves ?? [];\n if (group.length < 2 || group.length > 3) say(`${at}.action`, \"A grouped step moves 2 or 3 linked rows; one row is a plain move.\");\n if (new Set(group.map((m) => `${m.table}.${m.row}`)).size !== group.length) say(`${at}.action`, \"Each row moves once in a grouped step.\");\n group.forEach((m, mi) => moveOne(m, `${at}.moves[${mi}]`, (raw.walk?.[i]?.action as { moves?: WalkMove[] } | undefined)?.moves?.[mi]?.set));\n const e = step.expect;\n if (!(e?.kind === \"value\" && group.some((m) => e.table === m.table && e.row === m.row && e.field === m.field && sameJson(e.equals, m.to)))) {\n say(`${at}.expect`, \"A grouped step asserts where one of its rows landed (a value on that row and field).\");\n }\n break;\n }\n case \"edit\": {\n const row = rowIn(a.table, a.row);\n if (!row || row.archived) {\n say(`${at}.action`, `There is no live row \"${a.row}\" in \"${a.table}\".`);\n break;\n }\n const writes: Array<[string, unknown]> = a.set ? Object.entries(a.set) : a.field ? [[a.field, a.value]] : [];\n if (!writes.length) say(`${at}.action`, \"An edit names what it writes: field + value, or set: {field: value, …}.\");\n let changed = false;\n for (const [key, value] of writes) {\n const f = fieldOf(a.table, key);\n if (!f) {\n say(`${at}.action`, `\"${a.table}\" does not declare a field \"${key}\".`);\n continue;\n }\n if ([...stageRules.values()].some((r) => r.table === a.table && r.stageField === key)) {\n say(`${at}.action`, `\"${key}\" is the pipeline's stage; a record changes stage only by a move, which the stage rules check.`);\n }\n if (isComputed(f)) say(`${at}.action`, `\"${f.label}\" is computed by the store (${f.parityType}); nobody types into it.`);\n if (!sameJson(row.values[key], value)) changed = true;\n const broken = ruleBreak(f, value);\n if (broken) say(`${at}.action`, `${broken} The store would refuse this edit.`);\n row.values[key] = value;\n }\n coherent(a.table, row, `${at}.action`);\n if (writes.length && !changed) say(`${at}.action`, `\"${a.row}\" already holds what this edit writes; an edit that changes nothing teaches nothing.`);\n // The whole result stays coherent: every written choice is a choice, every date pair still holds.\n for (const pair of byToken.get(a.table)?.before ?? []) {\n const [x, y] = pair.map((k) => (k.includes(\".\") ? null : dayOfMoment(row.values[k])));\n if (x && y && x > y) say(`${at}.action`, `After this edit ${pair[0]} (${x}) comes after ${pair[1]} (${y}).`);\n }\n const e = step.expect;\n if (!(e?.kind === \"value\" && e.table === a.table && e.row === a.row && writes.some(([k, v]) => k === e.field && sameJson(e.equals, v)))) {\n say(`${at}.expect`, \"An edit step asserts a value it wrote, on the row it wrote it.\");\n }\n break;\n }\n case \"submit_form\": {\n const form = forms.find((f) => f.token === a.form);\n if (!form) {\n say(`${at}.action`, `It submits \"${a.form}\", which this template does not declare.`);\n break;\n }\n for (const key of Object.keys(a.values ?? {})) if (!form.fields.some((ff) => ff.fieldKey === key)) say(`${at}.action`, `The form \"${a.form}\" does not ask for \"${key}\".`);\n for (const ff of form.fields) if (ff.required && !filled(a.values?.[ff.fieldKey])) say(`${at}.action`, `The form requires \"${ff.fieldKey}\", and the step leaves it empty.`);\n // A stored row takes every column default the form did not ask (the store fills them on write — a new\n // request starts \"New\"), so the walk counts the submitted row the way the store will.\n const defaults: Record<string, unknown> = {};\n for (const f of byToken.get(form.table)?.fields ?? []) if (f.default !== undefined && !isComputed(f)) defaults[f.key] = f.default;\n const submitted = { key: `walk-${i}`, values: { ...defaults, ...a.values } };\n coherent(form.table, submitted, `${at}.action`);\n state.get(form.table)?.push(submitted);\n break;\n }\n case \"archive\":\n case \"restore\": {\n const row = rowIn(a.table, a.row);\n if (!row) say(`${at}.action`, `There is no row \"${a.row}\" in \"${a.table}\".`);\n else if (a.kind === \"archive\") {\n if (row.archived) say(`${at}.action`, `\"${a.row}\" is already archived.`);\n row.archived = true;\n archivedRows.add(`${a.table}.${a.row}`);\n } else {\n if (!row.archived) say(`${at}.action`, `\"${a.row}\" is not archived, so there is nothing to restore.`);\n if (archivedRows.has(`${a.table}.${a.row}`)) showsS5 = true;\n row.archived = false;\n }\n const e = step.expect;\n if (!(e?.kind === \"archived\" && e.table === a.table && e.row === a.row && e.equals === (a.kind === \"archive\"))) {\n say(`${at}.expect`, `An ${a.kind} step asserts that the row it acted on is ${a.kind === \"archive\" ? \"archived\" : \"back\"} ({kind: \"archived\", row: \"${a.row}\"}).`);\n }\n break;\n }\n case \"import\": {\n const table = byToken.get(a.table);\n if (!table) {\n say(`${at}.action`, `It imports into \"${a.table}\", which this template does not declare.`);\n break;\n }\n const key = fieldOf(a.table, a.dedupeKey);\n if (!key) say(`${at}.action.dedupeKey`, `This table has no column called \"${a.dedupeKey}\", so it cannot be what makes a row the same row.`);\n else if (!(key.rules ?? []).some((r) => r.kind === \"unique\")) say(`${at}.action.dedupeKey`, `\"${key.label}\" is the upsert key, so it carries a unique rule.`);\n if (!a.sourceName?.trim()) say(`${at}.action.sourceName`, \"Name the file as a person would: 'October customer list.csv'.\");\n if (!a.columns?.includes(a.dedupeKey)) say(`${at}.action.columns`, \"The file carries the upsert key as a column.\");\n for (const c of a.columns ?? []) if (!fieldOf(a.table, c)) say(`${at}.action.columns`, `The column \"${c}\" maps to no field of \"${a.table}\".`);\n let updates = 0;\n let adds = 0;\n const ki = a.columns?.indexOf(a.dedupeKey) ?? -1;\n (a.rows ?? []).forEach((cells, ri) => {\n if (cells.length !== a.columns.length) return say(`${at}.action.rows[${ri}]`, `The row has ${cells.length} cells under ${a.columns.length} columns.`);\n const values: Record<string, unknown> = {};\n a.columns.forEach((c, ci) => {\n const f = fieldOf(a.table, c);\n const cell = cells[ci] ?? \"\";\n // A person pastes the linked record's NAME; the store matches it to the record's title.\n if (f && isRelation(f) && f.relationTarget && cell) {\n const target = byToken.get(f.relationTarget);\n const byTitle = target?.rows.some((tr) => (storeText(tr.values?.[target.titleField]) ?? \"\").trim() === cell.trim());\n const isKey = target?.rows.some((tr) => tr.key === cell.trim());\n if (isKey && !byTitle) say(`${at}.action.rows[${ri}]`, `\"${cell}\" is a seed key; an import file holds what a person types — the ${target?.labelSingular.toLowerCase()}'s name (\"${storeText(target?.rows.find((tr) => tr.key === cell.trim())?.values?.[target.titleField])}\").`);\n else if (!byTitle) say(`${at}.action.rows[${ri}]`, `\"${cell}\" names no ${target?.labelSingular.toLowerCase() ?? \"record\"}; the store would refuse the row.`);\n }\n if (f?.choices?.length && cell && !f.choices.includes(cell)) say(`${at}.action.rows[${ri}]`, `\"${cell}\" is not one of \"${c}\"'s choices.`);\n // The store matches the pasted name to the record; the simulated row holds that record.\n const linked = f && isRelation(f) && f.relationTarget && cell ? byToken.get(f.relationTarget)?.rows.find((tr) => (storeText(tr.values?.[byToken.get(f.relationTarget!)!.titleField]) ?? \"\").trim() === cell.trim()) : undefined;\n values[c] = linked ? linked.key : f && isNumber(f) && parseNumeric(cell) ? Number(cell) : cell;\n });\n // custom.io_import_rows: the key matches a LIVE row's raw value, exactly, trimmed only.\n const keyValue = (cells[ki] ?? \"\").trim();\n const sameKey = (r: SeedRow) => (storeText(r.values[a.dedupeKey]) ?? \"\").trim() === keyValue;\n if ((state.get(a.table) ?? []).some((r) => r.archived && sameKey(r))) {\n say(`${at}.action.rows[${ri}]`, `\"${keyValue}\" belongs to an archived row; the store would add a second one beside it. Restore it first, or import a different key.`);\n }\n const existing = (state.get(a.table) ?? []).find((r) => !r.archived && sameKey(r));\n const rules = [...stageRules.values()].find((r) => r.table === a.table);\n if (existing) {\n updates += 1;\n // An update that changes the stage is a move: the same transitions, requires and statusImplies.\n const from = rules ? storeText(existing.values[rules.stageField]) : null;\n const to = rules && a.columns.includes(rules.stageField) ? storeText(values[rules.stageField]) : null;\n Object.assign(existing.values, values);\n if (rules && to && to !== from) {\n if (rules.transitions?.length && !rules.transitions.some((t) => t.from === from && t.to === to)) say(`${at}.action.rows[${ri}]`, `\"${keyValue}\" goes \"${from}\" → \"${to}\", a move the stage rules do not allow.`);\n for (const k of rules.requires?.[to] ?? []) if (!filled(existing.values[k])) say(`${at}.action.rows[${ri}]`, `\"${keyValue}\" lands in \"${to}\", which needs \"${k}\" filled; the file leaves it empty.`);\n for (const [x, needs] of inferredImplies(a.table, rules.stageField)) if (x === to) for (const k of needs) if (!filled(existing.values[k])) say(`${at}.action.rows[${ri}]`, `\"${keyValue}\" lands in \"${to}\" without \"${fieldOf(a.table, k)?.label ?? k}\", which every \"${to}\" row has.`);\n }\n coherent(a.table, existing, `${at}.action.rows[${ri}]`);\n } else {\n // A child table whose every seed row links a parent: a new row links one too.\n for (const rf of table.fields.filter((f) => isRelation(f) && f.relationTarget && f.parityType !== \"attachment\" && !f.multi && (f.relationMax ?? 1) === 1 && own.some((p) => p.token === f.relationTarget))) {\n if (table.rows.length && table.rows.every((r) => filled(r.values?.[rf.key])) && !filled(values[rf.key])) {\n say(`${at}.action.rows[${ri}]`, `The new row \"${keyValue}\" has no \"${rf.label}\", and every other ${table.labelSingular.toLowerCase()} has one; add the column.`);\n }\n }\n adds += 1;\n // A new imported row takes the columns' defaults the file leaves out, as the store writes it.\n for (const f of table.fields) if (f.default !== undefined && !isComputed(f) && values[f.key] === undefined) values[f.key] = f.default;\n const added = { key: `walk-${i}-${ri}`, values };\n // A new row passes the same door a person's would: the stage it lands in and its status rules.\n const landed = rules ? storeText(values[rules.stageField]) : null;\n for (const k of landed ? (rules?.requires?.[landed] ?? []) : []) if (!filled(values[k])) say(`${at}.action.rows[${ri}]`, `The new row \"${keyValue}\" lands in \"${landed}\", which needs \"${k}\" filled; the store would refuse it.`);\n coherent(a.table, added, `${at}.action.rows[${ri}]`);\n state.get(a.table)?.push(added);\n }\n });\n {\n const e = step.expect;\n if (!((e?.kind === \"count\" || e?.kind === \"value\" || e?.kind === \"aggregate\") && e.table === a.table)) {\n say(`${at}.expect`, `An import asserts what it did to \"${a.table}\" (a count, a value or a total on that table).`);\n }\n }\n if (!updates || !adds) say(`${at}.action.rows`, `An upsert import shows both halves: rows that update a record already there (${updates}) and rows that add a new one (${adds}).`);\n else showsS5 = true;\n break;\n }\n case \"ask_agent\": {\n // The answer the store would give NOW — after the steps before it changed the data.\n const qe = agent?.question?.expect;\n const nowRows = qe ? withComputedKeys(qe.table, [qe.measure.key, ...Object.keys(qe.filter ?? {})], state.get(qe.table) ?? []) : null;\n const now = qe ? storeAggregate(nowRows && \"rows\" in nowRows ? nowRows.rows : state.get(qe.table) ?? [], qe.measure, qe.filter, tz) : null;\n const want = now && now.ok ? now.value : null;\n if (!(step.expect?.kind === \"agent_answer\" && want !== null && sameNumber(step.expect.equals, want))) {\n say(`${at}.expect`, `Asking the agent asserts the exact answer it must give at this point of the walk (${want}).`);\n }\n const changedBefore = (spec.walk ?? []).slice(0, i).some((w) => [\"move\", \"moves\", \"edit\", \"import\", \"archive\", \"restore\", \"submit_form\"].includes(w?.action?.kind ?? \"\"));\n if (changedBefore && qe && want !== null && sameNumber(want, qe.answer)) {\n say(`${at}`, `The steps before this one change nothing the question reads (the answer is still ${want}); ask about what the walk just did, so the person sees the cause and the effect.`);\n }\n if (/\\b(today|tonight|yesterday|this (?:week|month|year|morning)|last (?:week|month))\\b/i.test(step.says ?? \"\") && !Object.values(qe?.filter ?? {}).some((v) => v !== null && typeof v === \"object\")) {\n say(`${at}.says`, `\"${step.says}\" names a time span the question does not have (it reads all time); drop the time words or give the question a date window.`);\n }\n break;\n }\n default:\n say(`${at}.action`, \"Each step does one thing: open, move, edit, submit_form, archive, restore, import or ask_agent.\");\n }\n const e = step.expect;\n switch (e?.kind) {\n case \"renders\": {\n const view = views.find((v) => v.token === e.surface);\n const dateKey = view?.kind === \"calendar\" ? view.dateField : view?.kind === \"timeline\" ? view.startField : undefined;\n const SPAN = /\\b(?:next|this|coming|past|last)\\s+(?:\\w+\\s+)?(?:days?|weeks?|months?)\\b|\\btoday\\b|\\btomorrow\\b/i;\n if (dateKey && !e.within && SPAN.test(step.says ?? \"\")) {\n say(`${at}.expect`, `\"${step.says}\" names a span of time; give the expectation the same window (\"within\": {\"from\": \"@today\", \"to\": \"@today+3w\"}) so it is checked on every install day.`);\n }\n if (e.within) {\n if (!dateKey) say(`${at}.expect.within`, `\"${e.surface}\" is not a calendar or timeline, so it has no date window.`);\n else {\n const short: string[] = [];\n for (const day of refWeek) {\n const rs = resolveRelativeDates(raw, day);\n const v = rs.views.find((x) => x.token === e.surface)!;\n const w = resolveRelativeDates({ business: raw.business, within: e.within } as never, day) as unknown as { within: { from?: string; to?: string } };\n const rows = (allTables(rs).find((t) => t.token === v.table)?.rows ?? []).map((r) => ({ key: r.key, values: r.values }));\n const n0 = rows.filter((r) => viewMatches(r, { anyOf: v.anyOf, filters: { ...(v.filters ?? {}), [dateKey]: w.within as AggregateFilter } }, tz)).length;\n if (n0 < e.minItems) short.push(`${WEEKDAY_NAMES[dayOfWeek(day)]} (${n0})`);\n }\n if (short.length) say(`${at}.expect`, `\"${step.says}\" expects at least ${e.minItems} records in that window, but installed on a ${short.join(\", \")} it holds fewer. Seed the window honestly or lower the expectation.`);\n }\n }\n const n = surfaceRows(e.surface);\n if (n === null) say(`${at}.expect`, `It expects \"${e.surface}\" to render, which is no view, form or extra of this template.`);\n else if (!(e.minItems >= 1)) say(`${at}.expect`, \"A render step expects at least one record on screen.\");\n else if (n < e.minItems) say(`${at}.expect`, `\"${e.surface}\" would show ${n} records, fewer than the ${e.minItems} expected.`);\n break;\n }\n case \"count\":\n case \"aggregate\": {\n const rows = state.get(e.table);\n if (!rows) {\n say(`${at}.expect`, `It counts \"${e.table}\", which this template does not declare.`);\n break;\n }\n for (const key of Object.keys(e.where ?? {})) if (!fieldOf(e.table, key)) say(`${at}.expect`, `\"${e.table}\" does not declare \"${key}\".`);\n const measure: AggregateMeasure = e.kind === \"count\" ? { op: \"count\" } : e.measure;\n const rowsC = withComputed(e.table, measure.key, rows);\n if (\"why\" in rowsC) say(`${at}.expect`, `${rowsC.why}.`);\n const got = storeAggregate(\"rows\" in rowsC ? rowsC.rows : rows, measure, e.where, tz);\n if (!got.ok) say(`${at}.expect`, got.says);\n else if (!e.equals) say(`${at}.expect`, \"A step that expects nothing (0) asserts nothing.\");\n else if (got.value === null || !sameNumber(e.equals, got.value)) say(`${at}.expect`, `After this step the store would give ${got.value}, but the step expects ${e.equals}.`);\n break;\n }\n case \"value\": {\n const row = rowIn(e.table, e.row);\n if (!row) say(`${at}.expect`, `There is no row \"${e.row}\" in \"${e.table}\".`);\n else if (!fieldOf(e.table, e.field)) say(`${at}.expect`, `\"${e.table}\" does not declare a field \"${e.field}\".`);\n else if (!sameJson(row.values[e.field], e.equals)) say(`${at}.expect`, `After this step \"${e.field}\" holds ${JSON.stringify(row.values[e.field])}, not ${JSON.stringify(e.equals)}.`);\n break;\n }\n case \"agent_answer\":\n if (a?.kind !== \"ask_agent\") say(`${at}.expect`, \"An agent answer is expected only after the step asks the agent.\");\n break;\n case \"archived\": {\n const row = rowIn(e.table, e.row);\n if (!row) say(`${at}.expect`, `There is no row \"${e.row}\" in \"${e.table}\".`);\n else if (!!row.archived !== e.equals) say(`${at}.expect`, `After this step \"${e.row}\" is ${row.archived ? \"\" : \"not \"}archived.`);\n break;\n }\n default:\n say(`${at}.expect`, \"Each step asserts one thing: renders, count, value, aggregate or agent_answer.\");\n }\n // The step's end state keeps the template's own cross-table rules, not just this row's.\n for (const [k, msg] of crossBreaks()) {\n if (crossSeen.has(k)) continue;\n crossSeen.add(k);\n say(`${at}.action`, `After this step ${msg} Pick a row whose linked record already agrees, or move that record first.`);\n }\n });\n\n // ── foundation ──────────────────────────────────────────────────────────────\n (spec.foundation ?? []).forEach((f, i) => {\n if (!own.some((t) => t.token === f.table)) say(`foundation[${i}]`, `\"${f.table}\" is not a table of this template.`);\n if (!f.keptFor?.trim()) say(`foundation[${i}].keptFor`, \"Say what this day-one table is kept for.\");\n });\n\n // ── strengths and the taught feature are SHOWN, not claimed ─────────────────\n const kinds = new Set(extras.map((e) => e.kind));\n const viewKinds = new Set(views.map((v) => v.kind));\n // S3: the most front doors any ONE table has (form, booking, portal, digest).\n const doors = new Map<string, number>();\n const door = (t: string | undefined) => t && doors.set(t, (doors.get(t) ?? 0) + 1);\n for (const f of forms) door(f.table);\n for (const e of extras) {\n if (e.kind === \"booking\") door(e.table);\n if (e.kind === \"portal\") for (const pt of e.tables ?? []) door(pt.table);\n if (e.kind === \"digest\") door(views.find((v) => v.token === e.view)?.table);\n }\n const stageFieldsOf = new Set([...stageRules.values()].map((r) => `${r.table}.${r.stageField}`));\n const distinctDays = (table: string, key: string) => new Set((byToken.get(table)?.rows ?? []).map((r) => dayOfMoment(r.values?.[key])).filter(Boolean)).size;\n const imports = (spec.walk ?? []).some((s) => s?.action?.kind === \"import\");\n const asks = (spec.walk ?? []).some((s) => s?.action?.kind === \"ask_agent\");\n const entityRefs = fields.filter((f) => f.parityType === \"entity_reference\");\n const shows: Record<string, boolean> = {\n S1: governed,\n S2: !!agent?.question && asks,\n S3: Math.max(0, ...doors.values()) >= 2,\n S4: entityRefs.length > 0 && entityRefs.every((f) => (f.allowedTypes ?? []).length > 0 && (f.allowedTypes ?? []).every((k) => (ENTITY_REFERENCE_KINDS as readonly string[]).includes(k))),\n S5: showsS5,\n relations_rollups: hasLookupOrRollup,\n dimensions: (spec.dimensions ?? []).length > 0,\n kanban: views.some((v) => v.kind === \"kanban\" && stageFieldsOf.has(`${v.table}.${v.groupBy}`)),\n calendar: views.some((v) => v.kind === \"calendar\" && fieldOf(v.table, v.dateField)?.parityType === \"datetime\" && distinctDays(v.table, v.dateField) >= 5),\n timeline: viewKinds.has(\"timeline\"),\n gallery: views.some((v) => v.kind === \"gallery\" && fieldOf(v.table, v.coverField)?.parityType === \"attachment\"),\n forms: forms.some((f) => f.audience === \"public\"),\n bookings: kinds.has(\"booking\"),\n portals: kinds.has(\"portal\"),\n dashboards: [...honestCharts.values()].some((n) => n >= 2),\n drill_down: kinds.has(\"drill_down\"),\n agents: !!agent?.question && asks,\n field_governance: governed,\n import_upsert: imports && showsS5,\n checklists: kinds.has(\"checklist\"),\n documents_esign: extras.some((e) => e.kind === \"document\" && (byToken.get(e.table)?.fields ?? []).some((f) => f.parityType === \"signature\" || f.format === \"signature\")),\n };\n const HOW: Record<string, string> = {\n S2: \"an agent question and a walk step that asks it\",\n S3: \"two front doors (form, booking, portal, digest) on the same table\",\n S4: \"an entity_reference column whose allowedTypes are platform kinds\",\n S5: \"an import walk step that updates and adds, or archive then restore\",\n kanban: \"a kanban grouped by the stage field\",\n calendar: \"a calendar on a datetime field with seed dates on at least five days\",\n gallery: \"a gallery view whose cover is a file field\",\n forms: \"a public form\",\n dashboards: \"a dashboard with two honest charts\",\n agents: \"an agent question and a walk step that asks it\",\n import_upsert: \"an import walk step that updates and adds\",\n documents_esign: \"a document on a table that has a signature field\",\n };\n for (const s of spec.strengths ?? []) if (shows[s] === false) say(\"strengths\", `It claims ${s} but nothing in it shows ${s}${HOW[s] ? ` (${s} needs ${HOW[s]})` : \"\"}. Build the thing that shows it, or drop the claim.`);\n if (spec.teaches && shows[spec.teaches] === false) say(\"teaches\", `It teaches \"${spec.teaches}\" but carries nothing that shows it${HOW[spec.teaches] ? ` (it needs ${HOW[spec.teaches]})` : \"\"}.`);\n for (const f of entityRefs) for (const k of f.allowedTypes ?? []) {\n if (!(ENTITY_REFERENCE_KINDS as readonly string[]).includes(k)) say(`fields (${f.key}).allowedTypes`, `\"${k}\" is not a kind of platform thing a column can point at. Use one of the store's kinds (agent, note, workbook, project, party …).`);\n }\n\n // ── absolute (historical) dates never drive schedule ────────────────────────\n const scheduleUses: Array<[string, string, string]> = [];\n const use = (table: string | undefined, key: string | undefined, where: string) => {\n if (table && key) scheduleUses.push([table, key, where]);\n };\n for (const v of views) {\n if (v.kind === \"calendar\") use(v.table, v.dateField, `the calendar \"${v.name}\"`);\n if (v.kind === \"timeline\") {\n use(v.table, v.startField, `the timeline \"${v.name}\"`);\n use(v.table, v.endField, `the timeline \"${v.name}\"`);\n }\n for (const k of [...Object.keys(v.filters ?? {}), ...Object.keys(v.anyOf ?? {})]) use(v.table, k, `the view \"${v.name}\"'s filter`);\n }\n for (const e of extras) {\n if (e.kind === \"digest\") {\n const v = views.find((x) => x.token === e.view);\n if (v?.kind === \"calendar\") use(v.table, v.dateField, `the digest \"${e.name}\"`);\n for (const k of Object.keys(v?.filters ?? {})) use(v?.table, k, `the digest \"${e.name}\"`);\n if (Object.keys(v?.anyOf ?? {}).length) say(`extras (${e.token})`, `The digest reads \"${v?.name}\", whose any-of filter digests never apply (they read only the flat filters); point it at a view without anyOf.`);\n }\n if (e.kind === \"booking\") for (const qq of e.questions ?? []) if (fieldOf(e.table, qq.fieldKey)?.parityType === \"datetime\" && /slot|appointment|visit|start/i.test(qq.fieldKey)) use(e.table, qq.fieldKey, `the booking \"${e.title}\"`);\n if (e.kind === \"stage_rules\") for (const keys of Object.values(e.requires ?? {})) for (const k of keys) use(e.table, k, `the stage rules \"${e.name}\"`);\n }\n if (agent?.question?.expect) for (const k of [...Object.keys(agent.question.expect.filter ?? {}), agent.question.expect.measure?.key]) use(agent.question.expect.table, k, \"the agent's scripted question\");\n for (const step of spec.walk ?? []) {\n const a = step?.action as Record<string, unknown> | undefined;\n const e = step?.expect as Record<string, unknown> | undefined;\n for (const x of [a, e]) {\n if (!x || typeof x.table !== \"string\") continue;\n use(x.table, typeof x.field === \"string\" ? x.field : undefined, \"a walk step\");\n for (const k of Object.keys((x.where as object) ?? {})) use(x.table, k, \"a walk step\");\n if (x.measure && typeof (x.measure as { key?: string }).key === \"string\") use(x.table, (x.measure as { key: string }).key, \"a walk step\");\n if (Array.isArray(x.columns)) for (const k of x.columns as string[]) use(x.table, k, \"a walk step\");\n }\n }\n for (const [table, key, where] of scheduleUses) {\n const f = fieldOf(table, key);\n if (f?.absoluteDates) say(`tables (${table}).fields (${key})`, `\"${f.label}\" holds history (absoluteDates), so it cannot drive ${where}: schedule dates are relative to install day.`);\n }\n\n // ── G6: fictional phones, domains and streets only ──────────────────────────\n const text = JSON.stringify(raw);\n const isPhoneField = (f: TemplateField) => f.parityType === \"phone\" || /(^|_)(phone|mobile|cell|fax|tel)(_|$)/.test(f.key) || /\\b(phone|mobile|cell|fax)\\b/.test(norm(f.label));\n const phoneHits = new Set<string>();\n for (const p of phonesOutsideFictionalRange(raw.business?.phone ?? \"\", true)) phoneHits.add(p);\n for (const t of tablesRaw) for (const r of t.rows) for (const f of t.fields) {\n const v = unwrap(r.values?.[f.key]);\n if (typeof v === \"string\") for (const p of phonesOutsideFictionalRange(v, isPhoneField(f))) phoneHits.add(p);\n }\n const rowless = JSON.stringify({ ...raw, tables: undefined, sharedBlocks: undefined, business: { ...raw.business, phone: undefined } });\n for (const p of phonesOutsideFictionalRange(rowless)) phoneHits.add(p);\n for (const phone of phoneHits) {\n say(\"phones\", `\"${phone}\" could reach a real phone. Use a fictional number: 555-0100 to 555-0199 in North America (e.g. \"(813) 555-0142\"), or a UK Ofcom drama number (e.g. \"020 7946 0123\").`);\n }\n const declaredDomains = new Set((raw.provenance?.fictionalDomains ?? []).map((d) => d.toLowerCase()));\n const websites = [raw.business?.website, ...tables.flatMap((t) => t.rows.flatMap((r) => t.fields.filter((f) => f.parityType === \"url\").map((f) => storeText(r.values?.[f.key]))))]\n .filter((w): w is string => !!w)\n .map((w) => w.toLowerCase().replace(/^https?:\\/\\//, \"\").replace(/^www\\./, \"\").split(\"/\")[0] ?? \"\");\n for (const d of raw.provenance?.fictionalDomains ?? []) {\n if ((PUBLIC_MAIL_DOMAINS as readonly string[]).includes(d.toLowerCase())) say(\"provenance.fictionalDomains\", `\"${d}\" is a public mail provider real people use, so it is never fictional. Give each person a mailbox on an invented domain.`);\n }\n for (const domain of new Set([...domainsIn(text), ...websites])) {\n if (!declaredDomains.has(domain)) say(\"provenance.fictionalDomains\", `\"${domain}\" is used but not declared fictional. List every invented domain in provenance.fictionalDomains (each is checked not to resolve).`);\n }\n const streets = new Set((raw.provenance?.fictionalStreets ?? []).map((s) => s.toLowerCase()));\n const addressLines = [raw.business?.address?.line1, ...tables.flatMap((t) => t.rows.flatMap((r) => t.fields.filter((f) => behaviorOf(f) === \"text\" && /address|street/i.test(`${f.key} ${f.label}`)).map((f) => storeText(r.values?.[f.key]))))];\n for (const line of addressLines) {\n const street = line ? numberedStreet(line) : null;\n if (street && !streets.has(street.toLowerCase())) say(\"provenance.fictionalStreets\", `\"${line}\" puts a house number on \"${street}\", which is not a declared fictional street. Invent the street and list it, or leave the number out.`);\n }\n\n // ═══ round 4: what a business would never ship ═══════════════════════════════\n\n // ── eligibility declarations name real fields ──\n for (const t of own) {\n for (const f of t.fields.filter((x) => x.eligible)) {\n const el = f.eligible!;\n const ok = isRelation(f) && byToken.has(el.table) && fieldOf(el.table, el.relation)?.relationTarget === f.relationTarget && isDate(fieldOf(el.table, el.until) ?? { parityType: \"\" }) && isDate(fieldOf(t.token, el.onDate) ?? { parityType: \"\" }) && Object.keys(el.where ?? {}).every((k) => !!fieldOf(el.table, k));\n if (!ok) say(`tables (${t.token}).fields (${f.key}).eligible`, `eligible needs: \"${f.key}\" a relation; \"${el.table}.${el.relation}\" pointing at the same table; \"${el.table}.${el.until}\" and \"${t.token}.${el.onDate}\" dates; every where key a field of \"${el.table}\".`);\n }\n }\n\n // ── formula fields: a formula the store can parse, over this table's own fields ──\n for (const t of own) {\n for (const f of t.fields.filter((x) => x.parityType === \"formula\")) {\n const fat = `tables (${t.token}).fields (${f.key})`;\n if (!f.formula?.trim()) {\n say(fat, `\"${f.label}\" is a formula; write it in formula, naming fields in braces: {Total} - {Paid}.`);\n continue;\n }\n const ast = parseFormula(f.formula);\n if (typeof ast === \"string\") {\n say(fat, `The formula \"${f.formula}\" cannot be read: ${ast}.`);\n continue;\n }\n for (const ref of formulaRefs(ast)) {\n const target = t.fields.find((x) => x.label === ref);\n if (!target) say(fat, `The formula reads {${ref}}, and \"${t.token}\" has no field labelled that.`);\n else if (target.key === f.key) say(fat, \"A formula never reads itself.\");\n // Store defect (clone proof, aidream c4b83fff07): a formula reads a lookup or rollup as 0.\n else if (target.parityType === \"lookup\" || target.parityType === \"rollup\") say(fat, `The formula reads {${ref}}, a ${target.parityType}, and the store currently reads that as 0 in a formula. Compute it from stored columns, or ask it as a dashboard or agent question.`);\n }\n }\n }\n\n // ── computed fields hold no seed values: the store computes them ──\n for (const t of tables) {\n for (const f of t.fields) {\n if (!isComputed(f)) continue;\n const seeded = t.rows.filter((r) => r.values?.[f.key] !== undefined).length;\n if (seeded) say(`tables (${t.token}).fields (${f.key})`, `\"${f.label}\" is computed by the store (${f.parityType}), and ${seeded} seed row(s) write a value into it; leave it to the store.`);\n }\n }\n\n // ── labels: no generic nouns, numbered options or placeholder people ──\n const label = (at: string, text: string | undefined, kind: Parameters<typeof findBannedLabel>[1]) => {\n if (!text) return;\n const hit = findBannedLabel(text, kind);\n if (hit) say(at, `\"${text}\" is ${hit.why}. Use the practitioner's own word.`);\n };\n for (const t of own) {\n label(`tables (${t.token}).name`, t.name, \"table\");\n label(`tables (${t.token}).labelSingular`, t.labelSingular, \"table\");\n label(`tables (${t.token}).labelPlural`, t.labelPlural, \"table\");\n for (const f of t.fields) {\n label(`tables (${t.token}).fields (${f.key}).label`, f.label, f.key === t.titleField ? \"title\" : \"field\");\n for (const c of f.choices ?? []) label(`tables (${t.token}).fields (${f.key}).choices`, c, \"choice\");\n }\n // A COLUMN OF COUNTERS: \"<word> 1, <word> 2, <word> 3…\" or numbers with leading zeros.\n for (const f of t.fields.filter((x) => behaviorOf(x) === \"text\")) {\n // Real-world numbered names are names, not counters (a closed list, not a hole).\n const REAL_NUMBERED = /^\\s*(?:period|grade|unit|week|floor|bay|court|lane)\\s+\\d+\\s*$/i;\n const nums = t.rows\n .map((r) => storeText(r.values?.[f.key]) ?? \"\")\n .filter((v) => !REAL_NUMBERED.test(v))\n .map((v) => /^\\s*[A-Za-z][A-Za-z ]*?[\\s#_-]+(\\d+)\\s*$/.exec(v)?.[1])\n .filter((x): x is string => !!x);\n if (nums.length < 3) continue;\n const sorted = nums.map(Number).sort((x, y) => x - y);\n const fromOne = sorted.every((n, i) => n === i + 1);\n const padded = nums.filter((n) => /^0\\d/.test(n)).length >= 3;\n if (fromOne || padded) say(`tables (${t.token}).fields (${f.key})`, `\"${f.label}\" counts ${fromOne ? \"1, 2, 3…\" : \"001, 002…\"} instead of naming each record. Use the business's own numbers (\"Job 2201\", \"INV-2041\") or names.`);\n }\n }\n for (const t of tables) {\n // A \"<thing>_name\" names a thing, not a person: \"Period 1\" is a class section, \"Bay 2\" a bay.\n const nameFields = t.fields.filter((f) => behaviorOf(f) === \"text\" && /(^|_)(full_)?name$|^(owner|patient|client|contact|person)_?name$/.test(f.key) && !THING_NAME.test(f.key));\n for (const f of nameFields) for (const r of t.rows) label(`tables (${t.token}).rows (${r.key}).${f.key}`, storeText(r.values?.[f.key]) ?? undefined, \"person\");\n }\n for (const e of extras) if (e.kind === \"document\") label(`extras (${e.token}).title`, e.title, \"title\");\n\n // ── stale words in seed text: weekdays, months, \"this week\" ──\n // Only words RELATIVE to the day they were written go stale: \"today\", \"tomorrow\", \"next week\",\n // \"last Monday\". A weekday or a month as a name or a recurring thing (\"Monday\", \"Sunday school\",\n // \"Tuesdays before noon\", \"May 2019 build\") is true on any day and passes.\n const WD = \"(?:mon|tues|wednes|thurs|fri|satur|sun)day\";\n const STALE = new RegExp(`\\\\b(?:today|tomorrow|yesterday|tonight)\\\\b|\\\\b(?:this|next|last|coming|past)\\\\s+(?:week|month|year|weekend|${WD})\\\\b`, \"i\");\n for (const t of tables) {\n const byKey = new Map(t.fields.map((f) => [f.key, f]));\n for (const r of t.rows) {\n for (const [k, v] of Object.entries(r.values ?? {})) {\n const f = byKey.get(k);\n if (!f || isRelation(f) || f.parityType === \"email\" || f.parityType === \"url\" || f.parityType === \"phone\") continue;\n const text = unwrap(v);\n if (typeof text === \"string\" && !RELATIVE_DATE.test(text) && STALE.test(text)) {\n say(`tables (${t.token}).rows (${r.key}).${k}`, `\"${text}\" says \"${STALE.exec(text)?.[0]}\", which is only true on the day it was written. Put the date in a date field written relative to install day (\"@today+1b 10:00\"), and keep the text free of \"today\" and \"next week\".`);\n }\n }\n }\n }\n\n // ── sensitivity floors by what a field holds (sensitivityFloorOf, below — one reading for the check and the describe box) ──\n for (const t of own) {\n for (const f of t.fields) {\n const at = `tables (${t.token}).fields (${f.key})`;\n const text = `${f.key} ${norm(f.label)}`;\n const e = effective(t.token, f);\n const floor = sensitivityFloorOf(t, f);\n if (floor === \"restricted\" && !(e.sensitivity === \"restricted\" && e.contextPolicy === \"exclude\")) {\n say(at, `\"${f.label}\" is the kind of value that is restricted and kept from the AI (restricted + exclude).`);\n } else if (floor === \"confidential\" && SENSITIVITY_RANK.indexOf(e.sensitivity) < 2) {\n say(at, `\"${f.label}\" reaches a person or a home, so it is at least confidential.`);\n } else if (/note/.test(text) && e.sensitivity === \"public\") {\n say(at, `\"${f.label}\" is somebody's notes; notes are never public.`);\n }\n }\n }\n\n // ── contact columns belong to different people ──\n for (const t of own) {\n for (const f of t.fields.filter((x) => x.parityType === \"phone\" || x.parityType === \"email\")) {\n const vals = t.rows.map((r) => storeText(r.values?.[f.key])).filter((v): v is string => !!v);\n if (vals.length >= 3 && new Set(vals.map((v) => v.toLowerCase())).size < 0.9 * vals.length) {\n say(`tables (${t.token}).fields (${f.key})`, `${vals.length - new Set(vals).size + 1} rows share one ${f.label}; real customers each have their own.`);\n }\n }\n }\n\n // ── one currency per template ──\n const currencies = new Set(fields.filter((f) => f.parityType === \"currency\").map((f) => (f.unit ?? \"\").toUpperCase()));\n if (currencies.size > 1) say(\"tables\", `Money is kept in ${[...currencies].join(\" and \")}; one business keeps its books in one currency.`);\n\n // ── choice colours mean something: done is never red, failed is never green ──\n const GOOD = /^(completed?|done|paid|approved|won|closed won|booked|confirmed|delivered|resolved|published|signed|passed|hired|accepted)$/i;\n const BAD = /^(cancell?ed|skipped|lost|closed lost|denied|rejected|no[- ]show|failed|overdue|declined|void(ed)?|refunded|churned|expired|blocked)$/i;\n for (const t of own) {\n for (const f of t.fields) {\n for (const [choice, color] of Object.entries(f.choiceColors ?? {})) {\n if (GOOD.test(choice) && color === \"red\") say(`tables (${t.token}).fields (${f.key}).choiceColors`, `\"${choice}\" is a good outcome painted red.`);\n if (BAD.test(choice) && color === \"green\") say(`tables (${t.token}).fields (${f.key}).choiceColors`, `\"${choice}\" is a bad outcome painted green.`);\n }\n }\n }\n\n // ── views tell the truth about their data ──\n for (const v of views) {\n const t = byToken.get(v.table);\n if (!t) continue;\n const vat = `views (${v.token})`;\n const filledShare = (key: string) => (t.rows.length ? t.rows.filter((r) => filled(r.values?.[key])).length / t.rows.length : 0);\n if (v.kind === \"kanban\") {\n const vals = new Set(t.rows.map((r) => storeText(r.values?.[v.groupBy])).filter((x) => x));\n if (vals.size < 2) saySeed(vat, `The board groups by \"${v.groupBy}\", and every row holds the same value — one column.`);\n }\n if (v.kind === \"calendar\" || v.kind === \"timeline\") {\n const keys = v.kind === \"calendar\" ? [v.dateField] : [v.startField, v.endField];\n for (const k of keys) {\n const f = fieldOf(v.table, k);\n if (!f) continue;\n if (f.parityType !== \"datetime\" && !(v.kind === \"calendar\" && v.allDay)) say(vat, `\"${f.label}\" is not a datetime; a ${v.kind} needs one (or declare allDay on a whole-day calendar).`);\n if (filledShare(k) < 0.5) saySeed(vat, `Only ${Math.round(filledShare(k) * 100)}% of rows fill \"${f.label}\"; the ${v.kind} would look empty.`);\n }\n for (const f of t.fields) {\n if (behaviorOf(f) === \"text\" && /(^|_)(start_|end_)?time$|(^|\\s)time$/.test(`${f.key} ${norm(f.label)}`)) {\n say(`tables (${t.token}).fields (${f.key})`, `\"${f.label}\" keeps a time as text beside a ${v.kind}; the time belongs in the datetime field.`);\n }\n }\n }\n if ((v.filters && Object.keys(v.filters).length) || Object.keys(v.anyOf ?? {}).length) {\n const n = t.rows.filter((r) => viewMatches({ key: r.key, values: r.values }, v, tz)).length;\n if (!n) saySeed(vat, `The view's filter matches no seed row; it opens empty.`);\n }\n }\n\n // ── stage ↔ date coherence, on every install weekday ──\n const resolvedFor = new Map(refWeek.map((d) => [d, allTables(resolveRelativeDates(raw, d))]));\n const dayOf = (v: unknown) => {\n const t = storeText(v);\n return t ? t.slice(0, 10) : null;\n };\n for (const e of extras) {\n if (e.kind !== \"stage_rules\") continue;\n const dateFields = (byToken.get(e.table)?.fields ?? []).filter((f) => isDate(f) && !f.absoluteDates);\n if (!e.dateField && dateFields.length) {\n say(`extras (${e.token}).dateField`, `\"${e.table}\" has a schedule date, so its stage rules say which date each stage agrees with: add \"dateField\": \"${dateFields[0]?.key}\" and \"stageDates\" (e.g. {\"${[...(byToken.get(e.table)?.fields.find((f) => f.key === e.stageField)?.choices ?? [\"Done\"])].pop()}\": \"past\"}).`);\n continue;\n }\n if (!e.dateField) continue;\n if (!fieldOf(e.table, e.dateField)) {\n say(`extras (${e.token}).dateField`, `\"${e.table}\" does not declare \"${e.dateField}\".`);\n continue;\n }\n const stageChoices = byToken.get(e.table)?.fields.find((f) => f.key === e.stageField)?.choices ?? [];\n const unlisted = stageChoices.filter((c) => !(c in (e.stageDates ?? {})));\n if (unlisted.length) say(`extras (${e.token}).stageDates`, `Say for every stage whether its date is past, today, future or any; ${unlisted.map((u) => `\"${u}\"`).join(\", \")} ${unlisted.length === 1 ? \"is\" : \"are\"} not listed, so a row could sit there with an impossible date.`);\n // A past/future/today rule on a stage whose every seed row has no date checks nothing: say \"none\".\n for (const [st, rule] of Object.entries(e.stageDates ?? {})) {\n if (rule !== \"past\" && rule !== \"future\" && rule !== \"today\") continue;\n const inSt = (byToken.get(e.table)?.rows ?? []).filter((r) => storeText(r.values?.[e.stageField]) === st);\n if (inSt.length && inSt.every((r) => !filled(r.values?.[e.dateField!]))) say(`extras (${e.token}).stageDates`, `Every \"${st}\" row has no ${e.dateField}, so \"${rule}\" checks nothing; write \"none\" (no date at this stage).`);\n }\n const offDays = new Map<string, { stage: string; rule: string; days: string[] }>();\n for (const [day, ts] of resolvedFor) {\n for (const r of ts.find((t) => t.token === e.table)?.rows ?? []) {\n const stage = storeText(r.values?.[e.stageField]);\n const rule = stage ? e.stageDates?.[stage] : undefined;\n const d = dayOf(r.values?.[e.dateField]);\n if (!stage || !rule || rule === \"any\") continue;\n if (rule === \"none\") {\n if (d) {\n const entry = offDays.get(r.key) ?? { stage, rule, days: [] };\n entry.days.push(WEEKDAY_NAMES[dayOfWeek(day)] ?? day);\n offDays.set(r.key, entry);\n }\n continue;\n }\n if (!d) continue;\n const ok = rule === \"past\" ? d <= day : rule === \"future\" ? d >= day : d === day;\n if (!ok) {\n const entry = offDays.get(r.key) ?? { stage, rule, days: [] };\n entry.days.push(WEEKDAY_NAMES[dayOfWeek(day)] ?? day);\n offDays.set(r.key, entry);\n }\n }\n }\n for (const [key, x] of offDays) {\n const row = byToken.get(e.table)?.rows.find((r) => r.key === key);\n const title = storeText(row?.values?.[byToken.get(e.table)?.titleField ?? \"\"]) ?? key;\n if (x.rule === \"none\") {\n say(`tables (${e.table}).rows (${key})`, `\"${title}\" is ${x.stage}, a stage with no date yet, but its ${e.dateField} is filled. Leave it empty.`);\n continue;\n }\n const when = x.rule === \"today\" ? \"today\" : x.rule === \"past\" ? \"on or before install day\" : \"on or after install day\";\n say(`tables (${e.table}).rows (${key})`, `\"${title}\" is ${x.stage}, so its ${e.dateField} must fall ${when}, but it does not when installed on a ${x.days.join(\", \")}. Write its date relative to install day so the two agree (\"@today-2b\" for done, \"@today+2b\" for coming).`);\n }\n }\n\n // ── business days, historical dates, ordered pairs ──\n for (const t of own) {\n for (const f of t.fields.filter((x) => isDate(x))) {\n if (f.businessDays) {\n const weekend = new Map<string, string[]>();\n for (const [day, ts] of resolvedFor) {\n for (const r of ts.find((x) => x.token === t.token)?.rows ?? []) {\n const d = dayOf(r.values?.[f.key]);\n if (d && [0, 6].includes(dayOfWeek(d))) weekend.set(r.key, [...(weekend.get(r.key) ?? []), WEEKDAY_NAMES[dayOfWeek(day)] ?? day]);\n }\n }\n for (const [key, days] of weekend) {\n const raw0 = tablesRaw.find((x) => x.token === t.token)?.rows.find((r) => r.key === key)?.values?.[f.key];\n say(`tables (${t.token}).rows (${key}).${f.key}`, `\"${f.label}\" is weekdays only, but \"${String(raw0)}\" lands on a Saturday or Sunday when installed on a ${days.join(\", \")}. Count in business days (\"@today+2b 10:00\") or add \"~b\" to move a weekend date to Monday.`);\n }\n }\n if (f.absoluteDates) {\n for (const r of t.rows) {\n const d = dayOf(r.values?.[f.key]);\n if (d && d > TEMPLATE_REFERENCE_DATE) say(`tables (${t.token}).rows (${r.key}).${f.key}`, `\"${f.label}\" is history and ${d} has not happened yet.`);\n }\n }\n }\n const schedule = t.fields.filter((f) => isDate(f) && !f.absoluteDates);\n if (schedule.length >= 2 && !t.before?.length && !t.datesIndependent?.trim()) {\n say(`tables (${t.token}).before`, `\"${t.token}\" has ${schedule.length} schedule dates (${schedule.map((f) => f.key).join(\", \")}); declare their order (before: [earlier, later]) or why they are independent.`);\n }\n const sideValue = (row: { values: Record<string, unknown> }, side: string): { at: string | null; ok: boolean } => {\n const [a, b] = side.split(\".\");\n if (!b) return { at: dayOfMoment(row.values?.[a ?? \"\"]), ok: !!fieldOf(t.token, a ?? \"\") };\n const via = fieldOf(t.token, a ?? \"\");\n if (!via?.relationTarget || !fieldOf(via.relationTarget, b)) return { at: null, ok: false };\n const target = byToken.get(via.relationTarget)?.rows.find((r) => r.key === row.values?.[a ?? \"\"]);\n return { at: target ? dayOfMoment(target.values?.[b]) : null, ok: true };\n };\n for (const [earlier, later] of t.before ?? []) {\n for (const r of t.rows) {\n const x = sideValue(r, earlier);\n const y = sideValue(r, later);\n if (!x.ok || !y.ok) {\n say(`tables (${t.token}).before`, `[${earlier}, ${later}] names a field this table cannot reach.`);\n break;\n }\n if (x.at && y.at && x.at > y.at) say(`tables (${t.token}).rows (${r.key})`, `${earlier} (${x.at}) comes after ${later} (${y.at}); the template says it never does.`);\n }\n }\n }\n\n // ── forms ask only what their audience may give ──\n const stageKeys = new Set([...stageRules.values()].map((r) => `${r.table}.${r.stageField}`));\n for (const form of forms) {\n const asked = new Set<string>();\n for (const ff of form.fields ?? []) {\n if (asked.has(ff.fieldKey)) say(`forms (${form.token}).fields (${ff.fieldKey})`, `The form asks for \"${ff.fieldKey}\" twice.`);\n asked.add(ff.fieldKey);\n const f = fieldOf(form.table, ff.fieldKey);\n if (!f) continue;\n const at = `forms (${form.token}).fields (${ff.fieldKey})`;\n if (isComputed(f)) say(at, `\"${f.label}\" is computed by the store; no form asks for it.`);\n if (stageKeys.has(`${form.table}.${f.key}`)) say(at, `\"${f.label}\" is the pipeline's stage; a form never sets it, a move does.`);\n if (form.audience === \"public\") {\n if (isRelation(f) && (f.parityType === \"member\" || f.relationTarget === SHARED_BLOCKS.team_member.table)) say(at, `A public form never asks a stranger to pick one of the staff (\"${f.label}\").`);\n const e = effective(form.table, f);\n if ((e.sensitivity === \"confidential\" || e.sensitivity === \"restricted\") && !f.askOfSubject && !f.askOfGuardian) {\n say(at, `\"${f.label}\" is ${e.sensitivity}; a public form asks it only of the person it belongs to (askOfSubject) or of a parent or guardian answering for a minor (askOfGuardian) — flag the field if that is who answers.`);\n }\n }\n }\n }\n\n // ── bookings: custom.booking_declare and custom._booking_availability, mirrored ──\n for (const e of extras) {\n if (e.kind !== \"booking\") continue;\n const at = `extras (${e.token})`;\n const status = fieldOf(e.table, \"status\");\n if (!status) say(at, `A booking table needs a choice field keyed \\`status\\` whose choices include \"booked\" and \"cancelled\"; \"${e.table}\" has none. Add it, so a held time can be confirmed and given back.`);\n else if (isChoice(status)) {\n const words = (status.choices ?? []).map((c) => c.trim().toLowerCase());\n const missing = [\"booked\", \"cancelled\"].filter((w) => !words.includes(w));\n if (missing.length) say(`${at}`, `This table's Status is a list of choices, and it has no choice called ${missing.join(\" or \")} — the booking page writes those words (custom.booking_declare refuses).`);\n }\n // The installer's own pre-check, word for word, so a writer sees at Q1 what the install\n // would refuse (the `slot` column the door writes, required and seeded on every row).\n const columns = bookingColumnsProblem(tables, e);\n if (columns && !(status && /writes \"booked\" and \"cancelled\"/.test(columns))) say(`${at}.table`, columns);\n for (const qq of e.questions ?? []) if ([\"slot\", \"status\", \"booked_with\"].includes(qq.fieldKey)) say(`${at}.questions`, `A booking page never asks for \"${qq.fieldKey}\": the store fills it in from the slot that was held.`);\n const a = e.availability ?? ({} as typeof e.availability);\n const rng = (v: number | undefined, lo: number, hi: number, what: string) => {\n if (v !== undefined && (v < lo || v > hi)) say(`${at}.availability`, `${what} is between ${lo} and ${hi}; this says ${v}.`);\n };\n rng(a.slotMinutes, 5, 480, \"Slot length (minutes)\");\n rng(a.bufferMinutes, 0, 480, \"The buffer (minutes)\");\n rng(a.leadMinutes, 0, 43200, \"Lead time (minutes)\");\n rng(a.maxPerDay, 1, 100, \"Appointments a day\");\n rng(a.days, 1, 90, \"Days ahead\");\n if (a.timezone) {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: a.timezone });\n } catch {\n say(`${at}.availability.timezone`, `There is no timezone called \"${a.timezone}\".`);\n }\n }\n const mins = (hhmm: string) => Number(hhmm.slice(0, 2)) * 60 + Number(hhmm.slice(3, 5));\n for (const w of a.windows ?? []) {\n if (/^\\d{2}:\\d{2}$/.test(w.from) && /^\\d{2}:\\d{2}$/.test(w.to) && mins(w.to) - mins(w.from) < (a.slotMinutes ?? 30)) {\n say(`${at}.availability.windows`, `The ${w.from}–${w.to} window on day ${w.weekday} is shorter than one ${a.slotMinutes ?? 30}-minute slot; nothing can be booked in it.`);\n }\n }\n // Seeded bookings sit inside the hours the page offers, on every install weekday.\n const len = a.slotMinutes ?? 30;\n const rawRows = tablesRaw.find((x) => x.token === e.table)?.rows ?? [];\n const cancelled = (r: { values?: Record<string, unknown> }) => /^(cancell?ed|no[- ]?show)$/i.test(storeText(r.values?.[\"status\"]) ?? \"\");\n const local = (v: unknown, d0: string) => {\n const t = typeof v === \"string\" ? resolveDateToken(v, d0, tz) ?? v : storeText(v) ?? \"\";\n const m = /^(\\d{4}-\\d{2}-\\d{2})T(\\d{2}):(\\d{2})/.exec(t);\n return m ? { date: m[1]!, mins: Number(m[2]) * 60 + Number(m[3]) } : null;\n };\n const sameZone = !a.timezone || a.timezone === tz;\n const fromPage = (r: { values?: Record<string, unknown> }) => {\n const st = storeText(r.values?.[\"status\"]) ?? \"\";\n return e.bookedStages ? e.bookedStages.includes(st) : /^(booked|confirmed|requested|held|pending|scheduled)$/i.test(st);\n };\n for (const st of e.bookedStages ?? []) if (status?.choices?.length && !status.choices.includes(st)) say(`${at}.bookedStages`, `\"${st}\" is not one of the status choices.`);\n for (const r of rawRows) {\n if (!sameZone || cancelled(r) || !fromPage(r)) continue;\n const off: string[] = [];\n for (const d0 of refWeek0) {\n const at0 = local(r.values?.[\"slot\"], d0);\n if (!at0) continue;\n const dow = dayOfWeek(at0.date);\n const inside = (a.windows ?? []).some((w) => w.weekday === dow && mins(w.from) <= at0.mins && at0.mins + len <= mins(w.to));\n if (!inside) off.push(WEEKDAY_NAMES[dayOfWeek(d0)] ?? d0);\n }\n if (off.length) say(`tables (${e.table}).rows (${r.key}).slot`, `\"${String(r.values?.[\"slot\"])}\" falls outside \"${e.title}\"'s hours when installed on a ${off.join(\", \")}; a booked time sits in an offered window.`);\n }\n // custom._booking_slots, mirrored: the times the page offers from the install moment (taken as\n // the END of install day, the fewest left), minus the seeded bookings already on those times.\n const freeSlots = (d0: string): number => {\n const now = 23 * 60 + 59;\n const floor = now + (a.leadMinutes ?? 120);\n const taken = new Set(rawRows.filter((r) => !cancelled(r)).map((r) => local(r.values?.[\"slot\"], d0)).filter((x): x is { date: string; mins: number } => !!x).map((x) => `${x.date} ${x.mins}`));\n let free = 0;\n for (let dd = 0; dd < Math.max(a.days ?? 14, 1); dd++) {\n const date = shiftDays(d0, dd);\n let n = 0;\n const wins = (a.windows ?? []).filter((w) => w.weekday === dayOfWeek(date)).sort((x, y) => (x.from === y.from ? (x.to < y.to ? -1 : 1) : x.from < y.from ? -1 : 1));\n for (const w of wins) {\n let m = mins(w.from);\n while (m + len <= mins(w.to)) {\n if (n >= (a.maxPerDay ?? 8)) break;\n if (dd * 1440 + m >= floor) {\n n += 1;\n if (!taken.has(`${date} ${m}`)) free += 1;\n }\n m += len + (a.bufferMinutes ?? 0);\n }\n }\n }\n return free;\n };\n (spec.walk ?? []).forEach((st, wi) => {\n if (st?.action?.kind !== \"open\" || st.action.surface !== e.token || st.expect?.kind !== \"renders\") return;\n const want = st.expect.minItems;\n const short = refWeek0.map((d0) => ({ d0, n: freeSlots(d0) })).filter((x) => x.n < want);\n if (short.length) say(`walk[${wi}].expect`, `\"${e.title}\" offers ${Math.min(...short.map((x) => x.n))} free times when installed on a ${short.map((x) => WEEKDAY_NAMES[dayOfWeek(x.d0)] ?? x.d0).join(\", \")}, fewer than the ${want} the step expects.`);\n });\n }\n\n // ── row actions that set the stage obey the stage rules ──\n for (const e of extras) {\n if (e.kind !== \"row_action\" || e.actionKind !== \"update\") continue;\n for (const st of e.steps ?? []) {\n const rules = stageRules.get(`${e.table}.${st.field}`);\n if (!rules || st.set !== \"value\" || typeof st.value !== \"string\") continue;\n const to = st.value;\n if (rules.transitions?.length && !rules.transitions.some((t) => t.to === to)) say(`extras (${e.token})`, `\"${e.name}\" puts a record in \"${to}\", which no stage rule lets anything move into.`);\n const sets = new Set((e.steps ?? []).filter((x) => x.set === \"value\").map((x) => x.field));\n for (const k of rules.requires?.[to] ?? []) if (!sets.has(k)) say(`extras (${e.token})`, `\"${e.name}\" puts a record in \"${to}\", which needs \"${k}\" filled; the action does not fill it, so the store would refuse it.`);\n }\n }\n for (const e of extras) {\n if (e.kind !== \"notification\" || e.when.event !== \"stage_entered\") continue;\n const rules = stageRules.get(`${e.when.table}.${[...stageRules.values()].find((r) => r.table === e.when.table)?.stageField}`);\n if (rules?.transitions?.length && e.when.stage && !rules.transitions.some((t) => t.to === e.when.stage)) say(`extras (${e.token})`, `It fires on entering \"${e.when.stage}\", which no stage rule lets anything move into.`);\n }\n\n // ── the documents say something ──\n for (const e of extras) {\n if (e.kind !== \"document\") continue;\n const tokens = new Set([...`${e.title}\\n${e.body}`.matchAll(MERGE_TOKEN)].map((m) => m[1]));\n if (tokens.size < 2) say(`extras (${e.token}).body`, \"A document this business sends carries the record's own facts — at least two merge fields.\");\n }\n\n // ── the agent's question is about what it says it is about ──\n if (agent?.question?.expect) {\n const qq = agent.question;\n const ask = norm(qq.ask);\n const words = (t: string) => norm(t).split(\" \").filter((w) => w.length >= 4);\n // A label of short words only (\"DJ pay\", \"Fee\") is named by its whole words, never unmatchable.\n const askWords = new Set(ask.split(\" \"));\n const mentions = (t: string) =>\n (!!norm(t) && ask.includes(norm(t))) ||\n words(t).some((w) => ask.includes(w.replace(/s$/, \"\"))) ||\n (words(t).length === 0 && norm(t).split(\" \").filter(Boolean).some((w) => w.length >= 3 && (askWords.has(w) || askWords.has(`${w}s`))));\n for (const [k, v] of Object.entries(qq.expect.filter ?? {})) {\n if (typeof v === \"string\" && !mentions(v) && !ask.includes(norm(v))) say(\"agent.question.ask\", `It filters on ${k} = \"${v}\", and the question never says so.`);\n }\n const qt = byToken.get(qq.expect.table);\n const mf = qq.expect.measure.key ? fieldOf(qq.expect.table, qq.expect.measure.key) : undefined;\n if (mf && !mentions(mf.label)) say(\"agent.question.ask\", `It adds up \"${mf.label}\", and the question never names it.`);\n if (qq.expect.measure.op === \"count\" && qt && !mentions(qt.labelPlural) && !mentions(qt.labelSingular)) say(\"agent.question.ask\", `It counts ${qt.labelPlural}, and the question never says what it counts.`);\n const why = qq.whyItMatters?.trim() ?? \"\";\n if (why.split(/\\s+/).length < 8 || /^(because|it matters|important|to know|for reporting|n\\/?a)\\.?$/i.test(why)) say(\"agent.question.whyItMatters\", \"Say in a full sentence what the owner does differently depending on the answer.\");\n const unit = (qq.expect.unit ?? \"\").trim().toLowerCase();\n if (mf?.unit && qq.expect.measure.op !== \"count\" && ![\"filled\", \"empty\", \"unique\"].includes(qq.expect.measure.op) && unit !== mf.unit.toLowerCase()) {\n say(\"agent.question.expect.unit\", `\"${mf.label}\" is kept in ${mf.unit}, so the answer is in ${mf.unit}, not \"${qq.expect.unit}\".`);\n }\n if (qq.expect.measure.op === \"count\" && qt && !mentions(unit) && !norm(qt.labelPlural).includes(unit.replace(/s$/, \"\"))) {\n say(\"agent.question.expect.unit\", `A count of ${qt.labelPlural} is in ${qt.labelPlural.toLowerCase()}, not \"${qq.expect.unit}\".`);\n }\n const readTables = new Set<string>([qq.expect.table]);\n for (const st of spec.walk ?? []) for (const x of [st?.action, st?.expect] as Array<{ table?: string } | undefined>) if (x?.table) readTables.add(x.table);\n if (agent.variables?.length && !agent.variables.some((v) => v.table === qq.expect.table)) {\n say(\"agent.variables\", `The question reads \"${qq.expect.table}\", and no variable gives the agent that table.`);\n }\n agent.variables?.forEach((v, vi) => {\n if (!readTables.has(v.table)) say(`agent.variables[${vi}]`, `\"${v.name}\" is bound to \"${v.table}\", which neither the question nor the walk reads.`);\n });\n }\n\n // ── the walk does something, and says what it does ──\n const walk = spec.walk ?? [];\n const opens = walk.filter((st) => st?.action?.kind === \"open\").length;\n if (opens > 1) say(\"walk\", `${opens} steps only open a screen; a teaching walk opens at most one and then does something.`);\n if (!walk.some((st) => [\"move\", \"moves\", \"edit\", \"import\", \"archive\", \"restore\"].includes(st?.action?.kind ?? \"\"))) say(\"walk\", \"No step changes anything; at least one moves, edits, imports or archives.\");\n const third = walk[2]?.action?.kind;\n if (walk.length === 3 && ![\"ask_agent\", \"submit_form\"].includes(third ?? \"\")) say(\"walk[2]\", \"The last step closes the loop: it asks the agent, or comes in through a front door (a form) — or add a fourth step that asks the agent.\");\n // At least one step exercises what the template teaches.\n const opened = (pred: (token: string) => boolean) => walk.some((st) => st?.action?.kind === \"open\" && pred(st.action.surface));\n const viewKind = (kind: string) => (token: string) => views.some((v) => v.token === token && v.kind === kind);\n const extraKind = (kind: string) => (token: string) => extras.some((e) => e.token === token && e.kind === kind);\n const touches = (pred: (table: string) => boolean) =>\n walk.some((st) => {\n const a = st?.action as { kind?: string; table?: string; surface?: string } | undefined;\n if (!a) return false;\n if (a.table) return pred(a.table);\n const v = views.find((x) => x.token === a.surface);\n return !!v && pred(v.table);\n });\n const lookupTables = (t: string) => !!byToken.get(t)?.fields.some((f) => f.parityType === \"lookup\" || f.parityType === \"rollup\");\n const governedShown = walk.some((st) => {\n const a = st?.action as { kind?: string; table?: string; surface?: string; field?: string; set?: Record<string, unknown> } | undefined;\n const isGoverned = (t: string, k: string) => {\n const f = fieldOf(t, k);\n return !!f && f.contextPolicy === \"exclude\" && (f.sensitivity === \"restricted\" || f.sensitivity === \"confidential\");\n };\n if (a?.kind === \"open\") {\n const v = views.find((x) => x.token === a.surface);\n return !!v && (byToken.get(v.table)?.fields ?? []).some((f) => isGoverned(v.table, f.key) && !(v.hiddenFields ?? []).includes(f.key));\n }\n if (a?.kind === \"edit\" && a.table) return [...Object.keys(a.set ?? {}), a.field ?? \"\"].some((k) => isGoverned(a.table!, k));\n return false;\n });\n const EXERCISED: Record<string, boolean> = {\n kanban: opened(viewKind(\"kanban\")) || walk.some((st) => st?.action?.kind === \"move\" || st?.action?.kind === \"moves\"),\n calendar: opened(viewKind(\"calendar\")),\n timeline: opened(viewKind(\"timeline\")),\n gallery: opened(viewKind(\"gallery\")),\n forms: walk.some((st) => st?.action?.kind === \"submit_form\"),\n bookings: opened(extraKind(\"booking\")),\n portals: opened(extraKind(\"portal\")),\n dashboards: opened(extraKind(\"dashboard\")),\n drill_down: opened(extraKind(\"drill_down\")),\n checklists: opened(extraKind(\"checklist\")),\n documents_esign: opened(extraKind(\"document\")) || touches((t) => extras.some((e) => e.kind === \"document\" && e.table === t)),\n relations_rollups: touches(lookupTables),\n dimensions: opened(extraKind(\"drill_down\")) || opened(extraKind(\"dashboard\")) || touches((t) => (spec.dimensions ?? []).some((d) => d.table === t)),\n agents: walk.some((st) => st?.action?.kind === \"ask_agent\"),\n field_governance: governedShown,\n import_upsert: walk.some((st) => st?.action?.kind === \"import\"),\n };\n if (spec.teaches && EXERCISED[spec.teaches] === false) say(\"walk\", `No step exercises \"${spec.teaches}\", the feature this template teaches; make one step open or use it.`);\n walk.forEach((st, i) => {\n const a = st?.action;\n const says = norm(st?.says ?? \"\");\n // Named = the whole name, or (for a long title) at least two of its distinctive words.\n const named = (t: string | undefined) => {\n if (!t) return false;\n if (says.includes(norm(t))) return true;\n const long = [...new Set(norm(t).split(\" \").filter((w) => w.length >= 4))];\n // A name of short words only is named by its whole words.\n const words = long.length ? long : [...new Set(norm(t).split(\" \").filter((w) => w.length >= 2))];\n const said = new Set(says.split(\" \"));\n return words.length > 0 && words.filter((w) => said.has(w) || said.has(`${w}s`)).length >= Math.min(2, words.length);\n };\n if (!a) return;\n if (a.kind === \"move\" || a.kind === \"edit\" || a.kind === \"archive\" || a.kind === \"restore\") {\n const t = byToken.get(a.table);\n const row = t?.rows.find((r) => r.key === a.row);\n const title = row ? storeText(row.values?.[t?.titleField ?? \"\"]) ?? undefined : undefined;\n if (!named(title)) say(`walk[${i}].says`, `Name the record it acts on (\"${title}\").`);\n if (a.kind === \"edit\") {\n const keys = a.set ? Object.keys(a.set) : a.field ? [a.field] : [];\n const labels = keys.map((k) => fieldOf(a.table, k)?.label).filter((l): l is string => !!l);\n if (labels.length && !labels.some((l) => named(l))) say(`walk[${i}].says`, `Name a field it changes (\"${labels[0]}\").`);\n }\n if (a.kind === \"move\" && !named(a.to)) say(`walk[${i}].says`, `Say where it moves the record (\"${a.to}\").`);\n }\n if (a.kind === \"moves\") {\n for (const m of a.moves ?? []) {\n const t = byToken.get(m.table);\n const title = storeText(t?.rows.find((r) => r.key === m.row)?.values?.[t?.titleField ?? \"\"]) ?? undefined;\n if (!named(title)) say(`walk[${i}].says`, `Name each record it moves (\"${title}\").`);\n }\n }\n if (a.kind === \"open\") {\n const v = views.find((x) => x.token === a.surface);\n const x = extras.find((e) => e.token === a.surface) as { name?: string; title?: string } | undefined;\n const name = v?.name ?? forms.find((f) => f.token === a.surface)?.name ?? x?.name ?? x?.title;\n if (!named(name)) say(`walk[${i}].says`, `Name the screen it opens (\"${name}\").`);\n }\n if (a.kind === \"import\" && !named(a.sourceName.replace(/\\.(csv|xlsx)$/i, \"\"))) say(`walk[${i}].says`, `Name the file it imports (\"${a.sourceName}\").`);\n if (a.kind === \"submit_form\") {\n const fm = forms.find((x) => x.token === a.form);\n if (!named(fm?.name)) say(`walk[${i}].says`, `Name the form it fills in (\"${fm?.name}\").`);\n }\n });\n\n // ═══ round 6: a template that installs cleanly and behaves like the business ═══\n\n // ── a new record can always be made: forms and imports carry every required field ──\n // The stage is set by moves, never asked. slot/status/booked_with are the BOOKING door's own\n // fields: exempt for a booking page, never for a plain form on the same table.\n const doorOwned = (table: string, key: string) => stageFieldsOf.has(`${table}.${key}`);\n const mustGive = (table: string) => (byToken.get(table)?.fields ?? []).filter((f) => f.required && !isComputed(f) && (f.source ?? \"manual\") === \"manual\" && f.default === undefined && !doorOwned(table, f.key));\n for (const form of forms) {\n const asked = new Set((form.fields ?? []).map((q) => q.fieldKey));\n for (const f of mustGive(form.table)) {\n if (!asked.has(f.key)) say(`forms (${form.token})`, `\"${form.name}\" never asks for \"${f.label}\", which every ${byToken.get(form.table)?.labelSingular.toLowerCase() ?? \"record\"} must have — the store would refuse each answer. Ask it, or give the field a default.`);\n }\n }\n (spec.walk ?? []).forEach((st, i) => {\n const a = st?.action;\n if (a?.kind !== \"import\") return;\n const cols = new Set(a.columns ?? []);\n const live = (state0.get(a.table) ?? []).map((r) => (storeText(r.values?.[a.dedupeKey]) ?? \"\").trim());\n (a.rows ?? []).forEach((cells, ri) => {\n const keyValue = (cells[a.columns.indexOf(a.dedupeKey)] ?? \"\").trim();\n if (live.includes(keyValue)) return;\n for (const f of mustGive(a.table)) {\n const ci = a.columns.indexOf(f.key);\n if (!cols.has(f.key) || !(cells[ci] ?? \"\").trim()) say(`walk[${i}].action.rows[${ri}]`, `The new row \"${keyValue}\" has no \"${f.label}\", which every ${byToken.get(a.table)?.labelSingular.toLowerCase() ?? \"record\"} must have; the import would refuse it.`);\n }\n });\n });\n\n // ── relationships[] and relation fields name each other ──\n for (const t of own) {\n for (const f of t.fields) {\n if (!isRelation(f) || !f.relationTarget || f.parityType === \"attachment\") continue;\n if (!(spec.relationships ?? []).some((r) => r.fromTable === t.token && r.fromField === f.key)) {\n say(`tables (${t.token}).fields (${f.key})`, `\"${f.label}\" points at \"${f.relationTarget}\" but relationships[] does not state it; add the sentence of domain truth with its flavour and what happens on delete.`);\n }\n }\n }\n\n // ── the agent's question is about a slice, not one row ──\n if (agent?.question?.expect) {\n const qe = agent.question.expect;\n const n = (byToken.get(qe.table)?.rows ?? []).filter((r) => storeFilterMatches({ key: r.key, values: r.values }, qe.filter, tz)).length;\n if (n < 3) say(\"agent.question.expect.filter\", `The question reads ${n} row(s); a question an owner asks an assistant adds up at least three (a single record is a look-up, not an answer).`);\n }\n\n // ── the seed is spread like a real business's ──\n for (const v of views) {\n if (v.kind !== \"calendar\" && v.kind !== \"timeline\") continue;\n const key = v.kind === \"calendar\" ? v.dateField : v.startField;\n const days = distinctDays(v.table, key);\n if (days < 5) saySeed(`views (${v.token})`, `The ${v.kind} \"${v.name}\" would show seed records on only ${days} day(s); spread them across at least five.`);\n }\n if (main) {\n // The spread applies to the template's MAIN board only: the main table's stage rules, when the\n // main table is also what its first board (kanban) shows. A secondary table that carries\n // stage rules so a grouped step can move it (supplies mostly \"In stock\") is exempt.\n // Only a BOARD (kanban) grouped by the stage field shows the spread; a grid grouped by stage does not.\n const board = views.find((v) => v.kind === \"kanban\") as (TemplateView & { groupBy?: string }) | undefined;\n const primary = board && board.table === main.token ? [...stageRules.values()].find((x) => x.table === main.token && (!board.groupBy || board.groupBy === x.stageField)) : undefined;\n const pt = primary ? own.find((x) => x.token === primary.table) : undefined;\n if (primary && pt) {\n const counts = new Map<string, number>();\n for (const row of pt.rows) {\n const st = storeText(row.values?.[primary.stageField]);\n if (st) counts.set(st, (counts.get(st) ?? 0) + 1);\n }\n for (const [st, c] of counts) if (c > 0.6 * pt.rows.length) say(`tables (${pt.token})`, `${c} of ${pt.rows.length} ${pt.labelPlural.toLowerCase()} sit in \"${st}\"; a working board spreads across its stages (at most 60% in one).`);\n }\n if ((spec.foundation ?? []).some((f) => f.table === main.token)) say(\"foundation\", `\"${main.token}\" is the main table — the day-to-day work — so it is never foundation data.`);\n }\n const viewSigs = new Map<string, string>();\n for (const v of views) {\n const { token: _t, name: _n, isDefault: _d, ...shape } = v as TemplateView & { token: string; name: string; isDefault?: boolean };\n const sig = JSON.stringify(Object.keys(shape).sort().map((k) => [k, (shape as Record<string, unknown>)[k]]));\n const twin = viewSigs.get(sig);\n if (twin) say(`views (${v.token})`, `\"${v.name}\" shows exactly what \"${twin}\" shows; drop it or give it its own question (a filter, a sort, a grouping).`);\n else viewSigs.set(sig, v.name);\n }\n\n // ═══ on-screen text is layout (common-docs/policies/interface-text-is-layout.md) ═══\n // Budgets from the policy: a label is a few words; secondary text (field help, a form\n // question's help) ≤ 60, one line; a tooltip or description ≤ 140, one sentence; a dialog,\n // confirmation or teaching step ≤ 140, two sentences at most. Who may see a value and whether\n // the AI reads it is sensitivity/contextPolicy — never words on the screen.\n // Sentences, not abbreviations: \"Mr. Ibáñez\", \"Dr. Achebe\", \"e.g.\" and \"a.m.\" end nothing.\n const sentences = (t: string) =>\n t\n .trim()\n .replace(/\\b(?:Mr|Mrs|Ms|Dr|St|Jr|Sr|Mt|No|vs|etc|Inc|Ltd|Co)\\./g, (m) => m.slice(0, -1))\n .replace(/\\b(?:e\\.g|i\\.e|a\\.m|p\\.m)\\./gi, \"x\")\n .split(/[.!?](?:\\s+|$)/)\n .filter((x) => x.trim()).length;\n const LABEL_MAX = 40;\n const IMPLEMENTATION =\n /\\b(?:the\\s+)?(?:ai|a\\.i\\.|agent|assistant|llm|model)\\b[^.]*\\b(?:reads?|sees?|never|cannot|can't|won't|doesn't|does not|is kept)\\b|\\b(?:never|not)\\b[^.]*\\b(?:ai|agent)\\b|\\bthe store\\b|\\bthis field\\b|\\bthis column\\b|\\bthe booking page writes\\b|\\bwrites? (?:a |the )?(?:booked )?time here\\b|\\bcustom\\.[a-z_]+|\\{\\{|\\b[a-z]+_[a-z0-9_]+\\b|\\b(?:sum|avg|count|min|max)\\s*\\(|\\s=\\s/i;\n const STAFF_VOICE = /\\bwe\\b|\\bour system\\b/i;\n const screen = (at: string, text: string | undefined, slot: \"label\" | \"secondary\" | \"tooltip\" | \"dialog\", opts: { publicVoice?: boolean } = {}) => {\n if (!text?.trim()) return;\n const t = text.trim();\n if (slot === \"label\" && (t.length > LABEL_MAX || t.split(/\\s+/).length > 6)) say(at, `\"${t}\" is a label (${t.length} characters); keep it to a few words — the name of the thing, no explanation.`);\n if (slot === \"secondary\" && (t.length > 60 || sentences(t) > 1)) say(at, `\"${t}\" is ${t.length} characters; help text is one line of at most 60, one sentence.`);\n if (slot === \"tooltip\" && (t.length > 140 || sentences(t) > 1)) say(at, `\"${t.slice(0, 60)}…\" is ${t.length} characters; a description is one sentence of at most 140.`);\n if (slot === \"dialog\" && (t.length > 140 || sentences(t) > 2)) say(at, `\"${t.slice(0, 60)}…\" is ${t.length} characters; this slot holds at most 140, two sentences: what happened and what to do.`);\n const impl = IMPLEMENTATION.exec(t);\n if (impl) say(at, `\"${t.slice(0, 70)}\" explains how the system works (\"${impl[0].trim()}\"); that belongs in sensitivity, contextPolicy or the commit, not on screen. Say only what the person needs.`);\n else if (!opts.publicVoice && slot !== \"label\" && STAFF_VOICE.test(t) && !/\\?\\s*$/.test(t)) say(at, `\"${t.slice(0, 70)}\" speaks as \"we\"; on the staff's own screen, name the thing instead.`);\n };\n for (const t of own) {\n screen(`tables (${t.token}).name`, t.name, \"label\");\n screen(`tables (${t.token}).labelPlural`, t.labelPlural, \"label\");\n screen(`tables (${t.token}).labelSingular`, t.labelSingular, \"label\");\n screen(`tables (${t.token}).describes`, t.describes, \"tooltip\");\n for (const f of t.fields) {\n screen(`tables (${t.token}).fields (${f.key}).label`, f.label, \"label\");\n screen(`tables (${t.token}).fields (${f.key}).help`, f.help, \"secondary\");\n for (const c of f.choices ?? []) screen(`tables (${t.token}).fields (${f.key}).choices`, c, \"label\");\n }\n }\n for (const v of views) screen(`views (${v.token}).name`, v.name, \"label\");\n for (const f of forms) {\n const pub = f.audience === \"public\";\n screen(`forms (${f.token}).name`, f.name, \"label\");\n screen(`forms (${f.token}).describes`, f.describes, \"tooltip\");\n screen(`forms (${f.token}).submitLabel`, f.submitLabel, \"label\");\n screen(`forms (${f.token}).confirmation`, f.confirmation, \"dialog\", { publicVoice: pub });\n for (const q of f.fields ?? []) {\n screen(`forms (${f.token}).fields (${q.fieldKey}).ask`, q.ask, \"tooltip\", { publicVoice: pub });\n screen(`forms (${f.token}).fields (${q.fieldKey}).help`, q.help, \"secondary\", { publicVoice: pub });\n }\n }\n for (const e of extras) {\n const at = `extras (${e.token})`;\n if (\"name\" in e) screen(`${at}.name`, e.name, \"label\");\n if (e.kind === \"booking\") {\n screen(`${at}.title`, e.title, \"label\");\n for (const q of e.questions ?? []) {\n screen(`${at}.questions (${q.fieldKey}).ask`, q.ask, \"tooltip\", { publicVoice: true });\n screen(`${at}.questions (${q.fieldKey}).help`, q.help, \"secondary\", { publicVoice: true });\n }\n }\n if (e.kind === \"portal\") screen(`${at}.title`, e.title, \"label\");\n if (e.kind === \"dashboard\") for (const b of e.blocks ?? []) screen(`${at}.blocks (${b.title})`, b.title, \"label\");\n const described = (e as { describes?: unknown }).describes;\n if (typeof described === \"string\") screen(`${at}.describes`, described, \"tooltip\");\n if (e.kind === \"stage_rules\") {\n for (const [st, d] of Object.entries(e.stages ?? {})) screen(`${at}.stages (${st})`, d, \"tooltip\");\n screen(`${at}.movesMessage`, e.movesMessage, \"dialog\");\n }\n }\n (spec.walk ?? []).forEach((w, i) => screen(`walk[${i}].says`, w?.says, \"dialog\", { publicVoice: true }));\n for (const f of spec.foundation ?? []) screen(`foundation (${f.table}).keptFor`, f.keptFor, \"tooltip\");\n\n // ═══ dates agree across relations (parent → child) ═══\n const sideDay = (table: string, row: { values: Record<string, unknown> }, side: string): { at: string | null; ok: boolean } => {\n const [a, b] = side.split(\".\");\n if (!b) {\n const f = fieldOf(table, a ?? \"\");\n return { at: dayOfMoment(row.values?.[a ?? \"\"]), ok: !!f && isDate(f) };\n }\n const via = fieldOf(table, a ?? \"\");\n const far = via?.relationTarget ? fieldOf(via.relationTarget, b) : undefined;\n if (!via?.relationTarget || !far || !isDate(far)) return { at: null, ok: false };\n const target = byToken.get(via.relationTarget)?.rows.find((r) => r.key === row.values?.[a ?? \"\"]);\n return { at: target ? dayOfMoment(target.values?.[b]) : null, ok: true };\n };\n for (const t of own) {\n for (const pair of t.datePairs ?? []) {\n const pat = `tables (${t.token}).datePairs`;\n if (pair.onlyWhen && !fieldOf(t.token, pair.onlyWhen.field)) say(pat, `onlyWhen names \"${pair.onlyWhen.field}\", which \"${t.token}\" does not declare.`);\n for (const r of t.rows) {\n const x = sideDay(t.token, r, pair.earlier);\n const y = sideDay(t.token, r, pair.later);\n if (!x.ok || !y.ok) {\n say(pat, `[${pair.earlier} → ${pair.later}] names something that is not a date \"${t.token}\" can reach.`);\n break;\n }\n const applies = !pair.onlyWhen || pair.onlyWhen.values.includes(storeText(r.values?.[pair.onlyWhen.field]) ?? \"\");\n const title = storeText(r.values?.[t.titleField]) ?? r.key;\n if (!applies && x.at === null && y.at !== null && pair.onlyWhen) {\n say(`tables (${t.token}).rows (${r.key})`, `\"${title}\" has ${pair.later} but is \"${storeText(r.values?.[pair.onlyWhen.field])}\"; it only has one when ${pair.onlyWhen.field} is ${pair.onlyWhen.values.join(\" or \")}.`);\n }\n if (applies && x.at && y.at && x.at > y.at) say(`tables (${t.token}).rows (${r.key})`, `\"${title}\": ${pair.later} (${y.at}) comes before ${pair.earlier} (${x.at}); the template says it never does.`);\n }\n }\n // Conventional pairs nobody has to remember: a bill is issued after the work it bills began;\n // a report is due only on a grant that was awarded.\n for (const f of t.fields.filter((x) => isDate(x) && !x.absoluteDates)) {\n // Only a bill: a certificate's or license's \"issued\" date rightly predates a person's start.\n const billing = /(invoice|bill|statement|receipt|payment|charge|fee)/i.test(`${t.token} ${t.labelSingular}`);\n if (billing && /(issued|billed|invoice)/.test(f.key)) {\n for (const rel of t.fields.filter((x) => isRelation(x) && x.relationTarget && x.parityType !== \"attachment\")) {\n const start = byToken.get(rel.relationTarget ?? \"\")?.fields.find((x) => isDate(x) && /(start|engag|opened|began|work_from|kickoff)/.test(x.key));\n if (!start) continue;\n for (const r of t.rows) {\n const x = sideDay(t.token, r, `${rel.key}.${start.key}`);\n const y = sideDay(t.token, r, f.key);\n if (x.at && y.at && y.at < x.at) say(`tables (${t.token}).rows (${r.key})`, `\"${storeText(r.values?.[t.titleField]) ?? r.key}\" is ${f.label.toLowerCase()} ${y.at}, before its ${rel.label.toLowerCase()} began (${x.at}).`);\n }\n }\n }\n // Only on a grant table: an appraisal, an inspection or an audit has a \"report due\" that has nothing to do\n // with an award (two writers renamed honest fields to get past this).\n if (/report_due|reporting_due/.test(f.key) && /grant|award|funder|funding/i.test(`${t.token} ${t.name} ${t.labelSingular}`)) {\n const st = t.fields.find((x) => isChoice(x) && /status|stage/.test(x.key));\n if (!st) continue;\n for (const r of t.rows) {\n const v = storeText(r.values?.[st.key]) ?? \"\";\n if (filled(r.values?.[f.key]) && !/award|active|funded|report|closed|complete/i.test(v)) {\n say(`tables (${t.token}).rows (${r.key})`, `\"${storeText(r.values?.[t.titleField]) ?? r.key}\" has a ${f.label.toLowerCase()} but is \"${v}\"; a report is due only once the grant is awarded.`);\n }\n }\n }\n }\n }\n const crossesRelation = own.some((t) => [...(t.datePairs ?? []).flatMap((p) => [p.earlier, p.later]), ...(t.before ?? []).flat()].some((side) => side.includes(\".\")));\n const grants = own.some((t) => /grant/i.test(`${t.token} ${t.name}`));\n const parentChildDates = own.some((t) =>\n t.fields.some((f) => isDate(f) && !f.absoluteDates) &&\n t.fields.some((rf) => isRelation(rf) && rf.relationTarget && own.find((p) => p.token === rf.relationTarget)?.fields.some((pf) => isDate(pf) && !pf.absoluteDates)),\n );\n if ((spec.job === \"billing\" || grants) && parentChildDates && !crossesRelation) {\n say(\"tables\", `A ${grants ? \"grants\" : \"billing\"} template dates records against the records they hang off; declare at least one datePairs entry across a relation (e.g. {\"earlier\": \"engagement.start_date\", \"later\": \"issued_on\"}).`);\n }\n\n // ═══ every seed value is one of its field's choices (single and multi) ═══\n for (const t of tables) {\n for (const f of t.fields.filter((x) => isChoice(x) && x.choices?.length)) {\n for (const r of t.rows) {\n const v = unwrap(r.values?.[f.key]);\n for (const one of Array.isArray(v) ? v : v === undefined || v === null || v === \"\" ? [] : [v]) {\n if (typeof one !== \"string\" || !f.choices!.includes(one)) {\n say(`tables (${t.token}).rows (${r.key}).${f.key}`, `\"${String(one)}\" is not one of \"${f.label}\"'s choices (${f.choices!.join(\", \")}). Use one of them, or add it to the list.`);\n }\n }\n }\n }\n }\n\n // ═══ moments that already happened, and stored copies the store would compute ═══\n for (const t of own) {\n const raw = tablesRaw.find((x) => x.token === t.token);\n // Date-driven status: the band the date falls in, on every install weekday.\n const sbd = t.statusByDate;\n if (sbd) {\n const sf = fieldOf(t.token, sbd.field);\n const df = fieldOf(t.token, sbd.dateField);\n if (!sf || !df || !isDate(df)) say(`tables (${t.token}).statusByDate`, `It reads \"${sbd.dateField}\" into \"${sbd.field}\"; both have to be fields of \"${t.token}\", the first a date.`);\n for (const b of sbd.bands ?? []) if (sf?.choices?.length && !sf.choices.includes(b.status)) say(`tables (${t.token}).statusByDate`, `\"${b.status}\" is not one of \"${sf.label}\"'s choices.`);\n const banded = new Set((sbd.bands ?? []).map((b) => b.status));\n for (const r of raw?.rows ?? []) {\n const st = storeText(r.values?.[sbd.field]) ?? \"\";\n const v = r.values?.[sbd.dateField];\n if (!banded.has(st) || typeof v !== \"string\") continue;\n const off: string[] = [];\n for (const d0 of refWeek0) {\n const dd = (resolveDateToken(v, d0, tz) ?? v).slice(0, 10);\n const diff = Math.round((Date.parse(`${dd}T00:00:00Z`) - Date.parse(`${d0}T00:00:00Z`)) / 86_400_000);\n const band = (sbd.bands ?? []).find((b) => (b.from === undefined || diff >= b.from) && (b.to === undefined || diff < b.to));\n if (band && band.status !== st) off.push(`${WEEKDAY_NAMES[dayOfWeek(d0)] ?? d0} (${band.status})`);\n }\n if (off.length) say(`tables (${t.token}).rows (${r.key}).${sbd.field}`, `\"${st}\" disagrees with its ${df?.label.toLowerCase() ?? sbd.dateField} ${v} when installed on a ${off.join(\", \")}.`);\n }\n }\n // An UNFILTERED rollup adds every linked record, so a status or time word in its name is a promise it\n // cannot keep. A rollup with a `filter` (live since 2026-10-03, custom.field_declare) adds only what the\n // filter picks, and may be named for it (\"Copay owed\").\n const ROLLUP_WORDS = /\\b(open|booked|upcoming|unpaid|outstanding|active|monthly|weekly|yearly|annual|on the books|lined up|ordered|pending|overdue|scheduled|confirmed|paid|completed|current|remaining|this (?:week|month|year|season)|ytd|mtd)\\b/i;\n for (const f of t.fields.filter((x) => x.parityType === \"rollup\" && !(x.filter && Object.keys(x.filter).length))) {\n const said = `${f.label} ${f.key.replace(/_/g, \" \")}`;\n const hit = ROLLUP_WORDS.exec(said);\n if (hit) say(`tables (${t.token}).fields (${f.key})`, `\"${f.label}\" says \"${hit[1]}\", but this rollup adds every linked record, whatever its status or date. Give it a filter that picks those records, or name it for all of them.`);\n }\n // A stored parent number that just repeats its children's amounts: a rollup computes it.\n for (const child of own) {\n for (const rel of child.fields.filter((f) => isRelation(f) && f.relationTarget === t.token && !f.multi && (f.relationMax ?? 1) === 1)) {\n const byParent = new Map<unknown, SeedRow[]>();\n for (const c of child.rows) byParent.set(c.values?.[rel.key], [...(byParent.get(c.values?.[rel.key]) ?? []), c]);\n // Money only, and never a bound (a budget, a cap, a pay range): a bound SHOULD sit near what it bounds.\n const money = (f: TemplateField) => f.parityType === \"currency\" && !isComputed(f) && !/(^|_| )(low|high|min|max|range|budget|limit|cap|ceiling|floor|expect\\w*)( |_|$)/i.test(`${f.key} ${f.label}`);\n for (const pf of t.fields.filter(money)) {\n for (const cf of child.fields.filter(money)) {\n const judged = t.rows\n .map((pr) => {\n const pv = Number(storeText(pr.values?.[pf.key]));\n const kids = (byParent.get(pr.key) ?? []).filter((c) => filled(c.values?.[cf.key])).map((c) => Number(storeText(c.values?.[cf.key]))).filter((n) => Number.isFinite(n));\n return filled(pr.values?.[pf.key]) && Number.isFinite(pv) && pv !== 0 && kids.length ? { pv, kids } : null;\n })\n .filter((x): x is { pv: number; kids: number[] } => !!x);\n if (judged.length < 3) continue;\n const near = (a: number, b: number) => Math.abs(a - b) <= 0.1 * Math.abs(a);\n // \"One of its children's amounts\" only where it HAS one child (then the sum is that amount): a\n // service's usual length matching one of its many tickets is a default, not a copy.\n const copies = judged.filter(({ pv, kids }) => near(pv, kids.reduce((a, b) => a + b, 0))).length;\n if (copies / judged.length >= 0.75) say(`tables (${t.token}).fields (${pf.key})`, `\"${pf.label}\" repeats its ${child.labelPlural.toLowerCase()}' \"${cf.label}\" on ${copies} of ${judged.length} rows; make it a rollup (via the ${child.labelPlural.toLowerCase()}, sum of \"${cf.label}\") so it never drifts.`);\n }\n }\n }\n }\n // \"Requested on\", \"Received at\", \"Date filed\": the moment is past (or now) on every install day.\n for (const f of t.fields.filter((ff) => isDate(ff) && /^(?:date_)?(?:requested|received|submitted|created|opened|reported|filed)(?:_(?:on|at|date))?$/.test(ff.key))) {\n for (const r of raw?.rows ?? []) {\n const v = r.values?.[f.key];\n if (typeof v !== \"string\") continue;\n const late = refWeek0.filter((day) => (resolveDateToken(v, day, tz) ?? v).slice(0, 10) > day);\n if (late.length) say(`tables (${t.token}).rows (${r.key}).${f.key}`, `\"${f.label}\" is ${v}, after the install day on a ${late.map((d) => WEEKDAY_NAMES[dayOfWeek(d)] ?? d).join(\", \")}; something requested or received has already happened.`);\n }\n }\n const rows = t.rows;\n const same = (x: unknown, y: unknown) => {\n const a = storeText(x);\n const b = storeText(y);\n if (a === null || b === null) return false;\n const qa = parseNumeric(a);\n const qb = parseNumeric(b);\n return qa && qb ? qCmp(qa, qb) === 0 : a.trim() === b.trim();\n };\n // A stored copy of a lookup the table already has.\n for (const l of t.fields.filter((ff) => ff.parityType === \"lookup\" && ff.via && ff.pick)) {\n const via = fieldOf(t.token, l.via!);\n const target = via?.relationTarget ? byToken.get(via.relationTarget) : undefined;\n if (!target) continue;\n const far = (r: SeedRow) => {\n const ref = r.values?.[l.via!];\n return target.rows.find((x) => x.key === (Array.isArray(ref) ? ref[0] : ref))?.values?.[l.pick!];\n };\n for (const sf of t.fields.filter((ff) => !isComputed(ff) && !isRelation(ff) && ff.key !== l.key)) {\n const have = rows.filter((r) => filled(r.values?.[sf.key]));\n if (have.length >= 3 && have.every((r) => same(r.values?.[sf.key], far(r)))) {\n say(`tables (${t.token}).fields (${sf.key})`, `\"${sf.label}\" repeats \"${l.label}\" on every row; drop it and use the lookup, which follows the linked record.`);\n }\n }\n }\n // A stored number that is just end − start.\n const moments = t.fields.filter((ff) => isDate(ff));\n for (const nf of t.fields.filter((ff) => isNumber(ff) && !isComputed(ff))) {\n for (const a of moments) {\n for (const b of moments) {\n if (a === b) continue;\n const have = rows.filter((r) => filled(r.values?.[nf.key]) && filled(r.values?.[a.key]) && filled(r.values?.[b.key]));\n if (have.length < 3) continue;\n const diffOk = (unit: number) =>\n have.every((r) => {\n const x = Date.parse(storeText(r.values?.[a.key]) ?? \"\");\n const y = Date.parse(storeText(r.values?.[b.key]) ?? \"\");\n const n = Number(storeText(r.values?.[nf.key]));\n return Number.isFinite(x) && Number.isFinite(y) && y > x && Math.abs((y - x) / unit - n) < 0.01;\n });\n const hours = diffOk(3_600_000);\n if (hours || diffOk(86_400_000)) {\n const whole = have.every((r) => Number.isInteger(Number(storeText(r.values?.[nf.key]))));\n const fx = hours ? (whole ? `DATEDIFF({${a.label}}, {${b.label}}, 'hours')` : `DATEDIFF({${a.label}}, {${b.label}}, 'minutes') / 60`) : `DATEDIFF({${a.label}}, {${b.label}}, 'days')`;\n say(`tables (${t.token}).fields (${nf.key})`, `\"${nf.label}\" is \"${b.label}\" minus \"${a.label}\" on every row; make it a formula field (parityType \"formula\", formula \"${fx}\") so it never drifts.`);\n }\n }\n }\n }\n }\n\n // ═══ cross-table realism, declared on the child table ═══\n const parentOf = (t: TemplateTable, relation: string, row: { values: Record<string, unknown> }) => {\n const rel = fieldOf(t.token, relation);\n const ptab = rel?.relationTarget ? byToken.get(rel.relationTarget) : undefined;\n const ref = row.values?.[relation];\n return { rel, ptab, prow: ptab?.rows.find((x) => x.key === (Array.isArray(ref) ? ref[0] : ref)) };\n };\n const titleOf = (t: TemplateTable | undefined, r: { key: string; values: Record<string, unknown> } | undefined) => (r ? storeText(r.values?.[t?.titleField ?? \"\"]) ?? r.key : \"\");\n const statusOf = (t: TemplateTable) => t.fields.find((f) => isChoice(f) && /(^|_)(status|stage)$/.test(f.key));\n for (const t of own) {\n const at = `tables (${t.token})`;\n // Single relations only: a list held on the parent (\"time_entries\") is the same link seen from the other side.\n const rels = t.fields.filter((f) => isRelation(f) && f.relationTarget && f.parityType !== \"attachment\" && !f.multi && (f.relationMax ?? 1) === 1 && own.some((p) => p.token === f.relationTarget));\n for (const d of t.childDates ?? []) {\n const rel = fieldOf(t.token, d.relation);\n const pf = rel?.relationTarget ? fieldOf(rel.relationTarget, d.parentField) : undefined;\n const cf = fieldOf(t.token, d.field);\n if (!rel?.relationTarget || !pf || !cf || !isDate(pf) || !isDate(cf)) {\n say(`${at}.childDates`, `[${d.relation}.${d.parentField} → ${d.field}] needs a relation of \"${t.token}\" and a date on each side.`);\n continue;\n }\n for (const r of t.rows) {\n const { ptab, prow } = parentOf(t, d.relation, r);\n const c = dayOfMoment(r.values?.[d.field]);\n const pd = prow ? dayOfMoment(prow.values?.[d.parentField]) : null;\n if (c && pd && c < pd) say(`${at}.rows (${r.key})`, `\"${titleOf(t, r)}\" has ${cf.label.toLowerCase()} ${c}, before its ${rel.label.toLowerCase()} \"${titleOf(ptab, prow)}\" ${pf.label.toLowerCase()} ${pd}.`);\n }\n }\n for (const w of t.withinParent ?? []) {\n const rel = fieldOf(t.token, w.relation);\n const pf = rel?.relationTarget ? fieldOf(rel.relationTarget, w.parentField) : undefined;\n const cf = fieldOf(t.token, w.field);\n if (!rel?.relationTarget || !pf || !cf || !isNumber(pf) || !isNumber(cf)) {\n say(`${at}.withinParent`, `[${w.field} ${w.op} ${w.relation}.${w.parentField}] needs a relation of \"${t.token}\" and a number on each side.`);\n continue;\n }\n for (const r of t.rows) {\n if (w.unless && w.unless.values.includes(storeText(r.values?.[w.unless.field]) ?? \"\")) continue;\n const { ptab, prow } = parentOf(t, w.relation, r);\n const c = parseNumeric(storeText(r.values?.[w.field]) ?? \"\");\n const pv = prow ? parseNumeric(storeText(prow.values?.[w.parentField]) ?? \"\") : null;\n if (c && pv && (w.op === \"<=\" ? qCmp(c, pv) > 0 : qCmp(c, pv) < 0)) {\n say(`${at}.rows (${r.key})`, `\"${titleOf(t, r)}\" has ${cf.label.toLowerCase()} ${storeText(r.values?.[w.field])}, ${w.op === \"<=\" ? \"above\" : \"below\"} \"${titleOf(ptab, prow)}\"'s ${pf.label.toLowerCase()} (${storeText(prow?.values?.[w.parentField])}).`);\n }\n }\n }\n for (const a of t.statusAgrees ?? []) {\n const rel = fieldOf(t.token, a.relation);\n const ptab = rel?.relationTarget ? byToken.get(rel.relationTarget) : undefined;\n if (!rel?.relationTarget || !ptab || !fieldOf(t.token, a.field) || !fieldOf(ptab.token, a.parentField)) {\n say(`${at}.statusAgrees`, `[${a.field} → ${a.relation}.${a.parentField}] needs a relation of \"${t.token}\" and a status field on each side.`);\n continue;\n }\n const perParent = new Map<string, string[]>();\n for (const r of t.rows) {\n const st = storeText(r.values?.[a.field]) ?? \"\";\n if (!a.childStatus.includes(st)) continue;\n const { prow } = parentOf(t, a.relation, r);\n if (!prow) continue;\n perParent.set(prow.key, [...(perParent.get(prow.key) ?? []), titleOf(t, r)]);\n const ps = storeText(prow.values?.[a.parentField]) ?? \"\";\n if (!a.parentStatus.includes(ps)) say(`${at}.rows (${r.key})`, `\"${titleOf(t, r)}\" is ${st}, so \"${titleOf(ptab, prow)}\" should be ${a.parentStatus.join(\" or \")}, but it is \"${ps}\".`);\n }\n if (a.maxPerParent !== undefined) {\n for (const [pk, kids] of perParent) {\n if (kids.length > a.maxPerParent) say(`${at}.statusAgrees`, `\"${titleOf(ptab, ptab.rows.find((x) => x.key === pk))}\" has ${kids.length} ${t.labelPlural.toLowerCase()} in ${a.childStatus.join(\"/\")} (${kids.join(\", \")}); at most ${a.maxPerParent}.`);\n }\n }\n }\n // A relation whose two sides both carry a schedule date, or both a status, states how they agree.\n for (const rel of rels) {\n const parent = own.find((p) => p.token === rel.relationTarget)!;\n const bothDates = t.fields.some((f) => isDate(f) && !f.absoluteDates) && parent.fields.some((f) => isDate(f) && !f.absoluteDates);\n const bothStatus = !!statusOf(t) && !!statusOf(parent);\n const datesStated = (t.childDates ?? []).some((d) => d.relation === rel.key) || [...(t.datePairs ?? []).flatMap((p) => [p.earlier, p.later]), ...(t.before ?? []).flat()].some((side) => side.startsWith(`${rel.key}.`));\n const statusStated = (t.statusAgrees ?? []).some((a) => a.relation === rel.key);\n const independent = (t.independentOf?.[rel.key] ?? \"\").trim().split(/\\s+/).length >= 3;\n if (independent) continue;\n if (bothDates && !datesStated) say(`${at}.childDates`, `\"${t.token}\" and its ${rel.label.toLowerCase()} (\"${parent.token}\") both carry dates; say how they agree, e.g. {\"relation\": \"${rel.key}\", \"field\": \"<this table's date>\", \"parentField\": \"<${parent.token}'s date>\"} or say why they are independent in independentOf {\"${rel.key}\": \"<reason>\"}.`);\n if (bothStatus && !statusStated) say(`${at}.statusAgrees`, `\"${t.token}\" and its ${rel.label.toLowerCase()} (\"${parent.token}\") both carry a status; say which child statuses need which parent status (statusAgrees), e.g. a Closed deal means a Sold listing.`);\n }\n // A stored count of linked rows is a rollup the store can compute. A bare \"size\" (a party of 4, a 12-inch\n // pipe) is a typed fact, not a count of anything linked, so only a roster/team/class size counts.\n for (const f of t.fields.filter((x) => isNumber(x) && !isComputed(x) && /(^|_)(count|roster_size|team_size|class_size|number_of|enrolled|headcount|players|members)($|_)/.test(x.key))) {\n const linked = own.find((c) => c.fields.some((cf) => isRelation(cf) && cf.relationTarget === t.token));\n const declared = (t.countMatches ?? []).find((c) => c.field === f.key);\n const linkers = own.filter((c) => c.fields.some((cf) => isRelation(cf) && cf.relationTarget === t.token)).map((c) => c.labelPlural.toLowerCase());\n if (linked && !declared) say(`${at}.fields (${f.key})`, `\"${f.label}\" stores a number the linked records already hold (${linkers.join(\", \")}); make it a rollup counting through the relation, so it can never disagree.`);\n if (declared) {\n const child = byToken.get(declared.childTable);\n for (const r of t.rows) {\n const n = (child?.rows ?? []).filter((c) => {\n const v = c.values?.[declared.childRelation];\n return Array.isArray(v) ? v.includes(r.key) : v === r.key;\n }).length;\n const stored = Number(storeText(r.values?.[f.key]) ?? NaN);\n if (!Number.isNaN(stored) && stored !== n) say(`${at}.rows (${r.key})`, `\"${titleOf(t, r)}\" says ${f.label.toLowerCase()} ${stored}, but ${n} ${child?.labelPlural.toLowerCase() ?? \"rows\"} link to it.`);\n }\n }\n }\n }\n const declaresRealism = own.some((t) => (t.childDates ?? []).length + (t.withinParent ?? []).length + (t.statusAgrees ?? []).length + (t.countMatches ?? []).length + (t.datePairs ?? []).length > 0);\n if ((spec.job === \"billing\" || spec.job === \"crm_pipeline\") && own.some((t) => t.fields.some((f) => isRelation(f) && own.some((p) => p.token === f.relationTarget))) && !declaresRealism) {\n say(\"tables\", `A ${spec.job === \"billing\" ? \"billing\" : \"pipeline\"} template states how its linked records agree (childDates, withinParent, statusAgrees or countMatches); this one states none.`);\n }\n\n // ── foreign text (cross-file) ──\n if (options.library) problems.push(...foreignTextProblems(raw, options.library));\n\n // ── Q2: capability present, declared exactly ────────────────────────────────\n const requires = spec.requires ?? [];\n const used = capabilitiesUsed(spec);\n for (const word of requires) {\n if (!(CAPABILITY_WORDS as readonly string[]).includes(word)) say(\"requires\", `\"${word}\" is not a capability word.`);\n else if (!used.has(word)) say(\"requires\", `It requires \"${word}\" but uses nothing that needs it.`);\n }\n for (const word of used) if (!requires.includes(word)) say(\"requires\", `The template uses \"${word}\" but does not declare it in requires.`);\n const waiting = [...new Set(requires)].map(capabilityStatus).filter((c) => !c.provided);\n\n if (options.profile === \"describe\") {\n const describeOwes = (p: UseCaseProblem) => {\n const root = p.at.split(/[.\\s[(]/)[0]!;\n if (GALLERY_ONLY_ROOTS.includes(root)) return false;\n if (seedLooks.has(p) || galleryBar.has(p)) return false;\n // Seed rows are a gallery card's; a describe spec may carry none.\n if (/^tables\\[\\d+\\] \\([^)]*\\)\\.rows$/.test(p.at)) return false;\n return true;\n };\n const kept = problems.filter(describeOwes);\n const waitingNow = [...used].map(capabilityStatus).filter((c) => !c.provided);\n return {\n ok: kept.length === 0,\n status: kept.length ? \"fail\" : waitingNow.length ? `waiting on ${[...new Set(waitingNow.map((w) => w.by))].sort().join(\", \")}` : \"pass\",\n problems: kept,\n waiting: waitingNow,\n };\n }\n const status: TemplateStatus = problems.length ? \"fail\" : waiting.length ? `waiting on ${[...new Set(waiting.map((w) => w.by))].sort().join(\", \")}` : \"pass\";\n return { ok: problems.length === 0, status, problems, waiting };\n}\n\n/** Validate and throw with every problem. A waiting template does not throw — it is held, not broken. */\nexport function assertTemplate(spec: TemplateSpec, options: ValidateOptions = {}): TemplateVerdict {\n const verdict = validateTemplate(spec, options);\n if (verdict.ok) return verdict;\n throw new Error(`The template \"${spec.id}\" is not ready — ${verdict.problems.length} problem(s):\\n${verdict.problems.map((p) => ` · ${p.at}: ${p.says}`).join(\"\\n\")}`);\n}\n\nconst RESTRICTED_KEY =\n /(^|_)(member_id|ssn|social_security|dob|date_of_birth|birth_date|allerg(y|ies)|diagnos(is|es)|medical_conditions?|conditions|medications?|current_medications|gate_code|access_code|door_code|alarm_code|password|passcode|pin|clinical_notes?|visit_notes?|progress_notes?|soap_notes?|case_notes?|legal_notes?|privileged_notes?|bank(_\\w+)?|routing(_number)?|account_number|iban|swift(_code)?|card(_number|_on_file)?|credit_card|cvv|cvc)($|_)/;\nconst RESTRICTED_LABEL = /\\b(bank|routing number|iban|card on file|credit card|card number|cvv|medical conditions?|medications?|diagnos[ie]s|case notes|legal notes|privileged)\\b/;\n// Personal health and identity floors bind PEOPLE tables only: a dog's date of birth is not\n// personal data. A table says what it holds (`subject`); undeclared, it holds people when it\n// has a name and a phone or email.\nconst PERSONAL_ONLY = /(^|_)(dob|date_of_birth|birth_date|allerg(y|ies)|diagnos(is|es)|medical_conditions?|conditions|medications?|current_medications|clinical_notes?|visit_notes?|progress_notes?|soap_notes?|member_id|ssn|social_security)($|_)/;\nconst holdsPeople = (t: Pick<TemplateTable, \"subject\" | \"fields\">) =>\n t.subject ? t.subject === \"person\" : t.fields.some((f) => /name/.test(f.key)) && t.fields.some((f) => f.parityType === \"phone\" || f.parityType === \"email\");\n\n/**\n * The lowest sensitivity the store accepts for a field, by what it holds: \"restricted\" (kept from the AI:\n * an identity or health fact about a person, a code, a card or bank number, privileged notes),\n * \"confidential\" (it reaches a person or a home: a phone, an email, an address), or null (no floor).\n * The template check refuses anything below it; the describe box fills an omitted sensitivity up to it.\n */\nexport function sensitivityFloorOf(\n table: Pick<TemplateTable, \"token\" | \"labelSingular\" | \"subject\" | \"fields\">,\n f: Pick<TemplateField, \"key\" | \"label\" | \"parityType\">,\n): \"restricted\" | \"confidential\" | null {\n const text = `${f.key} ${norm(f.label)}`;\n // \"Charges\" on a case or a person is a criminal record; on a bill, invoice or charge table it is money owed.\n const billingTable = /(invoice|bill|statement|receipt|payment|charge|fee|order|account)/i.test(`${table.token} ${table.labelSingular ?? \"\"}`);\n const criminalCharges = /(^|_)charges?($|_)/.test(f.key) && behaviorOf(f) === \"text\" && !billingTable;\n const phoneLike = behaviorOf(f) === \"text\" && /\\b(cell|mobile|phone)\\b/.test(norm(f.label));\n const personal = PERSONAL_ONLY.test(f.key) || /\\b(medical conditions?|medications?|diagnos[ie]s)\\b/.test(norm(f.label));\n const floored = (RESTRICTED_KEY.test(f.key) || RESTRICTED_LABEL.test(norm(f.label)) || criminalCharges) && (!personal || holdsPeople(table));\n if (floored) return \"restricted\";\n if (f.parityType === \"phone\" || phoneLike || f.parityType === \"email\" || /address|street/.test(text)) return \"confidential\";\n return null;\n}\n","// src/templates/plan.ts — @ai-matrx/records (templates)\n//\n// THE INSTALL PLAN: a TemplateSpec compiled into the ordered store-door calls that\n// `custom.template_install` runs AS THE PERSON, and the declaration `custom.template_declare`\n// takes. Chair (Unified Data System v6): one custom.template family, one install door.\n//\n// The plan compiles the same payloads (./payloads.ts) the retired browser installer walked — the same\n// translators (tableShellPayload, relationFieldSpec, rowsFor, derivedFieldSpec, viewSpec, formArgs,\n// bookingArgs, dashboardBlocks, stageRulesSpec, documentBody, rowActionList, notificationParts,\n// portalArgs), in the same order — with every id the store will mint written as a TOKEN the door\n// resolves at install time:\n//\n// ${org} the organization being installed into\n// ${ref:NAME} an id an earlier step saved as NAME (\"tables.patient\", \"fields.patient.dob\")\n// ${new:NAME} an id minted once per install (\"row.patient.rosa\")\n// ${date:TOKEN} an install-relative seed date (\"@today+1d 09:30\"), resolved in the business's\n// time zone on install day — so a calendar installed in March shows this week\n//\n// Each step may `save` ids out of its answer, `saveEach` a list of them, and say what it `made`\n// (kind + ref), which is the footprint uninstall archives. The door list is CLOSED on the server\n// (custom._template_doors); a step naming any other function is refused at declare time.\n//\n// seed.attachments: a template may carry `attachments` — files already in the file store (a\n// platform asset's `file_id`, name, mime, bytes). Each becomes a File record (custom.record_write\n// into the File kernel, the same door a file cell's attach uses) BEFORE the rows, and a row value\n// \"@file:<key>\" points at it.\n\nimport type { RecordsDataSource } from \"../ports\";\nimport {\n automationHeld,\n bookingArgs,\n bookingColumnsProblem,\n checklistSpec,\n dashboardBlocks,\n deferredRelations,\n derivedFieldSpec,\n formulaFieldSpec,\n formulaOrder,\n digestSpec,\n documentBody,\n drillDownDashboard,\n formArgs,\n isSelfDeclaredField,\n notificationParts,\n portalArgs,\n relationFieldSpec,\n relationPatches,\n rowActionList,\n rowLevels,\n rowsFor,\n selfDeclaredFieldSpec,\n stageFieldOf,\n stageRulesSpec,\n tableShellPayload,\n viewSpec,\n} from \"./payloads\";\nimport { RELATIVE_DATE, footprintOf, type TemplateBooking, type TemplateFootprint, type TemplateRowAction, type TemplateSpec } from \"./types\";\nimport { allTables } from \"./validate\";\nimport { membersAddRowsSteps } from \"./confidential\";\nimport { compileHostExtras, type TemplateHostExtras, type TemplatePlanBinding, type TemplatePlanExtraAgent } from \"./extras\";\nimport type { TemplateWorkflow as TemplateWorkflowSpec } from \"./types\";\n\nexport const INSTALL_PLAN_VERSION = 1 as const;\n\n/**\n * The seed-date grammar the server's `${date:…}` resolver (custom._template_date) must speak: the\n * whole client grammar (RELATIVE_DATE — business days `b`, the `~b` weekend snap, weekday anchors\n * `@mon` / `@next-tue`). Business days and anchors depend on the install day's weekday, so they\n * cannot be compiled away here; the server resolves them. The plan test holds every committed\n * template's tokens to this, and this to RELATIVE_DATE, so the two can never drift apart.\n */\nexport const SERVER_DATE_GRAMMAR: RegExp = RELATIVE_DATE;\n\n/** The store doors a plan may call — the server's custom._template_doors(), mirrored. */\nexport const TEMPLATE_PLAN_DOORS = [\n \"person_kernel_id\",\n \"file_kernel_id\",\n \"record_write\",\n \"record_write_many\",\n \"record_change_many\",\n \"table_from_example\",\n \"table_declare\",\n \"field_declare\",\n \"applicable_fields\",\n \"table_dimensions_set\",\n \"view_declare\",\n \"form_declare\",\n \"booking_declare\",\n \"dashboard_declare\",\n \"pipeline_declare\",\n \"doc_template_save\",\n \"action_declare\",\n \"subscription_declare\",\n \"rule_declare\",\n \"checklist_declare\",\n \"portal_declare\",\n \"query_table_homes\",\n] as const;\nexport type TemplatePlanDoor = (typeof TEMPLATE_PLAN_DOORS)[number];\n\n/** What uninstall archives for a step, by kind (custom.template_uninstall). */\nexport type TemplateMadeKind = \"table\" | \"field\" | \"view\" | \"form\" | \"dashboard\" | \"document\" | \"portal\" | \"record\" | \"rule\";\n\nexport interface TemplatePlanStep {\n /** Where in the walk this is, for a refusal a person can read (\"tables.patient\"). */\n label: string;\n door: TemplatePlanDoor;\n args: Record<string, unknown>;\n /** NAME → a path into the door's JSON answer ([] = the whole answer). */\n save?: Record<string, string[]>;\n /** Every element of the array at `array` saves `prefix + element[key]` = element[value]. */\n saveEach?: { array: string[]; key: string[]; value: string[]; prefix: string };\n made?: Array<{ kind: TemplateMadeKind; ref: string; title?: string; table?: string }>;\n}\n\nexport interface TemplatePlanAgent {\n platformAgent: { id: string; name: string };\n name: string;\n /**\n * Each variable bound to an installed table; the door answers each with its `table_id`.\n * `binding` (optional, Kits → Template merge): the full merge-field binding (./extras).\n */\n bindings: Array<{ variable: string; tableToken: string; describes: string; binding?: TemplatePlanBinding }>;\n}\n\nexport interface TemplateInstallPlan {\n planVersion: typeof INSTALL_PLAN_VERSION;\n /** The business's IANA zone: install-relative dates resolve in it. */\n timezone: string;\n steps: TemplatePlanStep[];\n /**\n * The host's step (the kit path's agent copy), answered by custom.template_install once installed.\n * Absent for a spec with no agent (a describe one-off): the door answers no agent step.\n */\n agent?: TemplatePlanAgent;\n /**\n * Ids known before the first step (`ref:tables.<token>` → an existing table's id, for each table that\n * `bindsTo` one): custom.template_install starts its id map with these, so every later step and every\n * `made` entry resolves the bound table exactly as if the install had made it.\n */\n ids?: Record<string, string>;\n /** Kits → Template merge (optional): more agent copies, then workflows — host steps too (./extras). */\n extraAgents?: TemplateHostExtras[\"extraAgents\"];\n workflows?: TemplateHostExtras[\"workflows\"];\n}\n\n/** The gallery card (lane 2 / lane 8): what custom.templates returns, and nothing else. */\nexport interface TemplateCard {\n name: string;\n persona: string;\n business: string;\n vertical: string;\n industry: string;\n job: string;\n audience: string;\n teaches: string;\n strengths: string[];\n requires: string[];\n footprint: TemplateFootprint;\n previewImage: string | null;\n}\n\n/** A file already in the file store, seeded as a File record at install (seed.attachments). */\nexport interface TemplateAttachment {\n key: string;\n fileId: string;\n name: string;\n mime: string;\n bytes: number;\n}\n\nexport type TemplateSpecWithAttachments = TemplateSpec & { attachments?: TemplateAttachment[] };\n\n/** `custom.template_declare`'s p_spec: the spec, its card and its compiled plan. */\nexport type TemplateDeclaration = TemplateSpecWithAttachments & {\n card: TemplateCard;\n installPlan: TemplateInstallPlan;\n organizationId?: string;\n};\n\nconst ROW_BATCH = 10;\nconst DERIVED = new Set([\"lookup\", \"rollup\"]);\nconst FILE_VALUE = /^@file:([A-Za-z0-9_.-]+)$/;\nconst TOKEN_NAME = /^[A-Za-z0-9_.:-]+$/;\n\nconst ref = (name: string): string => {\n if (!TOKEN_NAME.test(name)) throw new Error(`\"${name}\" cannot be an id name in an install plan (letters, digits, _ . : - only).`);\n return `\\${ref:${name}}`;\n};\nconst minted = (name: string): string => {\n if (!TOKEN_NAME.test(name)) throw new Error(`\"${name}\" cannot be an id name in an install plan (letters, digits, _ . : - only).`);\n return `\\${new:${name}}`;\n};\n\n/**\n * Every relative seed date becomes a `${date:…}` token (resolved by the door on install day), and\n * every \"@file:<key>\" a reference to the File record the attachments step made.\n */\nfunction tokenizeValues<T>(value: T, attachments: Set<string>): T {\n const walk = (v: unknown): unknown => {\n if (typeof v === \"string\") {\n if (RELATIVE_DATE.test(v)) return `\\${date:${v}}`;\n const f = FILE_VALUE.exec(v);\n if (f) {\n if (!attachments.has(f[1]!)) throw new Error(`A row points at the file \"${f[1]}\", which the template's attachments do not list.`);\n return ref(`files.${f[1]}`);\n }\n return v;\n }\n if (Array.isArray(v)) return v.map(walk);\n if (v && typeof v === \"object\") return Object.fromEntries(Object.entries(v).map(([k, x]) => [k, walk(x)]));\n return v;\n };\n return walk(value) as T;\n}\n\nexport function templateCard(spec: TemplateSpec): TemplateCard {\n return {\n name: spec.vertical,\n persona: spec.useCase,\n business: spec.business.name,\n vertical: spec.vertical,\n industry: spec.industry,\n job: spec.job,\n audience: spec.audience,\n teaches: spec.teaches,\n strengths: [...spec.strengths],\n requires: [...spec.requires],\n footprint: footprintOf(spec),\n previewImage: spec.previewImage ?? null,\n };\n}\n\n/** Compile `spec` into the plan custom.template_install runs. Throws, by name, on a spec it cannot install. */\nexport function compileInstallPlan(written: TemplateSpecWithAttachments): TemplateInstallPlan {\n const attachments = written.attachments ?? [];\n const attachmentKeys = new Set(attachments.map((a) => a.key));\n const spec = tokenizeValues({ ...written, attachments: undefined }, attachmentKeys) as TemplateSpec;\n // A table that binds to an existing one seeds none of its rows; a new table's row value that points\n // at one of those rows is dropped (the person's real rows are hers, not the template's sample).\n const bound = new Map(allTables(spec).filter((t) => t.bindsTo?.tableId).map((t) => [t.token, t.bindsTo!]));\n const has = (token: string, key: string) => bound.get(token)?.fields.includes(key) ?? false;\n const tables = allTables(spec).map((t) => {\n if (bound.has(t.token)) return { ...t, rows: [] };\n const toBound = t.fields.filter((f) => f.parityType === \"relation\" && f.relationTarget && bound.has(f.relationTarget)).map((f) => f.key);\n if (!toBound.length) return t;\n return { ...t, rows: t.rows.map((r) => ({ ...r, values: Object.fromEntries(Object.entries(r.values ?? {}).filter(([k]) => !toBound.includes(k))) })) };\n });\n const steps: TemplatePlanStep[] = [];\n const tableRef = (token: string): string => {\n if (!tables.some((t) => t.token === token)) throw new Error(`The template names a table \"${token}\" it does not have.`);\n return ref(`tables.${token}`);\n };\n const tableTokens: Record<string, string> = Object.fromEntries(tables.map((t) => [t.token, ref(`tables.${t.token}`)]));\n // A booking page writes its own `slot` (required) and booked/cancelled `status`; a template that\n // does not declare and seed them is refused here, before any step is planned (install.ts preflight).\n const bookingProblem = spec.extras\n .filter((e): e is TemplateBooking => e.kind === \"booking\")\n .map((b) => bookingColumnsProblem(tables, b))\n .find((p) => p);\n if (bookingProblem) throw new Error(bookingProblem);\n\n // 1 — the Home (a Person-kernel record, the same path records-ui's ExampleTables takes).\n steps.push({ label: \"home.kernel\", door: \"person_kernel_id\", args: {}, save: { \"kernel.person\": [] } });\n steps.push({\n label: \"home\",\n door: \"record_write\",\n args: { p_organization_id: \"${org}\", p_table_id: ref(\"kernel.person\"), p_data: { name: `${spec.business.name} Home` } },\n save: { home: [] },\n made: [{ kind: \"record\", ref: \"home\", title: `${spec.business.name} Home` }],\n });\n\n // 1a — seed.attachments: each file becomes a File record before any row points at it.\n if (attachments.length) {\n steps.push({ label: \"files.kernel\", door: \"file_kernel_id\", args: {}, save: { \"kernel.file\": [] } });\n for (const a of attachments) {\n steps.push({\n label: `files.${a.key}`,\n door: \"record_write\",\n args: { p_organization_id: \"${org}\", p_table_id: ref(\"kernel.file\"), p_data: { file_id: a.fileId, name: a.name, mime: a.mime, bytes: a.bytes } },\n save: { [`files.${a.key}`]: [] },\n made: [{ kind: \"record\", ref: `files.${a.key}`, title: a.name }],\n });\n }\n }\n\n // 1b — the tables, one per call (each changes the organization's shape). A bound table is not made:\n // only the plain columns it lacks are declared on it (relations and the rest follow below, as for any table).\n for (const t of tables) {\n if (bound.has(t.token)) {\n for (const f of t.fields.filter((x) => !DERIVED.has(x.parityType) && x.parityType !== \"formula\" && x.parityType !== \"relation\" && !isSelfDeclaredField(x) && !has(t.token, x.key))) {\n steps.push({\n label: `bound.${t.token}.${f.key}`,\n door: \"field_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(t.token), p_spec: selfDeclaredFieldSpec(f) },\n save: { [`fields.${t.token}.${f.key}`]: [] },\n made: [{ kind: \"field\", ref: `fields.${t.token}.${f.key}`, table: `tables.${t.token}` }],\n });\n }\n continue;\n }\n steps.push({\n label: `tables.${t.token}`,\n door: \"table_from_example\",\n args: { p_organization_id: \"${org}\", p_home_id: ref(\"home\"), p_example: tableShellPayload(spec, t) },\n saveEach: { array: [\"tables\"], key: [\"token\"], value: [\"table_id\"], prefix: \"tables.\" },\n made: [{ kind: \"table\", ref: `tables.${t.token}`, title: t.name }],\n });\n }\n\n // 1b' — lane 12 P7: tables whose members add their own rows (members_add_rows on the Table document,\n // custom.record_change_many on the Table kernel, as the person who just made them).\n steps.push(...membersAddRowsSteps(spec, tableRef));\n\n // 1c — the relation columns.\n for (const t of tables) {\n for (const f of t.fields.filter((x) => x.parityType === \"relation\" && x.relationTarget && !has(t.token, x.key))) {\n steps.push({\n label: `relations.${t.token}.${f.key}`,\n door: \"field_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(t.token), p_spec: relationFieldSpec(f, tableRef(f.relationTarget!)) },\n save: { [`fields.${t.token}.${f.key}`]: [] },\n made: [{ kind: \"field\", ref: `fields.${t.token}.${f.key}`, table: `tables.${t.token}` }],\n });\n }\n }\n\n // 1c' — the columns table_from_example cannot make as declared (a date AND a time; a column\n // with a default), before any row needs them.\n for (const t of tables) {\n for (const f of t.fields.filter((x) => isSelfDeclaredField(x) && !has(t.token, x.key))) {\n steps.push({\n label: `self_declared.${t.token}.${f.key}`,\n door: \"field_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(t.token), p_spec: selfDeclaredFieldSpec(f) },\n save: { [`fields.${t.token}.${f.key}`]: [] },\n made: [{ kind: \"field\", ref: `fields.${t.token}.${f.key}`, table: `tables.${t.token}` }],\n });\n }\n }\n\n // 1d — the rows, a table only after the tables it points at, ids minted per install. Links that\n // cannot travel with their row (a circle, a link to its own table) are set once every row exists.\n const rowIds = new Map<string, string>();\n for (const t of tables) for (const r of t.rows) rowIds.set(`${t.token}.${r.key}`, minted(`row.${t.token}.${r.key}`));\n const deferred = deferredRelations(tables);\n for (const level of rowLevels(tables)) {\n for (const t of level) {\n const { rows, ids } = rowsFor(t, rowIds, deferred.get(t.token));\n for (let i = 0; i < rows.length; i += ROW_BATCH) {\n steps.push({\n label: `rows.${t.token}.${i / ROW_BATCH + 1}`,\n door: \"record_write_many\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(t.token), p_rows: rows.slice(i, i + ROW_BATCH), p_ids: ids.slice(i, i + ROW_BATCH) },\n });\n }\n }\n }\n\n for (const t of tables) {\n const changes = relationPatches(t, rowIds, deferred.get(t.token));\n for (let i = 0; i < changes.length; i += ROW_BATCH) {\n steps.push({\n label: `links.${t.token}.${i / ROW_BATCH + 1}`,\n door: \"record_change_many\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(t.token), p_changes: changes.slice(i, i + ROW_BATCH) },\n });\n }\n }\n\n // 2 — lookups and rollups.\n for (const t of tables) {\n for (const f of t.fields.filter((x) => DERIVED.has(x.parityType) && !has(t.token, x.key))) {\n steps.push({\n label: `derived.${t.token}.${f.key}`,\n door: \"field_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(t.token), p_spec: derivedFieldSpec(f) },\n save: { [`fields.${t.token}.${f.key}`]: [] },\n made: [{ kind: \"field\", ref: `fields.${t.token}.${f.key}`, table: `tables.${t.token}` }],\n });\n }\n }\n\n // 2b — formulas, after every column they read; never seeded (install.ts formula_fields).\n for (const t of tables) {\n for (const f of formulaOrder(t).filter((x) => !has(t.token, x.key))) {\n steps.push({\n label: `formula.${t.token}.${f.key}`,\n door: \"field_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(t.token), p_spec: formulaFieldSpec(f) },\n save: { [`fields.${t.token}.${f.key}`]: [] },\n made: [{ kind: \"field\", ref: `fields.${t.token}.${f.key}`, table: `tables.${t.token}` }],\n });\n }\n }\n\n // 3 — field ids for the parts that name a Field by id (documents, row actions, any-of views).\n const needIds = new Set<string>([\n ...spec.extras.filter((e) => e.kind === \"document\" || e.kind === \"row_action\").map((e) => (e as { table: string }).table),\n ...spec.views.filter((v) => v.anyOf && Object.keys(v.anyOf).length).map((v) => v.table),\n ]);\n const fieldRefs = (token: string): Record<string, string> => {\n const t = tables.find((x) => x.token === token);\n return Object.fromEntries((t?.fields ?? []).map((f) => [f.key, ref(`fields.${token}.${f.key}`)]));\n };\n for (const token of needIds) {\n steps.push({\n label: `field_ids.${token}`,\n door: \"applicable_fields\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(token), p_record_type: null },\n saveEach: { array: [], key: [\"data\", \"key\"], value: [\"id\"], prefix: `fields.${token}.` },\n });\n }\n\n // 4 — Dimensions.\n // A bound table keeps the Dimensions its organization already set.\n for (const d of spec.dimensions.filter((x) => !bound.has(x.table))) {\n const overrides: Record<string, unknown> = {};\n if (d.dimensions) overrides[\"dimensions\"] = d.dimensions;\n if (d.measures) overrides[\"measures\"] = d.measures;\n if (d.paths) overrides[\"paths\"] = d.paths;\n if (d.default) overrides[\"default\"] = d.default;\n steps.push({\n label: `dimensions.${d.table}`,\n door: \"table_dimensions_set\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(d.table), p_overrides: overrides },\n });\n }\n\n // 5 — views.\n for (const v of spec.views) {\n steps.push({\n label: `views.${v.token}`,\n door: \"view_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(v.table), p_spec: viewSpec(v, fieldRefs(v.table)) },\n save: { [`views.${v.token}`]: [] },\n made: [{ kind: \"view\", ref: `views.${v.token}`, title: v.name, table: `tables.${v.table}` }],\n });\n }\n\n // 6 — forms.\n for (const f of spec.forms) {\n steps.push({\n label: `forms.${f.token}`,\n door: \"form_declare\",\n args: formArgs(\"${org}\", tableRef(f.table), f),\n save: { [`forms.${f.token}`]: [] },\n made: [{ kind: \"form\", ref: `forms.${f.token}`, title: f.name, table: `tables.${f.table}` }],\n });\n }\n\n // 7 — extras, in the order the spec lists them, except that documents come first: a checklist step may hand\n // over a document, so the document must exist before the checklist that names it, wherever the writer listed\n // it (T0554 listed its renewal letter after its renewal checklist). A table's row actions are one list, last.\n const actionsByTable = new Map<string, TemplateRowAction[]>();\n const formRefs = Object.fromEntries(spec.forms.map((f) => [f.token, ref(`forms.${f.token}`)]));\n const documentRefs = Object.fromEntries(\n spec.extras.filter((e) => e.kind === \"document\").map((e) => [(e as { token: string }).token, ref(`documents.${(e as { token: string }).token}`)]),\n );\n const extrasInOrder = [...spec.extras.filter((e) => e.kind === \"document\"), ...spec.extras.filter((e) => e.kind !== \"document\")];\n for (const e of extrasInOrder) {\n switch (e.kind) {\n case \"booking\":\n steps.push({\n label: `bookings.${e.token}`,\n door: \"booking_declare\",\n args: bookingArgs(\"${org}\", tableRef(e.table), e),\n save: { [`bookings.${e.token}.form`]: [\"form_id\"], [`bookings.${e.token}.slots`]: [\"slot_table_id\"] },\n made: [\n { kind: \"form\", ref: `bookings.${e.token}.form`, title: e.title, table: `tables.${e.table}` },\n { kind: \"table\", ref: `bookings.${e.token}.slots`, title: `${e.title} slots` },\n ],\n });\n break;\n case \"dashboard\":\n steps.push({\n label: `dashboards.${e.token}`,\n door: \"dashboard_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(e.table), p_name: e.name, p_blocks: dashboardBlocks(e, tableTokens), p_presentation: {}, p_dashboard_id: null },\n save: { [`dashboards.${e.token}`]: [] },\n made: [{ kind: \"dashboard\", ref: `dashboards.${e.token}`, title: e.name, table: `tables.${e.table}` }],\n });\n break;\n case \"drill_down\": {\n // The drill path is the table's own Dimensions (step 4); its entry point is a dashboard.\n const d = drillDownDashboard(e, spec.dimensions);\n steps.push({\n label: `dashboards.${e.token}`,\n door: \"dashboard_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(e.table), p_name: d.name, p_blocks: d.blocks, p_presentation: {}, p_dashboard_id: null },\n save: { [`dashboards.${e.token}`]: [] },\n made: [{ kind: \"dashboard\", ref: `dashboards.${e.token}`, title: e.name, table: `tables.${e.table}` }],\n });\n break;\n }\n case \"digest\": {\n const view = spec.views.find((v) => v.token === e.view);\n if (!view) throw new Error(`The digest \"${e.name}\" sends the view \"${e.view}\", which this template does not declare.`);\n steps.push({\n label: `digests.${e.token}`,\n door: \"subscription_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(view.table), p_spec: digestSpec(e, ref(`views.${e.view}`)) },\n save: { [`digests.${e.token}`]: [] },\n made: [{ kind: \"rule\", ref: `digests.${e.token}`, title: e.name, table: `tables.${view.table}` }],\n });\n break;\n }\n case \"stage_rules\":\n steps.push({\n label: `stage_rules.${e.token}`,\n door: \"pipeline_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(e.table), p_spec: stageRulesSpec(e) },\n });\n break;\n case \"document\":\n steps.push({\n label: `documents.${e.token}`,\n door: \"doc_template_save\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(e.table), p_name: e.name, p_body: documentBody(e, fieldRefs(e.table), spec.business.name), p_template_id: null },\n save: { [`documents.${e.token}`]: [] },\n made: [{ kind: \"document\", ref: `documents.${e.token}`, title: e.name, table: `tables.${e.table}` }],\n });\n break;\n case \"row_action\":\n actionsByTable.set(e.table, [...(actionsByTable.get(e.table) ?? []), e]);\n break;\n case \"notification\": {\n const n = notificationParts(e, stageFieldOf(tables, e.when.table, e.when.stage));\n steps.push({\n label: `notifications.${e.token}.view`,\n door: \"view_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(e.when.table), p_spec: n.view },\n save: { [`notifications.${e.token}.view`]: [] },\n made: [{ kind: \"view\", ref: `notifications.${e.token}.view`, title: e.name, table: `tables.${e.when.table}` }],\n });\n steps.push({\n label: `notifications.${e.token}`,\n door: \"subscription_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(e.when.table), p_spec: { ...n.subscription, saved_view_id: ref(`notifications.${e.token}.view`) } },\n save: { [`notifications.${e.token}`]: [] },\n made: [{ kind: \"rule\", ref: `notifications.${e.token}`, title: e.name, table: `tables.${e.when.table}` }],\n });\n break;\n }\n case \"portal\":\n steps.push({\n label: `portals.${e.token}`,\n door: \"portal_declare\",\n args: portalArgs(\"${org}\", e, tableTokens),\n save: { [`portals.${e.token}`]: [] },\n made: [{ kind: \"portal\", ref: `portals.${e.token}`, title: e.title, table: `tables.${e.clientTable}` }],\n });\n break;\n case \"checklist\":\n // A checklist template is a record: uninstall archives it like one.\n for (const t of [e.aboutTable, ...(e.trigger && e.trigger.kind !== \"manual\" ? [e.trigger.table] : [])]) tableRef(t);\n for (const st of e.steps) {\n const r = st.requires;\n if (r?.kind === \"form\" && !formRefs[r.form]) throw new Error(`The checklist \"${e.name}\" asks for the form \"${r.form}\", which this template does not declare.`);\n if (r?.kind === \"document\" && !documentRefs[r.document]) throw new Error(`The checklist \"${e.name}\" asks for the document \"${r.document}\", which this template does not declare.`);\n }\n steps.push({\n label: `checklists.${e.token}`,\n door: \"checklist_declare\",\n args: { p_organization_id: \"${org}\", p_spec: checklistSpec(e, tableTokens, formRefs, documentRefs), p_template_id: null },\n save: { [`checklists.${e.token}`]: [\"template_id\"] },\n made: [{ kind: \"record\", ref: `checklists.${e.token}`, title: e.name }],\n });\n break;\n case \"automation\":\n throw new Error(automationHeld(e));\n default:\n throw new Error(`The install plan has no door for a ${(e as { kind: string }).kind} yet (\"${(e as { token?: string }).token ?? \"?\"}\"), so this template cannot be declared until it does.`);\n }\n }\n for (const [token, actions] of actionsByTable) {\n steps.push({\n label: `row_actions.${token}`,\n door: \"action_declare\",\n args: { p_organization_id: \"${org}\", p_table_id: tableRef(token), p_actions: rowActionList(actions, fieldRefs(token)) },\n });\n }\n\n const host = compileHostExtras(spec);\n const agent = spec.agent as TemplateSpec[\"agent\"] | undefined;\n return {\n planVersion: INSTALL_PLAN_VERSION,\n timezone: spec.business.timezone || \"UTC\",\n steps,\n ...(agent?.platformAgent\n ? {\n agent: {\n platformAgent: agent.platformAgent,\n name: agent.name,\n bindings: (agent.variables ?? []).map((v) => {\n const binding = host.agentBindings.get(v.name);\n return { variable: v.name, tableToken: v.table, describes: v.describes, ...(binding ? { binding } : {}) };\n }),\n },\n }\n : {}),\n ...(bound.size ? { ids: Object.fromEntries([...bound].map(([token, b]) => [`ref:tables.${token}`, b.tableId])) } : {}),\n ...host.extras,\n };\n}\n\n/** `custom.template_declare`'s p_spec for one template: the spec, its card and its plan. */\nexport function templateDeclaration(spec: TemplateSpecWithAttachments, organizationId?: string): TemplateDeclaration {\n return {\n ...spec,\n card: templateCard(spec),\n installPlan: compileInstallPlan(spec),\n ...(organizationId ? { organizationId } : {}),\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// The client loop every host calls (lane 2's gallery, lane 8's publisher, lane 9's scopes)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** The family's budgeted doors: each call does what fits in its budget and says `done`. */\nexport type TemplateFamilyDoor = \"template_install\" | \"template_uninstall\" | \"template_restore\";\n\n/** What the three doors answer (custom._template_answer). */\nexport interface TemplateDoorAnswer {\n install_id?: string;\n state?: \"installing\" | \"installed\" | \"refused\" | \"uninstalling\" | \"uninstalled\";\n ok?: boolean;\n done?: boolean;\n already?: boolean;\n next_step?: number;\n steps?: number;\n made?: Array<{ kind: string; id: string | null; ref: string; title: string | null; table_id: string | null }>;\n archived?: unknown[];\n left?: unknown[];\n refusal?: Record<string, unknown> | null;\n agent?: { platform_agent: { id: string; name: string }; name: string; bindings: Array<Record<string, unknown>>; copied: boolean } | null;\n /**\n * Kits → Template merge (custom._template_answer, only for a template that carries them): the plan's\n * extra agents and workflows, and the ids the host resolves them with — `tables.<token>` → table\n * id, `row.<token>.<rowKey>` → seed row id.\n */\n host?: { extra_agents?: TemplatePlanExtraAgent[] | null; workflows?: TemplateWorkflowSpec[] | null; ids?: Record<string, string> } | null;\n [key: string]: unknown;\n}\n\nexport interface TemplateDoorRun {\n ok: boolean;\n answer: TemplateDoorAnswer | null;\n /** The transport's own error (the 8 s ceiling, a lock wait), after the retries ran out. */\n error?: { code: string | null; message: string; hint: string | null };\n calls: number;\n}\n\nconst TRANSIENT = new Set([\"57014\", \"55P03\", \"40P01\", \"40001\"]);\n\n/**\n * Call one of the family's budgeted doors until it says done: install (p_template_id), uninstall\n * or restore (p_install_id). A refusal comes back verbatim (`ok: false`, answer.refusal); a lock\n * wait or a statement timeout is retried, because a call that times out changed nothing.\n */\nexport async function runTemplateDoor(\n source: RecordsDataSource,\n door: TemplateFamilyDoor,\n organizationId: string,\n id: string,\n options: { maxCalls?: number; onCall?: (answer: TemplateDoorAnswer) => void } = {},\n): Promise<TemplateDoorRun> {\n const max = options.maxCalls ?? 40;\n const key = door === \"template_install\" ? \"p_template_id\" : \"p_install_id\";\n let answer: TemplateDoorAnswer | null = null;\n let error: TemplateDoorRun[\"error\"];\n let calls = 0;\n while (calls < max) {\n calls++;\n const { data, error: e } = await source.rpc(door, { p_organization_id: organizationId, [key]: id }, { schema: \"custom\" });\n if (e) {\n error = { code: e.code ?? null, message: e.message, hint: e.hint ?? null };\n if (e.code && TRANSIENT.has(e.code)) continue;\n return { ok: false, answer, error, calls };\n }\n answer = (data ?? null) as TemplateDoorAnswer | null;\n if (answer) options.onCall?.(answer);\n if (!answer) return { ok: false, answer, calls };\n if (answer.done) return { ok: true, answer, calls };\n if (answer.state === \"refused\") {\n const code = typeof answer.refusal?.[\"code\"] === \"string\" ? (answer.refusal[\"code\"] as string) : \"\";\n if (TRANSIENT.has(code)) continue;\n return { ok: false, answer, calls };\n }\n }\n return { ok: false, answer, ...(error ? { error } : {}), calls };\n}\n\n/** Tables a plan makes (for a suite): the `tables.*` refs its steps save. */\nexport function planTables(plan: TemplateInstallPlan): string[] {\n return plan.steps.flatMap((s) => (s.made ?? []).filter((m) => m.kind === \"table\").map((m) => m.ref));\n}\n\n","// src/choice.ts — @ai-matrx/records\n//\n// WHAT A CHOICE VALUE IS, in one place, for every screen and every caller.\n//\n// A pick-list is a Table and an option is a Record of it (FLD-5 / FLD-6) — that part is\n// unchanged and is the store being right. What a CELL holds is not the option record's id: it\n// is the option's own stable key, a short word derived from its title when the option is born,\n// unique within its list and never rewritten. So renaming \"Circle\" to \"Round\" rewrites no row,\n// and nothing — no person, no agent, no import — is ever asked to know a uuid for a word the\n// product showed them.\n//\n// The read doors hand back the LABEL in the cell and name the key beside it in `_choices`:\n//\n// { \"kind\": \"Circle\",\n// \"_choices\": { \"kind\": { \"key\": \"circle\", \"label\": \"Circle\", \"id\": \"…\",\n// \"retired\": false, \"reason\": null } } }\n//\n// A multi-choice cell reads as an array of labels and its `_choices` entry is an array in the\n// same order. A RETIRED option is in there too, with `retired: true` and the reason — a value\n// whose choice was retired reads as its label and says what happened rather than vanishing.\n//\n// WRITING takes the label, the key, or (so nothing that worked yesterday breaks) the option\n// record's id. The store normalises all three to the key on the way in and refuses a word that\n// names no choice, naming the choices themselves.\n\nimport type { RecordDocument, StoredRecord } from \"./record\";\nimport { isUuidShape } from \"@ai-matrx/kit/uuid\";\n\n/** One option, as `_choices` names it and as `optionsOf` returns it. */\nexport interface ChoiceOption {\n /** The stable key the cell actually holds. */\n key: string;\n /** What a person reads. */\n label: string;\n /** The option RECORD's id, for a caller that needs the row itself. */\n id?: string;\n /** True when the option was retired: still readable, no longer pickable. */\n retired?: boolean;\n /** Why it is no longer offered, in a sentence, when it is retired. */\n reason?: string | null;\n}\n\n/**\n * The stable key of an option RECORD as `custom.field_options` returns it.\n *\n * It lives in `metadata.option_key`, not in the document: FLD-5 keeps a category to one title\n * field, and the key is the store's own bookkeeping rather than a column anybody declared.\n * The fallback is the same slug the store derives, so an option written by something that has\n * not caught up still answers.\n */\nexport function optionKey(option: StoredRecord): string {\n const stored = option.metadata?.[\"option_key\"];\n if (typeof stored === \"string\" && stored.trim() !== \"\") return stored;\n return choiceSlug(optionLabel(option));\n}\n\n/** What a person reads on an option record. */\nexport function optionLabel(option: StoredRecord): string {\n const doc = option.data as RecordDocument | undefined;\n const title = doc?.[\"title\"] ?? doc?.[\"name\"];\n if (typeof title === \"string\" && title.trim() !== \"\") return title;\n return \"Unnamed choice\";\n}\n\n/**\n * The store's own slug, mirrored so a client can predict a key without a round trip.\n * `custom.choice_slug` is the original; a title with nothing a-z0-9 in it gets a short hash of\n * itself there, and this returns the empty-ish fallback rather than guessing a hash — a caller\n * that needs the real key for such a title reads it off the option.\n */\nexport function choiceSlug(word: string): string {\n const slug = word\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 55);\n return slug === \"\" ? \"choice\" : slug;\n}\n\n/**\n * Does this stored (or typed) value name this option? The key, the label and the option's own\n * id all name the same choice, and a control has to recognise every one of them: what the read\n * door hands it is the LABEL, what the store holds is the KEY, and what a screen written before\n * this contract sends is the ID.\n */\nexport function isTheChosen(option: StoredRecord, value: unknown): boolean {\n if (typeof value !== \"string\") return false;\n const asked = value.trim().toLowerCase();\n if (asked === \"\") return false;\n return (\n asked === optionKey(option).toLowerCase() ||\n asked === optionLabel(option).toLowerCase() ||\n asked === option.id.toLowerCase()\n );\n}\n\n/** Every value of one cell, as strings, whether the Field is multi or not. */\nexport function choiceValuesOf(value: unknown): string[] {\n if (Array.isArray(value)) return value.filter((v): v is string => typeof v === \"string\");\n if (typeof value === \"string\" && value !== \"\") return [value];\n return [];\n}\n\n/**\n * What the read door said about one column's choices: the key behind the label, and whether the\n * option was retired and why. Returns an empty array when the document carries no `_choices`\n * entry for that column, which is also what a document written before this contract looks like.\n */\nexport function choicesOf(document: RecordDocument | undefined, fieldKeyOrId: string): ChoiceOption[] {\n const block = document?.[\"_choices\"];\n if (!block || typeof block !== \"object\") return [];\n const entry = (block as Record<string, unknown>)[fieldKeyOrId];\n if (!entry) return [];\n const list = Array.isArray(entry) ? entry : [entry];\n return list.filter((x): x is ChoiceOption => !!x && typeof x === \"object\" && typeof (x as ChoiceOption).key === \"string\");\n}\n\n/** True when this cell's value points at a choice that has since been retired. */\nexport function holdsARetiredChoice(document: RecordDocument | undefined, fieldKeyOrId: string): boolean {\n return choicesOf(document, fieldKeyOrId).some((c) => c.retired === true);\n}\n\n/** True when a token looks like a uuid — which a choice value is no longer allowed to be. */\nexport function looksLikeAnId(value: unknown): boolean {\n return typeof value === \"string\" && isUuidShape(value);\n}\n\n/* ═══ WORDS TYPED INTO A CHOICE CELL THAT ARE NOT A CHOICE (lane CHOICE-COLUMN-EDIT) ═══════════\n *\n * A software team's \"Account Type\" column offers Cursor · Claude · Codex, and somebody types\n * \"Gemini\". Three answers are possible and the store has a door for each: add it to the choices\n * and the cell takes it (`recordUpdateAddingChoices`), keep it as typed on a column that takes\n * other values (`config.allow_other` — an ordinary `recordUpdate`), or refuse it. Which one is\n * the Feature Knob `custom/choice_nudge` (`choiceNudge()`), and this is the ONE place that\n * reads it, so the grid, the record form and every other surface answer the same way.\n */\n\n/** The Feature Knob `custom/choice_nudge`: ask (the default), always add, or never add. */\nexport type ChoiceNudge = \"ask\" | \"always_add\" | \"never_add\";\n\nexport const CHOICE_NUDGES: readonly ChoiceNudge[] = [\"ask\", \"always_add\", \"never_add\"];\n\n/** Any answer the knob door gives, as one of the three; anything unknown is the default, `ask`. */\nexport function asChoiceNudge(value: unknown): ChoiceNudge {\n return typeof value === \"string\" && (CHOICE_NUDGES as readonly string[]).includes(value) ? (value as ChoiceNudge) : \"ask\";\n}\n\n/** What `decideTypedChoice` answers. */\nexport type TypedChoiceDecision =\n /** Nothing was typed. */\n | { decision: \"empty\" }\n /** The words name a live choice (by its words or its key, any case): write `key`. */\n | { decision: \"chosen\"; key: string; label: string }\n /** Ask the person. `keepOffered` is true only when the column takes other values. */\n | { decision: \"ask\"; words: string; keepOffered: boolean }\n /** Add the words to the choices and the cell takes them — without asking (`always_add`). */\n | { decision: \"add\"; words: string }\n /** Keep the words as typed, an \"other\" value (`never_add` on a column that takes other values). */\n | { decision: \"keep_as_typed\"; words: string }\n /** The words are not one of the choices and nothing may add them (`never_add`, closed column). */\n | { decision: \"not_a_choice\"; words: string };\n\n/** A choice as either door hands it: an option record (`fieldOptions`) or a `_choices` entry. */\nexport type ChoiceLike = StoredRecord | ChoiceOption;\n\nfunction choiceKeyAndLabel(option: ChoiceLike): { key: string; label: string; retired: boolean } {\n if (typeof (option as ChoiceOption).key === \"string\" && typeof (option as ChoiceOption).label === \"string\") {\n const o = option as ChoiceOption;\n return { key: o.key, label: o.label, retired: o.retired === true };\n }\n // `custom.field_options` answers LIVE options only, so an option record is never retired.\n const record = option as StoredRecord;\n return { key: optionKey(record), label: optionLabel(record), retired: false };\n}\n\n/**\n * THE ONE DECISION for words typed into a choice cell.\n *\n * `options` are the column's choices; a retired one is not pickable, so words naming only a\n * retired choice are treated as new (adding them brings the retired choice back, which is what\n * the store does). `nudge` absent or unknown is `ask`.\n */\nexport function decideTypedChoice(args: {\n words: string;\n options: readonly ChoiceLike[];\n allowOther: boolean;\n nudge?: ChoiceNudge | string | null | undefined;\n}): TypedChoiceDecision {\n const words = args.words.trim();\n if (words === \"\") return { decision: \"empty\" };\n const asked = words.toLowerCase();\n for (const option of args.options) {\n const { key, label, retired } = choiceKeyAndLabel(option);\n if (retired) continue;\n if (label.toLowerCase() === asked || key.toLowerCase() === asked) return { decision: \"chosen\", key, label };\n }\n const nudge = asChoiceNudge(args.nudge);\n if (nudge === \"always_add\") return { decision: \"add\", words };\n if (nudge === \"never_add\") return args.allowOther ? { decision: \"keep_as_typed\", words } : { decision: \"not_a_choice\", words };\n return { decision: \"ask\", words, keepOffered: args.allowOther };\n}\n\n/* ═══ REMOVING A CHOICE THAT RECORDS STILL HOLD (lane CHOICE-TAILS, 2026-09-27) ════════════════\n *\n * A dental front desk's \"Visit Type\" offers Cleaning · Exam · X-ray · Whitening, and the office\n * stops booking X-rays as their own visit. Removing X-ray used to leave every record that held it\n * holding a retired choice, with nobody asked. Now the column editor asks, Notion-style:\n * \"3 records use “X-ray”.\" — move them to another choice, keep the words as other values (only\n * where the column takes other values), or clear them. The answer goes in the SAME save as the\n * list (`fieldUpdateRehomingChoices`), and that save answers its own undo.\n */\n\n/** How many records hold one choice (`custom.field_choice_usage`), keyed by the option's id. */\nexport interface ChoiceUsage {\n key: string;\n words: string;\n retired: boolean;\n /** Live records the caller may see whose cell holds the choice. */\n records: number;\n}\n\n/** Where the records of a removed choice go. */\nexport type ChoiceRehome =\n | { then: \"move\"; to: string }\n | { then: \"keep\" }\n | { then: \"clear\" };\n\n/** One cell as it was before a rehoming save — what its undo writes back. */\nexport interface ChoiceCellBack {\n record_id: string;\n value: unknown;\n}\n\n/** What `fieldUpdateRehomingChoices` answers. */\nexport interface ChoicesRehomed {\n field_id: string;\n rehomed: Array<{ choice_id: string; words: string; then: ChoiceRehome[\"then\"]; to: string | null; records: number }>;\n cells_back: number;\n /** Send `{ patch: { options: undo.options }, cells_back: undo.cells_back }` to put it all back. */\n undo: { options: Array<{ id: string; words: string }>; cells_back: ChoiceCellBack[] };\n}\n\n/**\n * THE CHOICES A LIST NO LONGER NAMES THAT RECORDS STILL HOLD — the ones the editor must ask about.\n * `beforeIds` is the list as the store answered it, `afterIds` the list as the person has it now.\n */\nexport function removedChoicesInUse(\n beforeIds: readonly string[],\n afterIds: readonly string[],\n usage: Readonly<Record<string, ChoiceUsage>> | null | undefined,\n): Array<{ id: string; words: string; records: number }> {\n if (!usage) return [];\n const kept = new Set(afterIds);\n return beforeIds\n .filter((id) => !kept.has(id))\n .map((id) => ({ id, words: usage[id]?.words ?? \"\", records: usage[id]?.records ?? 0 }))\n .filter((c) => c.records > 0);\n}\n\n/** “1 record uses “X-ray”.” · “3 records use “X-ray”.” — the question's first line. */\nexport function recordsUseSentence(records: number, words: string): string {\n return `${records} ${records === 1 ? \"record uses\" : \"records use\"} “${words}”.`;\n}\n\n/** What the answer will do, said before Save: “3 records move to “Exam”.” */\nexport function rehomeSentence(records: number, words: string, rehome: ChoiceRehome, toWords?: string): string {\n const n = `${records} ${records === 1 ? \"record\" : \"records\"}`;\n if (rehome.then === \"move\") return `${n} that ${records === 1 ? \"holds\" : \"hold\"} “${words}” ${records === 1 ? \"moves\" : \"move\"} to “${toWords ?? \"another choice\"}”.`;\n if (rehome.then === \"keep\") return `${n} ${records === 1 ? \"keeps\" : \"keep\"} “${words}” as another value.`;\n return `${n} that ${records === 1 ? \"holds\" : \"hold\"} “${words}” ${records === 1 ? \"is\" : \"are\"} cleared.`;\n}\n","// src/memory/world.ts — @ai-matrx/records/memory (lane CHAIR-GALLERY-2, 2026-10-05)\n//\n// A TEMPLATE, INSTALLED INTO MEMORY. `templateWorld(spec)` walks the template's OWN install plan\n// (`compileInstallPlan` — the very steps `custom.template_install` runs) and applies each step to an\n// in-memory world instead of the store: the tables, their fields, the pick-list choices, the relations,\n// the seed rows, the views, the forms, the booking pages and the dashboards. Nothing is invented and\n// nothing is sent anywhere; the answers the memory doors (./doors.ts) give are read off this world.\n//\n// Ids are STABLE: the same template gives the same ids on the server and in the browser, so a page\n// rendered on the server and hydrated in the browser names the same records.\n\nimport { compileInstallPlan, type TemplateInstallPlan } from \"../templates/plan\";\nimport { resolveDateToken } from \"../templates/validate\";\nimport type { TemplateSpec } from \"../templates/types\";\nimport { choiceSlug } from \"../choice\";\n\ntype Json = Record<string, unknown>;\n\n/** The ids the store's kernel tables carry everywhere (custom.table_kernel_id() and its siblings). */\nexport const MEMORY_KERNEL = {\n table: \"11111111-0000-4000-8000-000000000001\",\n field: \"11111111-0000-4000-8000-000000000002\",\n person: \"11111111-0000-4000-8000-000000000005\",\n file: \"11111111-0000-4000-8000-000000000006\",\n rule: \"11111111-0000-4000-8000-000000000003\",\n} as const;\n\n/** One stable uuid-shaped id per name (FNV-1a over the name, four lanes). */\nexport function stableId(name: string): string {\n const lanes = [0x811c9dc5, 0x01000193, 0x9e3779b9, 0x85ebca6b];\n for (let i = 0; i < name.length; i += 1) {\n const c = name.charCodeAt(i);\n for (let l = 0; l < 4; l += 1) lanes[l] = Math.imul((lanes[l]! ^ c) >>> 0, 0x01000193 + l * 2) >>> 0;\n }\n const hex = lanes.map((n) => n.toString(16).padStart(8, \"0\")).join(\"\");\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-4${hex.slice(13, 16)}-${\"89ab\"[parseInt(hex[16]!, 16) % 4]}${hex.slice(17, 20)}-${hex.slice(20, 32)}`;\n}\n\nexport interface MemoryField {\n id: string;\n table_id: string;\n data: Json;\n}\nexport interface MemoryOption {\n id: string;\n key: string;\n label: string;\n color: string | null;\n}\nexport interface MemoryTable {\n id: string;\n token: string;\n /** The Table's declaration as the table kernel holds it. */\n document: Json;\n fields: MemoryField[];\n /** Field key → its choices, in order. */\n options: Map<string, MemoryOption[]>;\n /** Record id → its stored document (choice cells hold the option KEY, relations hold record ids). */\n rows: Map<string, Json>;\n /** Insertion order, which is the template's own row order. */\n order: string[];\n}\nexport interface MemoryView {\n view_id: string;\n token: string;\n table_id: string;\n name: string;\n definition: Json;\n filters: Json;\n}\nexport interface MemoryForm {\n form_id: string;\n token: string;\n table_id: string;\n title: string;\n questions: Json[];\n presentation: Json;\n booking: Json | null;\n}\nexport interface MemoryDashboard {\n dashboard_id: string;\n token: string;\n table_id: string;\n name: string;\n blocks: Json[];\n}\nexport interface MemoryWorld {\n organization_id: string;\n user_id: string;\n /** The business's IANA zone. */\n timezone: string;\n today: string;\n businessName: string;\n tables: MemoryTable[];\n tableById: Map<string, MemoryTable>;\n views: MemoryView[];\n forms: MemoryForm[];\n dashboards: MemoryDashboard[];\n /** Every record id → the table it belongs to. */\n recordTable: Map<string, MemoryTable>;\n /** Table id → the field key that is its pipeline stage. */\n stageField: Map<string, string>;\n /** Standard sources (`{ kind: \"entity\", token }`) this world answers — `withEntities`. */\n entities?: Map<string, import(\"./entity\").MemoryEntity>;\n}\n\nexport interface TemplateWorldOptions {\n /** \"YYYY-MM-DD\" the template's relative dates resolve against. Default: today (UTC). */\n today?: string;\n}\n\nconst COMPUTED = new Set([\"lookup\", \"rollup\", \"formula\"]);\n\n/**\n * A field as the store keeps it, from the template's own words (the `table_from_example` /\n * `field_declare` translation, mirrored for reading: type, format, config, display format).\n */\nfunction storedField(spec: Json, tableId: string, tableToken: string, sort: number, idOf: (n: string) => string): MemoryField {\n const key = String(spec[\"key\"]);\n const parity = String(spec[\"parityType\"] ?? spec[\"type\"] ?? \"text\");\n const base: Json = {\n key,\n label: spec[\"label\"] ?? key,\n sort,\n dated: Boolean(spec[\"dated\"]),\n multi: Boolean(spec[\"multi\"]),\n required: Boolean(spec[\"required\"]),\n rules: Array.isArray(spec[\"rules\"]) ? spec[\"rules\"] : [],\n config: {},\n source: COMPUTED.has(parity) ? \"formula\" : \"manual\",\n depends_on: [],\n sensitivity: spec[\"sensitivity\"] ?? \"internal\",\n context_policy: spec[\"contextPolicy\"] ?? spec[\"context_policy\"] ?? \"include\",\n applies_to_types: [],\n entity_definition_id: tableId,\n parity_type: parity,\n };\n const unit = spec[\"unit\"];\n if (typeof unit === \"string\" && unit) base[\"unit\"] = unit;\n const display = spec[\"displayFormat\"] ?? spec[\"display_format\"];\n if (display && typeof display === \"object\") base[\"display_format\"] = display;\n const config = base[\"config\"] as Json;\n switch (parity) {\n case \"text\":\n base[\"type\"] = \"text\";\n break;\n case \"long_text\":\n base[\"type\"] = \"text\";\n base[\"format\"] = \"long\";\n config[\"multiline\"] = true;\n break;\n case \"email\":\n case \"phone\":\n case \"url\":\n case \"signature\":\n base[\"type\"] = \"text\";\n base[\"format\"] = parity;\n break;\n case \"number\":\n case \"integer\":\n case \"decimal\":\n base[\"type\"] = \"range\";\n break;\n case \"currency\":\n base[\"type\"] = \"range\";\n base[\"format\"] = \"currency\";\n if (!base[\"unit\"]) base[\"unit\"] = \"USD\";\n break;\n case \"percent\":\n base[\"type\"] = \"range\";\n base[\"format\"] = \"percent\";\n break;\n case \"datetime\": {\n base[\"type\"] = \"range\";\n const timed = spec[\"kind\"] === \"datetime\" || spec[\"format\"] === \"datetime\";\n config[\"kind\"] = timed ? \"datetime\" : \"date\";\n if (timed) base[\"format\"] = \"datetime\";\n break;\n }\n case \"checkbox\":\n base[\"type\"] = \"boolean\";\n break;\n case \"select\":\n case \"multi_select\":\n base[\"type\"] = \"list\";\n config[\"options_table_id\"] = idOf(`options.${tableToken}.${key}`);\n if (parity === \"multi_select\") base[\"multi\"] = true;\n break;\n case \"relation\":\n base[\"type\"] = \"relation\";\n base[\"relation_target\"] = spec[\"relation_target\"] ?? (spec[\"relationTarget\"] ? idOf(`tables.${String(spec[\"relationTarget\"])}`) : null);\n if (spec[\"relation_max\"] ?? spec[\"relationMax\"]) base[\"relation_max\"] = spec[\"relation_max\"] ?? spec[\"relationMax\"];\n break;\n case \"member\":\n base[\"type\"] = \"relation\";\n base[\"relation_target\"] = MEMORY_KERNEL.person;\n break;\n case \"attachment\":\n base[\"type\"] = \"relation\";\n base[\"relation_target\"] = MEMORY_KERNEL.file;\n break;\n case \"lookup\":\n base[\"type\"] = \"formula\";\n config[\"via\"] = spec[\"via\"];\n config[\"pick\"] = spec[\"pick\"];\n break;\n case \"rollup\":\n base[\"type\"] = \"formula\";\n config[\"via\"] = spec[\"via\"];\n config[\"agg\"] = spec[\"agg\"];\n config[\"of\"] = spec[\"of\"] ?? spec[\"pick\"];\n if (spec[\"filter\"]) config[\"filter\"] = spec[\"filter\"];\n break;\n case \"formula\":\n base[\"type\"] = \"formula\";\n config[\"formula_text\"] = spec[\"formula_text\"] ?? spec[\"formula\"];\n break;\n default:\n base[\"type\"] = \"text\";\n }\n if (parity !== \"datetime\" && typeof spec[\"format\"] === \"string\" && !base[\"format\"] && parity !== \"lookup\" && parity !== \"rollup\") {\n base[\"format\"] = spec[\"format\"];\n }\n return { id: idOf(`fields.${tableToken}.${key}`), table_id: tableId, data: base };\n}\n\nconst PLACEHOLDER = /\\$\\{(org|ref:[^}]+|new:[^}]+|date:[^}]+)\\}/g;\n\n/**\n * Walk the template's install plan into memory. Pure: the same spec and day give the same world.\n */\nexport function templateWorld(spec: TemplateSpec, options: TemplateWorldOptions = {}): MemoryWorld {\n const plan: TemplateInstallPlan = compileInstallPlan(spec);\n const today = options.today ?? new Date().toISOString().slice(0, 10);\n const tz = plan.timezone || spec.business?.timezone || \"UTC\";\n const seed = `template:${(spec as { id?: string }).id ?? spec.business?.name ?? \"preview\"}`;\n const idOf = (name: string): string => {\n if (name === \"kernel.person\") return MEMORY_KERNEL.person;\n if (name === \"kernel.file\") return MEMORY_KERNEL.file;\n return plan.ids?.[`ref:${name}`] ?? stableId(`${seed}:${name}`);\n };\n const org = stableId(`${seed}:organization`);\n const resolveString = (s: string): unknown => {\n const whole = /^\\$\\{(org|ref:[^}]+|new:[^}]+|date:[^}]+)\\}$/.exec(s);\n const one = (tok: string): string => {\n if (tok === \"org\") return org;\n if (tok.startsWith(\"date:\")) return resolveDateToken(tok.slice(5), today, tz) ?? tok.slice(5);\n return idOf(tok.slice(4));\n };\n if (whole) return one(whole[1]!);\n return s.replace(PLACEHOLDER, (_m, tok: string) => one(tok));\n };\n const resolve = (v: unknown): unknown => {\n if (typeof v === \"string\") return resolveString(v);\n if (Array.isArray(v)) return v.map(resolve);\n if (v && typeof v === \"object\") return Object.fromEntries(Object.entries(v).map(([k, x]) => [k, resolve(x)]));\n return v;\n };\n\n const world: MemoryWorld = {\n organization_id: org,\n user_id: stableId(`${seed}:viewer`),\n timezone: tz,\n today,\n businessName: spec.business?.name ?? \"\",\n tables: [],\n tableById: new Map(),\n views: [],\n forms: [],\n dashboards: [],\n recordTable: new Map(),\n stageField: new Map(),\n };\n const tokenOfTable = new Map<string, string>();\n\n const addField = (table: MemoryTable, raw: Json) => {\n const key = String(raw[\"key\"]);\n const existing = table.fields.findIndex((f) => f.data[\"key\"] === key);\n const field = storedField(raw, table.id, table.token, (existing >= 0 ? existing : table.fields.length) * 10 + 10, idOf);\n if (existing >= 0) table.fields[existing] = field;\n else table.fields.push(field);\n const choices = (raw[\"choices\"] ?? raw[\"options\"]) as unknown;\n if (Array.isArray(choices)) {\n const colors = new Map<string, string>();\n const display = (raw[\"displayFormat\"] ?? raw[\"display_format\"]) as { options?: { choices?: Array<{ value: string; color: string }> } } | undefined;\n for (const c of display?.options?.choices ?? []) colors.set(c.value, c.color);\n table.options.set(\n key,\n choices.map((label) => ({\n id: idOf(`options.${table.token}.${key}.${String(label)}`),\n key: choiceSlug(String(label)),\n label: String(label),\n color: colors.get(String(label)) ?? null,\n })),\n );\n }\n (table.document[\"fields\"] as string[]).push(key);\n };\n\n const writeRow = (table: MemoryTable, id: string, data: Json) => {\n const doc: Json = {};\n for (const [k, v] of Object.entries(data)) if (!k.startsWith(\"_\")) doc[k] = v;\n // A choice cell holds the option's KEY (the store normalises label → key on the way in).\n for (const [key, opts] of table.options) {\n const v = doc[key];\n const toKey = (x: unknown) => opts.find((o) => o.label === x || o.key === x || o.id === x)?.key ?? x;\n if (Array.isArray(v)) doc[key] = v.map(toKey);\n else if (v !== undefined && v !== null) doc[key] = toKey(v);\n }\n const before = table.rows.get(id);\n if (!before) table.order.push(id);\n table.rows.set(id, { ...(before ?? {}), ...doc });\n world.recordTable.set(id, table);\n };\n\n for (const step of plan.steps) {\n const args = resolve(step.args) as Json;\n const tableId = typeof args[\"p_table_id\"] === \"string\" ? (args[\"p_table_id\"] as string) : null;\n const table = tableId ? world.tableById.get(tableId) : undefined;\n switch (step.door) {\n case \"table_from_example\":\n case \"table_declare\": {\n const example = (args[\"p_example\"] ?? { tables: [args[\"p_spec\"]] }) as { tables?: Json[] };\n for (const t of example.tables ?? []) {\n const token = String(t[\"token\"]);\n const id = idOf(`tables.${token}`);\n const made: MemoryTable = {\n id,\n token,\n document: {\n name: t[\"name\"],\n slug: token,\n label_singular: t[\"labelSingular\"] ?? null,\n label_plural: t[\"labelPlural\"] ?? null,\n description: t[\"describes\"] ?? null,\n title_field: t[\"titleField\"] ?? null,\n type: t[\"type\"] ?? \"entity\",\n display: t[\"display\"] ?? \"grid\",\n icon: t[\"icon\"] ?? null,\n fields: [],\n },\n fields: [],\n options: new Map(),\n rows: new Map(),\n order: [],\n };\n world.tables.push(made);\n world.tableById.set(id, made);\n tokenOfTable.set(id, token);\n for (const f of (t[\"fields\"] as Json[] | undefined) ?? []) addField(made, f);\n }\n break;\n }\n case \"field_declare\":\n if (table) addField(table, args[\"p_spec\"] as Json);\n break;\n case \"record_write\":\n if (table) writeRow(table, idOf(step.save ? Object.keys(step.save)[0]! : `${step.label}`), args[\"p_data\"] as Json);\n break;\n case \"record_write_many\":\n if (table) {\n const rows = (args[\"p_rows\"] as Json[]) ?? [];\n const ids = (args[\"p_ids\"] as string[] | undefined) ?? [];\n rows.forEach((r, i) => writeRow(table, ids[i] ?? idOf(`${step.label}.${i}`), r));\n }\n break;\n case \"record_change_many\":\n if (table) {\n for (const change of (args[\"p_changes\"] as Json[]) ?? []) {\n if (change[\"op\"] === \"update\" && typeof change[\"record_id\"] === \"string\") writeRow(table, change[\"record_id\"], change[\"patch\"] as Json);\n }\n }\n break;\n case \"view_declare\": {\n if (!tableId) break;\n const s = args[\"p_spec\"] as Json;\n const token = step.label.replace(/^views\\./, \"\");\n world.views.push({\n view_id: idOf(`views.${token}`),\n token,\n table_id: tableId,\n name: String(s[\"name\"] ?? token),\n definition: { table_id: tableId, ...((s[\"definition\"] as Json) ?? {}) },\n filters: (s[\"filters\"] as Json) ?? {},\n });\n break;\n }\n case \"form_declare\":\n case \"booking_declare\": {\n if (!tableId) break;\n const save = step.save ? Object.keys(step.save)[0]! : step.label;\n world.forms.push({\n form_id: idOf(save),\n token: step.label.replace(/^(forms|bookings|extras)\\./, \"\"),\n table_id: tableId,\n title: String(args[\"p_title\"] ?? \"\"),\n questions: (args[\"p_questions\"] as Json[]) ?? [],\n presentation: (args[\"p_presentation\"] as Json) ?? {},\n booking: step.door === \"booking_declare\" ? ((args[\"p_availability\"] as Json) ?? {}) : null,\n });\n break;\n }\n case \"dashboard_declare\": {\n if (!tableId) break;\n const save = step.save ? Object.keys(step.save)[0]! : step.label;\n world.dashboards.push({\n dashboard_id: idOf(save),\n token: step.label.replace(/^(dashboards|extras)\\./, \"\"),\n table_id: tableId,\n name: String(args[\"p_name\"] ?? \"\"),\n blocks: (args[\"p_blocks\"] as Json[]) ?? [],\n });\n break;\n }\n case \"pipeline_declare\": {\n const stage = ((args[\"p_spec\"] as Json)?.[\"stage_field\"] as Json | undefined)?.[\"key\"];\n if (tableId && typeof stage === \"string\") world.stageField.set(tableId, stage);\n break;\n }\n default:\n break;\n }\n }\n return world;\n}\n","// src/memory/doors.ts — @ai-matrx/records/memory (lane CHAIR-GALLERY-2, 2026-10-05)\n//\n// THE STORE'S READ DOORS, ANSWERED FROM MEMORY. `memoryDataSource(world)` is a `RecordsDataSource` —\n// the same seam a host binds supabase-js to — so every screen of @ai-matrx/records-ui mounts on it\n// unchanged and reads a template's tables, fields, choices, relations, rows, views, forms, booking\n// pages and dashboards exactly as the store would hand them back after an install.\n//\n// READ-ONLY BY CONSTRUCTION. There is no network here and nothing is persisted: every door that would\n// change the store answers the one refusal `PREVIEW_REFUSAL` in words a person can read. The only\n// thing a preview keeps is a viewer's own look (`view_look_set`), held in this data source's memory\n// for as long as the page is open — a switch between board and calendar is a look, not a write.\n//\n// A DOOR THIS FILE DOES NOT KNOW REFUSES BY NAME (it never answers an empty list): the refusal says\n// which door the preview does not answer, so a screen that needs one says so instead of lying.\n\nimport { memoryEntityDoors as entityDoors } from \"./entity\";\nimport type { RecordsDataSource, RecordsFilter, RecordsResponse } from \"../ports\";\nimport type { PgError } from \"../results\";\nimport { MEMORY_KERNEL, type MemoryTable, type MemoryWorld } from \"./world\";\n\ntype Json = Record<string, unknown>;\ntype Answer = { data: unknown; error: PgError | null };\n\n/** What every write door answers in a preview. */\nexport const PREVIEW_REFUSAL: PgError = {\n code: \"42501\",\n message: \"This is a preview of a template. Nothing here is saved — use the template to make it yours.\",\n details: null,\n hint: null,\n} as unknown as PgError;\n\nconst WRITE_DOOR =\n /(^|_)(write|writes|declare|delete|update|upsert|archive|restore|set|move|save|submit|insert|merge|retype|undo|retire|assign|claim|clear|snooze|unsnooze|publish|invite|revoke|issue|pin|duplicate|designate|bind|unbind|change|start|complete|decide|request|hold|release|expire|forget|begin|finish|rows|take|nudge|import|mute|sign|render|instantiate|ensure)(_|$)/;\n\nfunction ok(data: unknown): Answer {\n return { data, error: null };\n}\nfunction refuse(message: string, code = \"PGRST202\"): Answer {\n return { data: null, error: { code, message, details: null, hint: null } as unknown as PgError };\n}\n\nfunction stamp(world: MemoryWorld): Json {\n const at = `${world.today}T09:00:00+00:00`;\n return { created_at: at, updated_at: at, created_by: world.user_id, updated_by: world.user_id };\n}\n\n/** One row's document as the read doors hand it back: choices as words + `_choices`, worked-out values filled. */\nfunction readDocument(world: MemoryWorld, table: MemoryTable, id: string): Json {\n const stored = table.rows.get(id) ?? {};\n const doc: Json = { ...stored };\n const choices: Json = {};\n for (const [key, opts] of table.options) {\n const v = stored[key];\n if (v === undefined || v === null) continue;\n const one = (k: unknown) => opts.find((o) => o.key === k);\n if (Array.isArray(v)) {\n const picked = v.map(one).filter((o) => o !== undefined);\n doc[key] = picked.map((o) => o!.label);\n choices[key] = picked.map((o) => ({ key: o!.key, label: o!.label, id: o!.id, retired: false, reason: null }));\n } else {\n const o = one(v);\n if (o) {\n doc[key] = o.label;\n choices[key] = { key: o.key, label: o.label, id: o.id, retired: false, reason: null };\n }\n }\n }\n if (Object.keys(choices).length) doc[\"_choices\"] = choices;\n for (const f of table.fields) {\n if (f.data[\"type\"] !== \"formula\") continue;\n const key = String(f.data[\"key\"]);\n const config = (f.data[\"config\"] ?? {}) as Json;\n const parity = f.data[\"parity_type\"];\n if (parity === \"lookup\") doc[key] = lookup(world, table, stored, config);\n else if (parity === \"rollup\") doc[key] = rollup(world, table, id, config);\n }\n return doc;\n}\n\nfunction lookup(world: MemoryWorld, table: MemoryTable, stored: Json, config: Json): unknown {\n const via = String(config[\"via\"] ?? \"\");\n const pick = String(config[\"pick\"] ?? \"\");\n const target = stored[via];\n const first = Array.isArray(target) ? target[0] : target;\n if (typeof first !== \"string\") return null;\n const far = world.recordTable.get(first);\n if (!far) return null;\n const value = readDocument(world, far, first)[pick];\n void table;\n return value ?? null;\n}\n\nfunction rollup(world: MemoryWorld, table: MemoryTable, id: string, config: Json): unknown {\n // `via` names the relation field on the OTHER table that points here (\"table.field\" or \"field\").\n const via = String(config[\"via\"] ?? \"\");\n const [maybeTable, maybeField] = via.includes(\".\") ? via.split(\".\") : [null, via];\n const of = config[\"of\"] ? String(config[\"of\"]) : null;\n const agg = String(config[\"agg\"] ?? \"count\");\n const filter = (config[\"filter\"] ?? null) as Json | null;\n const values: unknown[] = [];\n let count = 0;\n for (const other of world.tables) {\n if (maybeTable && other.token !== maybeTable) continue;\n const rel = other.fields.find((f) => f.data[\"key\"] === maybeField && f.data[\"type\"] === \"relation\" && f.data[\"relation_target\"] === table.id);\n if (!rel) continue;\n for (const rid of other.order) {\n const row = other.rows.get(rid)!;\n const link = row[maybeField!];\n const linked = Array.isArray(link) ? link.includes(id) : link === id;\n if (!linked) continue;\n if (filter && !admits(world, other, rid, filter)) continue;\n count += 1;\n if (of) values.push(readDocument(world, other, rid)[of]);\n }\n }\n const nums = values.filter((v): v is number => typeof v === \"number\");\n switch (agg) {\n case \"count\":\n return count;\n case \"sum\":\n return nums.reduce((a, b) => a + b, 0);\n case \"avg\":\n return nums.length ? nums.reduce((a, b) => a + b, 0) / nums.length : null;\n case \"min\":\n return nums.length ? Math.min(...nums) : values.filter((v) => typeof v === \"string\").sort()[0] ?? null;\n case \"max\":\n return nums.length ? Math.max(...nums) : values.filter((v) => typeof v === \"string\").sort().at(-1) ?? null;\n default:\n return count;\n }\n}\n\n/** The store's filter, both shapes: a flat key → scalar / null / window object, or a rule tree. */\nfunction admits(world: MemoryWorld, table: MemoryTable, id: string, filter: unknown): boolean {\n if (!filter || typeof filter !== \"object\") return true;\n const doc = readDocument(world, table, id);\n const stored = table.rows.get(id) ?? {};\n const f = filter as Json;\n if (typeof f[\"op\"] === \"string\") return rule(table, doc, stored, f) !== false;\n for (const [key, want] of Object.entries(f)) {\n const got = doc[key];\n const raw = stored[key];\n if (want === null) {\n if (!(got === null || got === undefined || got === \"\")) return false;\n } else if (typeof want === \"object\" && !Array.isArray(want)) {\n const w = want as { from?: string | null; to?: string | null };\n if (typeof got !== \"string\" && typeof got !== \"number\") return false;\n const g = String(got);\n const at = new Date(g.length === 10 ? `${g}T00:00:00Z` : g).getTime();\n if (w.to && at >= new Date(w.to).getTime()) return false;\n if (w.from && at < new Date(w.from).getTime()) return false;\n } else {\n const list = Array.isArray(got) ? got : [got];\n const rawList = Array.isArray(raw) ? raw : [raw];\n if (!list.some((x) => x === want) && !rawList.some((x) => x === want)) return false;\n }\n }\n return true;\n}\n\nfunction rule(table: MemoryTable, doc: Json, stored: Json, node: Json): unknown {\n if (\"const\" in node) return node[\"const\"];\n if (typeof node[\"field\"] === \"string\") {\n const field = table.fields.find((f) => f.id === node[\"field\"] || f.data[\"key\"] === node[\"field\"]);\n return field ? doc[String(field.data[\"key\"])] ?? stored[String(field.data[\"key\"])] ?? null : null;\n }\n const args = ((node[\"args\"] as Json[]) ?? []).map((a) => rule(table, doc, stored, a));\n switch (node[\"op\"]) {\n case \"and\":\n case \"all\":\n return args.every((a) => a !== false);\n case \"or\":\n case \"any\":\n return args.some((a) => a !== false && a !== null);\n case \"not\":\n return args[0] === false;\n case \"eq\":\n return Array.isArray(args[0]) ? (args[0] as unknown[]).includes(args[1]) : args[0] === args[1];\n case \"neq\":\n return args[0] !== args[1];\n case \"is_empty\":\n return args[0] === null || args[0] === undefined || args[0] === \"\";\n case \"not_empty\":\n return !(args[0] === null || args[0] === undefined || args[0] === \"\");\n default:\n return true;\n }\n}\n\nfunction sortRows(world: MemoryWorld, table: MemoryTable, ids: string[], sort: unknown): string[] {\n const sorts = (Array.isArray(sort) ? sort : []) as Array<{ field?: string; direction?: string }>;\n if (!sorts.length) return ids;\n const docs = new Map(ids.map((id) => [id, readDocument(world, table, id)]));\n return [...ids].sort((a, b) => {\n for (const s of sorts) {\n const key = s.field ?? \"\";\n const x = docs.get(a)![key];\n const y = docs.get(b)![key];\n if (x === y) continue;\n if (x === undefined || x === null) return 1;\n if (y === undefined || y === null) return -1;\n const c = typeof x === \"number\" && typeof y === \"number\" ? x - y : String(x).localeCompare(String(y));\n if (c !== 0) return s.direction === \"desc\" ? -c : c;\n }\n return 0;\n });\n}\n\nfunction matching(world: MemoryWorld, table: MemoryTable, args: Json): string[] {\n const search = typeof args[\"p_search\"] === \"string\" ? (args[\"p_search\"] as string).trim().toLowerCase() : \"\";\n let ids = table.order.filter((id) => admits(world, table, id, args[\"p_filter\"]));\n if (search) ids = ids.filter((id) => JSON.stringify(readDocument(world, table, id)).toLowerCase().includes(search));\n return sortRows(world, table, ids, args[\"p_sort\"]);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// A dashboard block, worked out from the template's rows the way `custom.dashboard_run` answers it.\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst DAY_MS = 86_400_000;\n\n/** The first day of the bucket a date falls in, as the store answers it (\"YYYY-MM-DDT00:00:00+00:00\"). */\nfunction bucketOf(value: unknown, by: string): string | null {\n if (typeof value !== \"string\" || value.length < 10) return null;\n const [y, m, d] = value.slice(0, 10).split(\"-\").map(Number) as [number, number, number];\n let at = new Date(Date.UTC(y, m - 1, d));\n if (by === \"week\") at = new Date(at.getTime() - ((at.getUTCDay() + 6) % 7) * DAY_MS);\n else if (by === \"month\") at = new Date(Date.UTC(y, m - 1, 1));\n else if (by === \"quarter\") at = new Date(Date.UTC(y, Math.floor((m - 1) / 3) * 3, 1));\n else if (by === \"year\") at = new Date(Date.UTC(y, 0, 1));\n return `${at.toISOString().slice(0, 10)}T00:00:00+00:00`;\n}\n\nfunction groupValues(doc: Json, stored: Json, key: string): Array<string | null> {\n const shown = doc[key];\n const raw = stored[key];\n // A relation groups by the linked record's id (the chart names it); a choice by its words.\n const pick = typeof raw === \"string\" && raw === shown ? raw : shown ?? raw;\n const list = Array.isArray(pick) ? pick : [pick];\n const out = list.map((v) => (v === undefined || v === null || v === \"\" ? null : String(v)));\n return out.length ? out : [null];\n}\n\ninterface AggregateAsk {\n groupBy: string[];\n measures: Array<{ op: string; key?: string | undefined }>;\n bucket: { key?: string; by?: string } | null;\n filters: unknown[];\n search?: string;\n limit?: number;\n}\n\n/**\n * GROUPS AND MEASURES, worked out from the template's rows the way `custom.record_aggregate`\n * answers them (and `custom.dashboard_run` per block): a choice groups by its words, a link by the\n * linked record's id, a bucket by the first day of its period (`<key>_<by>`); the search and every\n * filter narrow first; groups rank by the first measure, buckets in time order.\n */\nfunction aggregateRows(world: MemoryWorld, table: MemoryTable, ask: AggregateAsk): Json[] {\n const { groupBy, measures, bucket } = ask;\n const search = (ask.search ?? \"\").trim().toLowerCase();\n let ids = table.order.filter((id) => ask.filters.every((f) => admits(world, table, id, f)));\n if (search) ids = ids.filter((id) => JSON.stringify(readDocument(world, table, id)).toLowerCase().includes(search));\n const groups = new Map<string, { groups: Record<string, string | null>; ids: string[] }>();\n for (const id of ids) {\n const doc = readDocument(world, table, id);\n const stored = table.rows.get(id) ?? {};\n let combos: Array<Record<string, string | null>> = [{}];\n for (const key of groupBy) {\n const values = groupValues(doc, stored, key);\n combos = combos.flatMap((c) => values.map((v) => ({ ...c, [key]: v })));\n }\n if (bucket?.key) {\n const at = bucketOf(doc[bucket.key] ?? stored[bucket.key], bucket.by ?? \"month\");\n if (at === null) continue;\n combos = combos.map((c) => ({ ...c, [`${bucket.key}_${bucket.by ?? \"month\"}`]: at }));\n }\n for (const c of combos) {\n const k = JSON.stringify(c);\n const g = groups.get(k) ?? { groups: c, ids: [] };\n g.ids.push(id);\n groups.set(k, g);\n }\n }\n if (!groupBy.length && !bucket?.key && !groups.size) groups.set(\"{}\", { groups: {}, ids: [] });\n const measureName = (m: { op: string; key?: string | undefined }) => (m.op === \"count\" ? \"count\" : `${m.op}_${m.key ?? \"\"}`);\n let rows = [...groups.values()].map((g) => {\n const out: Record<string, number | null> = {};\n for (const m of measures) {\n if (m.op === \"count\") {\n out[\"count\"] = g.ids.length;\n continue;\n }\n const nums = g.ids.map((id) => readDocument(world, table, id)[m.key ?? \"\"]).filter((v): v is number => typeof v === \"number\");\n const sum = nums.reduce((a, b) => a + b, 0);\n out[measureName(m)] =\n m.op === \"sum\" ? sum : !nums.length ? null : m.op === \"avg\" ? sum / nums.length : m.op === \"min\" ? Math.min(...nums) : m.op === \"max\" ? Math.max(...nums) : null;\n }\n return { groups: g.groups, measures: out, row_count: g.ids.length } as Json & { groups: Record<string, string | null>; measures: Record<string, number | null> };\n });\n const primary = measures[0] ? measureName(measures[0]) : \"count\";\n if (bucket?.key) {\n const k = `${bucket.key}_${bucket.by ?? \"month\"}`;\n rows.sort((a, b) => String(a.groups[k]).localeCompare(String(b.groups[k])));\n } else rows.sort((a, b) => (b.measures[primary] ?? 0) - (a.measures[primary] ?? 0));\n const limit = Number(ask.limit ?? 0);\n if (limit > 0) rows = rows.slice(0, limit);\n return rows;\n}\n\nfunction measuresOf(raw: unknown): Array<{ op: string; key?: string | undefined }> {\n const list = Array.isArray(raw) ? (raw as Json[]) : [];\n const out = list.map((m) => ({ op: String(m[\"op\"] ?? \"count\"), key: m[\"key\"] as string | undefined }));\n return out.length ? out : [{ op: \"count\" }];\n}\n\nfunction runBlock(world: MemoryWorld, subject: string, raw: Json, canvas: Json, index: number): Json {\n const table = world.tableById.get(String(raw[\"table_id\"] ?? subject));\n const title = String(raw[\"title\"] ?? `Block ${index + 1}`);\n const base = { ...raw, title, table_id: table?.id ?? subject, ms: 0 };\n if (!table) return { ...base, rows: [], refused: \"This block's table is not in this template.\" };\n if (raw[\"kind\"] === \"stuck\") return { ...base, rows: [] };\n const measures = measuresOf(raw[\"measures\"]);\n const groupBy = ((raw[\"group_by\"] as string[]) ?? []).slice();\n const bucket = (raw[\"bucket\"] as { key?: string; by?: string } | null) ?? null;\n const rows = aggregateRows(world, table, { groupBy, measures, bucket, filters: [raw[\"filter\"], canvas], limit: Number(raw[\"limit\"] ?? 0) });\n return { ...base, measures, group_by: groupBy, rows };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// A booking page's times, from its declared hours, in the business's own clock.\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface Availability {\n timezone: string;\n slot_minutes: number;\n buffer_minutes: number;\n lead_minutes: number;\n max_per_day: number;\n days: number;\n windows: Array<{ weekday: number; from: string; to: string; member_user_id: string | null }>;\n}\n\nfunction bookingAvailability(world: MemoryWorld, raw: Json): Availability {\n const num = (k: string, fallback: number) => (typeof raw[k] === \"number\" ? (raw[k] as number) : fallback);\n return {\n timezone: String(raw[\"timezone\"] ?? world.timezone),\n slot_minutes: num(\"slot_minutes\", 30),\n buffer_minutes: num(\"buffer_minutes\", 0),\n lead_minutes: num(\"lead_minutes\", 0),\n max_per_day: num(\"max_per_day\", 0),\n days: num(\"days\", 14),\n windows: ((raw[\"windows\"] as Json[]) ?? []).map((w) => ({\n weekday: Number(w[\"weekday\"] ?? 1),\n from: String(w[\"from\"] ?? \"09:00\"),\n to: String(w[\"to\"] ?? \"17:00\"),\n member_user_id: null,\n })),\n };\n}\n\n/** Minutes the zone is ahead of UTC at one instant. */\nfunction zoneOffset(zone: string, at: number): number {\n const parts = new Intl.DateTimeFormat(\"en-US\", { timeZone: zone, hourCycle: \"h23\", year: \"numeric\", month: \"2-digit\", day: \"2-digit\", hour: \"2-digit\", minute: \"2-digit\" })\n .formatToParts(new Date(at))\n .reduce<Record<string, number>>((acc, p) => (p.type === \"literal\" ? acc : { ...acc, [p.type]: Number(p.value) }), {});\n return (Date.UTC(parts[\"year\"]!, parts[\"month\"]! - 1, parts[\"day\"]!, parts[\"hour\"]!, parts[\"minute\"]!) - at) / 60_000;\n}\n\n/** The instant a wall-clock time on one day in a zone is. */\nfunction zonedInstant(zone: string, day: number, minutes: number): number {\n const guess = day + minutes * 60_000;\n return guess - zoneOffset(zone, guess - zoneOffset(zone, guess) * 60_000) * 60_000;\n}\n\nfunction bookingSlots(world: MemoryWorld, table: MemoryTable, a: Availability, days: number) {\n const zone = (() => {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: a.timezone });\n return a.timezone;\n } catch {\n return \"UTC\";\n }\n })();\n const taken = new Set<number>();\n for (const id of table.order) {\n for (const v of Object.values(table.rows.get(id) ?? {})) {\n if (typeof v === \"string\" && /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}/.test(v)) taken.add(new Date(v).getTime());\n }\n }\n const toMin = (hhmm: string) => {\n const [h, m] = hhmm.split(\":\").map(Number);\n return (h ?? 0) * 60 + (m ?? 0);\n };\n const [y, m, d] = world.today.split(\"-\").map(Number) as [number, number, number];\n const start = Date.UTC(y, m - 1, d);\n const earliest = zonedInstant(zone, start, 9 * 60) + a.lead_minutes * 60_000;\n const step = Math.max(5, a.slot_minutes + a.buffer_minutes);\n const slots: Array<{ key: string; at: string; taken: boolean; member_user_id: null }> = [];\n for (let i = 0; i < Math.max(1, days); i += 1) {\n const day = start + i * DAY_MS;\n const weekday = new Date(day).getUTCDay();\n let today = 0;\n for (const w of a.windows.filter((x) => x.weekday === weekday)) {\n for (let t = toMin(w.from); t + a.slot_minutes <= toMin(w.to); t += step) {\n if (a.max_per_day > 0 && today >= a.max_per_day) break;\n const at = zonedInstant(zone, day, t);\n if (at < earliest) continue;\n today += 1;\n const iso = new Date(at).toISOString();\n slots.push({ key: iso, at: iso, taken: taken.has(at), member_user_id: null });\n }\n }\n }\n return slots;\n}\n\nconst VIEWER = \"viewer\";\n\n/** The memory store, as the seam every records-ui screen reads through. */\nexport function memoryDataSource(world: MemoryWorld): RecordsDataSource & { readonly world: MemoryWorld } {\n const looks = new Map<string, { look: Json; updated_at: string }>();\n const tableRow = (t: MemoryTable) => ({ id: t.id, document: { ...t.document }, level: VIEWER });\n const row = (t: MemoryTable, id: string) => ({ id, document: readDocument(world, t, id), level: VIEWER });\n const tableOf = (args: Json) => world.tableById.get(String(args[\"p_table_id\"] ?? \"\"));\n const fieldById = (id: unknown) => {\n for (const t of world.tables) for (const f of t.fields) if (f.id === id) return { t, f };\n return null;\n };\n const nameOf = (id: string): string | null => {\n const t = world.recordTable.get(id);\n if (!t) return null;\n const title = String(t.document[\"title_field\"] ?? \"\");\n const v = readDocument(world, t, id)[title];\n return typeof v === \"string\" ? v : v === undefined || v === null ? null : String(v);\n };\n\n const doors: Record<string, (args: Json) => Answer> = {\n table_kernel_id: () => ok(MEMORY_KERNEL.table),\n field_kernel_id: () => ok(MEMORY_KERNEL.field),\n person_kernel_id: () => ok(MEMORY_KERNEL.person),\n file_kernel_id: () => ok(MEMORY_KERNEL.file),\n rule_kernel_id: () => ok(MEMORY_KERNEL.rule),\n store_is_open: () => ok(true),\n read_records: (args) => {\n const limit = Number(args[\"p_limit\"] ?? 50);\n const offset = Number(args[\"p_offset\"] ?? 0);\n if (args[\"p_table_id\"] === MEMORY_KERNEL.table) return ok(world.tables.slice(offset, offset + limit).map(tableRow));\n const t = tableOf(args);\n if (!t) return ok([]);\n return ok(t.order.slice(offset, offset + limit).map((id) => row(t, id)));\n },\n read_records_by_ids: (args) => {\n const ids = (args[\"p_record_ids\"] as string[]) ?? [];\n if (args[\"p_table_id\"] === MEMORY_KERNEL.table) return ok(world.tables.filter((t) => ids.includes(t.id)).map(tableRow));\n const t = tableOf(args);\n if (!t) return ok([]);\n return ok(ids.filter((id) => t.rows.has(id)).map((id) => row(t, id)));\n },\n read_records_matching: (args) => {\n const t = tableOf(args);\n if (!t) return ok([]);\n const limit = Number(args[\"p_limit\"] ?? 50);\n const offset = Number(args[\"p_offset\"] ?? 0);\n return ok(matching(world, t, args).slice(offset, offset + limit).map((id) => row(t, id)));\n },\n read_records_page: (args) => {\n const t = tableOf(args);\n const limit = Number(args[\"p_limit\"] ?? 50);\n const offset = Number(args[\"p_offset\"] ?? 0);\n if (!t) return ok({ rows: [], total: 0, limit, offset, sort_ignored: [] });\n const ids = matching(world, t, args);\n return ok({ rows: ids.slice(offset, offset + limit).map((id) => row(t, id)), total: ids.length, limit, offset, sort_ignored: [] });\n },\n read_record: (args) => {\n const id = String(args[\"p_record_id\"] ?? \"\");\n const t = world.recordTable.get(id);\n if (!t) return refuse(\"That record is not in this template.\", \"P0002\");\n return ok(readDocument(world, t, id));\n },\n record_headers: (args) =>\n ok(\n ((args[\"p_ids\"] as string[]) ?? [])\n .filter((id) => world.recordTable.has(id))\n .map((id) => ({ id, mine: false, version: 1, table_id: world.recordTable.get(id)!.id, deleted_at: null, ...stamp(world) })),\n ),\n applicable_fields: (args) => {\n const t = tableOf(args);\n if (!t) return ok([]);\n return ok(\n t.fields.map((f) => ({\n id: f.id,\n data: f.data,\n version: 1,\n metadata: {},\n shown_to: null,\n table_id: MEMORY_KERNEL.field,\n data_class: \"field\",\n deleted_at: null,\n visibility: \"internal\",\n custom_fields: {},\n organization_id: world.organization_id,\n ...stamp(world),\n })),\n );\n },\n field_options: (args) => {\n const hit = fieldById(args[\"p_field_id\"]);\n if (!hit) return ok([]);\n const opts = hit.t.options.get(String(hit.f.data[\"key\"])) ?? [];\n return ok(\n opts.map((o, i) => ({\n id: o.id,\n organization_id: world.organization_id,\n table_id: (hit.f.data[\"config\"] as Json)[\"options_table_id\"] ?? null,\n data_class: \"record\",\n data: { name: o.label, sort: (i + 1) * 10, ...(o.color ? { color: o.color } : {}) },\n version: 1,\n metadata: { option_key: o.key },\n custom_fields: {},\n visibility: \"internal\",\n deleted_at: null,\n ...stamp(world),\n })),\n );\n },\n my_levels: (args) => ok(((args[\"p_ids\"] as string[]) ?? []).map((id) => ({ id, level: VIEWER }))),\n views: (args) =>\n ok(\n world.views\n .filter((v) => !args[\"p_table_id\"] || v.table_id === args[\"p_table_id\"])\n .map((v) => ({ view_id: v.view_id, name: v.name, table_id: v.table_id, filters: v.filters, definition: v.definition, created_at: `${world.today}T09:00:00Z` })),\n ),\n view_look_read: (args) => {\n const out: Json = {};\n for (const [key, look] of looks) if (key.startsWith(`${String(args[\"p_table_id\"])}:`)) out[key.split(\":\")[1]!] = look;\n return ok(out);\n },\n view_look_set: (args) => {\n const key = `${String(args[\"p_table_id\"])}:${String(args[\"p_view_id\"])}`;\n const look = (args[\"p_look\"] as Json | null) ?? null;\n if (look) looks.set(key, { look, updated_at: new Date().toISOString() });\n else looks.delete(key);\n return ok(look);\n },\n grid_layout: (args) =>\n ok({\n layout: { mode: \"auto\", wrap: false, row_height: \"normal\", fit_max_columns: 8, freeze_first_column: false },\n source: { mode: \"platform\", wrap: \"platform\", row_height: \"platform\", fit_max_columns: \"platform\", freeze_first_column: \"platform\" },\n refused: [],\n view_id: args[\"p_view_id\"] ?? null,\n }),\n table_decorations: () => ok({ rows: {}, cells: {}, rules: [], stale: [], colors: [\"slate\", \"green\", \"amber\", \"red\", \"blue\", \"violet\", \"teal\"], columns: {}, version: 1, rule_ops: [] }),\n row_actions: () => ok({ stale: [], actions: [] }),\n table_stage_field: (args) => ok(world.stageField.get(String(args[\"p_table_id\"])) ?? null),\n pipeline_read: (args) => {\n const t = tableOf(args);\n const stage = t ? world.stageField.get(t.id) : undefined;\n const field = stage ? t!.fields.find((f) => f.data[\"key\"] === stage) : undefined;\n if (!t || !stage || !field) return ok({ is_pipeline: false, why: \"This table has no stage column.\" });\n const stages = (t.options.get(stage) ?? []).map((o) => ({ key: o.key, label: o.label, retired: false }));\n return ok({ is_pipeline: true, table_id: t.id, stage_field: stage, field_id: field.id, stage_label: field.data[\"label\"], stages, rules: [] });\n },\n pipeline_board: (args) => {\n const t = tableOf(args);\n const stage = t ? world.stageField.get(t.id) : undefined;\n if (!t || !stage) return ok([]);\n const measure = typeof args[\"p_measure\"] === \"string\" ? (args[\"p_measure\"] as string) : null;\n const ids = t.order.filter((id) => admits(world, t, id, args[\"p_filter\"]));\n return ok(\n (t.options.get(stage) ?? []).map((o, i) => {\n const inIt = ids.filter((id) => t.rows.get(id)![stage] === o.key);\n const total = measure\n ? inIt.reduce((sum, id) => sum + (typeof t.rows.get(id)![measure] === \"number\" ? (t.rows.get(id)![measure] as number) : 0), 0)\n : null;\n return { stage_key: o.key, stage_label: o.label, stage_position: i + 1, cards: inIt.length, total, wip_limit: null, over_limit: false };\n }),\n );\n },\n relation_words_many: (args) =>\n ok(((args[\"p_record_ids\"] as string[]) ?? []).map((id) => ({ record_id: id, words: nameOf(id), archived: false }))),\n reverse_columns: (args) => {\n const target = String(args[\"p_table_id\"] ?? \"\");\n const out: Json[] = [];\n for (const t of world.tables) {\n for (const f of t.fields) {\n if (f.data[\"type\"] !== \"relation\" || f.data[\"relation_target\"] !== target) continue;\n out.push({\n key: `${t.token}__${String(f.data[\"key\"])}`,\n label: String(t.document[\"name\"] ?? t.token),\n source_field_id: f.id,\n source_field_key: f.data[\"key\"],\n source_field_label: f.data[\"label\"],\n source_table_id: t.id,\n source_table_name: t.document[\"name\"],\n cardinality: \"many\",\n read_only: true,\n });\n }\n }\n return ok(out);\n },\n reverse_links_many: (args) => {\n const hit = fieldById(args[\"p_field_id\"]);\n return ok(\n ((args[\"p_record_ids\"] as string[]) ?? []).map((rid) => {\n if (!hit) return { record_id: rid, total: 0, links: [] };\n const key = String(hit.f.data[\"key\"]);\n const links = hit.t.order\n .filter((id) => {\n const v = hit.t.rows.get(id)![key];\n return Array.isArray(v) ? v.includes(rid) : v === rid;\n })\n .map((id) => ({ id, words: nameOf(id) ?? \"\" }));\n return { record_id: rid, total: links.length, links };\n }),\n );\n },\n // A template's own record has no history, comments, checklists or worked-out provenance yet:\n // these are the answers an installed template gives on its first day.\n record_history: () => ok([]),\n field_history: () => ok([]),\n computed_provenance: () => ok([]),\n comment_thread: (args) => ok({ record_id: args[\"p_record_id\"] ?? null, comments: [], may_comment: false, may_resolve: false }),\n checklist_runs: () => ok([]),\n checklist_templates: () => ok([]),\n doc_templates: () => ok([]),\n doc_renders: () => ok([]),\n doc_signatures: () => ok([]),\n record_row_controls: () =>\n ok({\n shown_to: { value: null, effective: \"everyone\", type_default: null, table_default: null, allowed: [\"everyone\"], is_child: false, can_change: false },\n published_to_web: { available: false, value: false, table_default: null, can_change: false },\n indexed: { available: false, value: null, table_default: null, effective: false, can_change: false },\n }),\n enrich_cells: () => ok([]),\n enrichments: () => ok([]),\n pipeline_pending: () => ok([]),\n record_stage_pending: () => ok([]),\n io_imports: () => ok([]),\n relation_words: (args) => ok(nameOf(String(args[\"p_value\"] ?? \"\"))),\n // The read doors a form, a booking page and a dashboard are drawn from (lane CHAIR-GALLERY-3).\n forms: (args) =>\n ok(\n world.forms\n .filter((f) => !f.booking && (!args[\"p_table_id\"] || f.table_id === args[\"p_table_id\"]))\n .map((f) => ({\n form_id: f.form_id,\n table_id: f.table_id,\n title: f.title,\n slug: f.token,\n published_at: `${world.today}T09:00:00Z`,\n closed_at: null,\n submission_cap: null,\n responses: 0,\n in_table: 0,\n held: 0,\n rejected: 0,\n state: \"open\",\n quarantine_rule_id: null,\n notify_rule_id: null,\n questions: f.questions,\n presentation: { ...f.presentation, questions: f.presentation[\"questions\"] ?? f.questions },\n })),\n ),\n form_preview_asks: (args) => {\n const t = tableOf(args);\n const values = (args[\"p_values\"] as Json | null) ?? {};\n return ok(\n ((args[\"p_questions\"] as Json[]) ?? []).map((q) => {\n const when = q[\"show_if\"] ?? q[\"showIf\"] ?? null;\n const asked = !when || !t ? true : rule(t, values, values, when as Json) !== false;\n return { field_key: String(q[\"field\"] ?? q[\"key\"] ?? \"\"), asked, decided: true, said: null };\n }),\n );\n },\n bookings: (args) =>\n ok(\n world.forms\n .filter((f) => f.booking && (!args[\"p_table_id\"] || f.table_id === args[\"p_table_id\"]))\n .map((f) => ({\n form_id: f.form_id,\n table_id: f.table_id,\n title: f.title,\n slug: f.token,\n published_at: `${world.today}T09:00:00Z`,\n closed_at: null,\n slot_minutes: Number(f.booking![\"slot_minutes\"] ?? 30),\n timezone: String(f.booking![\"timezone\"] ?? world.timezone),\n slot_table_id: null,\n booked: 0,\n cancelled: 0,\n upcoming: 0,\n held: 0,\n next_at: null,\n state: \"open\",\n })),\n ),\n booking_public: (args) => {\n const f = world.forms.find((x) => x.form_id === args[\"p_form_id\"] && x.booking);\n const t = f ? world.tableById.get(f.table_id) : undefined;\n if (!f || !t) return refuse(\"That booking page is not in this template.\", \"P0002\");\n const availability = bookingAvailability(world, f.booking!);\n return ok({\n form_id: f.form_id,\n organization_id: world.organization_id,\n table_id: t.id,\n title: f.title,\n presentation: { ...f.presentation, questions: f.questions },\n fields: t.fields.map((x) => ({ id: x.id, ...x.data })),\n honeypot_key: null,\n availability,\n slots: bookingSlots(world, t, availability, Number(args[\"p_days\"] ?? availability.days)),\n state: \"open\",\n message: null,\n });\n },\n dashboards: (args) =>\n ok(\n world.dashboards\n .filter((d) => !args[\"p_table_id\"] || d.table_id === args[\"p_table_id\"])\n .map((d) => ({\n dashboard_id: d.dashboard_id,\n table_id: d.table_id,\n name: d.name,\n blocks: d.blocks,\n presentation: {},\n block_count: d.blocks.length,\n version: 1,\n created_at: `${world.today}T09:00:00Z`,\n updated_at: `${world.today}T09:00:00Z`,\n })),\n ),\n dashboard_run: (args) => {\n const d = world.dashboards.find((x) => x.dashboard_id === args[\"p_dashboard_id\"]);\n if (!d) return refuse(\"That dashboard is not in this template.\", \"P0002\");\n const canvas = (args[\"p_filter\"] as Json | null) ?? {};\n return ok({\n dashboard_id: d.dashboard_id,\n name: d.name,\n subject_table_id: d.table_id,\n presentation: {},\n filter: canvas,\n grain: null,\n compare: null,\n calendar: { time_zone: world.timezone, week_start: \"monday\" },\n blocks: d.blocks.map((b, i) => runBlock(world, d.table_id, b, canvas, i)),\n });\n },\n dashboard_stuck: () => ok([]),\n // THE EIGHTH VERB, in memory: the same groups and measures as the live `custom.record_aggregate`\n // (and its row shape: no comparison asked ⇒ every prior_* null).\n record_aggregate: (args) => {\n const t = tableOf(args);\n if (!t) return refuse(\"That table is not in this template.\", \"P0002\");\n const rows = aggregateRows(world, t, {\n groupBy: ((args[\"p_group_by\"] as string[]) ?? []).slice(),\n measures: measuresOf(args[\"p_measures\"]),\n bucket: (args[\"p_bucket\"] as { key?: string; by?: string } | null) ?? null,\n filters: [args[\"p_filter\"]],\n ...(typeof args[\"p_search\"] === \"string\" ? { search: args[\"p_search\"] as string } : {}),\n limit: Number(args[\"p_limit\"] ?? 200),\n });\n return ok(rows.map((r) => ({ ...r, prior_groups: null, prior_measures: null, prior_row_count: null, delta: null, compare: null })));\n },\n };\n\n const source = {\n world,\n rpc(fn: string, args: Record<string, unknown>): PromiseLike<Answer> {\n const name = fn.replace(/^custom\\./, \"\").replace(/^platform\\./, \"\");\n const entityDoor = world.entities ? (entityDoors(world.entities) as Record<string, (a: Json) => Answer | null>)[name] : undefined;\n const fromEntity = entityDoor ? entityDoor(args ?? {}) : null;\n if (fromEntity) return Promise.resolve(fromEntity);\n const door = doors[name];\n if (door) return Promise.resolve(door(args ?? {}));\n if (WRITE_DOOR.test(name)) return Promise.resolve({ data: null, error: PREVIEW_REFUSAL });\n return Promise.resolve(refuse(`A template preview does not answer ${name}.`));\n },\n schema() {\n return {\n from(): never {\n throw new Error(\"A template preview reads through the store's doors, never a table.\");\n },\n };\n },\n };\n return source as unknown as RecordsDataSource & { readonly world: MemoryWorld };\n}\n\nexport type { RecordsFilter, RecordsResponse };\n"],"mappings":"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","names":["question","out","COMPUTED","ok","refuse","zoneOffset","m","t"]}
|