{"version":3,"sources":["../../src/memory/index.ts","../../src/recordType.ts","../../src/memory/entity.ts","../../src/aggregate.ts","../../src/templates/types.ts","../../src/formulaLook.ts","../../src/templates/payloads.ts","../../src/templates/validate.ts","../../src/templates/confidential.ts","../../src/templates/extras.ts","../../src/store.generated.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, PREVIEW_VIEWER_NAME } from \"./doors\";\nexport { MEMORY_KERNEL, stableId, templateWorld } from \"./world\";\nexport { memoryEntityAsk, memoryEntityCreate, 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/recordType.ts — @ai-matrx/records · lane CLOSE-CORE (CD-CORE-15, acceptance test 8 \"Type field\")\n//\n// A TABLE WHOSE TYPE FIELD DECIDES ITS COLUMNS. A Shape table whose Kind is its type field: a Circle has a\n// Radius, a Rectangle a Width and a Height. Which columns one record has is the STORE's answer\n// (`custom.applicable_fields` with that record's type, `client.fields({ recordType })`); these helpers are only\n// the pure facts a screen needs around that answer:\n//   · which type a record IS (its type field's value),\n//   · the question a table's OWN screens ask (`EVERY_RECORD_TYPE`: the grid's columns, Column settings,\n//     filters list Radius and Width side by side), and\n//   · whether a column a screen already holds applies to a record's type, so a grid draws a Rectangle's Radius\n//     cell as \"does not apply\" instead of an empty box that invites a value the store would put away.\n\n/** Anything that names the record types it applies to: a Field, or one of its Rules. */\nexport interface NamesRecordTypes {\n  applies_to_types?: readonly string[] | null | undefined;\n}\n\n/** Asked of `client.fields` / `useFields`: every column of the table, whichever record types it applies to. */\nexport const EVERY_RECORD_TYPE = \"*\";\n\n/** The words of a type as a person may have written them: \"Big circle\", \"big_circle\" and \"BIG-CIRCLE\" agree. */\nfunction typeWord(value: string): string {\n  return value.trim().toLowerCase().replace(/[\\s_-]+/g, \" \");\n}\n\n/**\n * The record type of one record: the value of its table's type field (a choice's key), or undefined when the\n * table has no type field or the record has no type yet. A list value reads as its first choice.\n */\nexport function recordTypeOf(\n  table: { type_field?: string | null | undefined } | null | undefined,\n  document: Record<string, unknown> | null | undefined,\n): string | undefined {\n  const key = table?.type_field;\n  if (!key || !document) return undefined;\n  const raw = document[key];\n  const value = Array.isArray(raw) ? raw[0] : raw;\n  return typeof value === \"string\" && value.trim() !== \"\" ? value : undefined;\n}\n\n/** A column every record has (it names no record types). */\nexport function fieldAppliesToEveryType(field: NamesRecordTypes): boolean {\n  return !Array.isArray(field.applies_to_types) || field.applies_to_types.length === 0;\n}\n\n/**\n * Whether a column applies to a record of this type. A column that names no types applies to every record; one\n * that names types applies only to a record whose type is one of them, compared as words (the store also\n * matches a choice's id, so a column declared by option id may read as applying here only after the store says\n * so — a screen asks the store when it matters).\n */\nexport function fieldAppliesToType(field: NamesRecordTypes, recordType: string | null | undefined): boolean {\n  if (fieldAppliesToEveryType(field)) return true;\n  if (recordType === undefined || recordType === null || recordType === \"\") return false;\n  if (recordType === EVERY_RECORD_TYPE) return true;\n  const wanted = typeWord(recordType);\n  return (field.applies_to_types ?? []).some((t) => typeof t === \"string\" && typeWord(t) === wanted);\n}\n\n/** The record types a column names, as they were written. Empty for a column every record has. */\nexport function typesOfField(field: NamesRecordTypes): string[] {\n  return fieldAppliesToEveryType(field) ? [] : (field.applies_to_types ?? []).filter((t): t is string => typeof t === \"string\");\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   * The token's API fact `create_via` (`api.create_via`): `\"insert\"` lets `entity_row_write` with no\n   * record id add a row (task and project since chairblk3_a); absent or `\"refuse\"` refuses, as live.\n   */\n  create_via?: \"insert\" | \"refuse\";\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, create_via: e.create_via ?? \"refuse\" },\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\nconst TITLE_KEYS = [\"name\", \"display_name\", \"title\", \"subject\"];\n\n/**\n * What `entity_row_write` does with NO record id (chairblk3_a): a token whose `create_via` is\n * `\"insert\"` gets one new row in the organization the call names, from the writable columns only,\n * a name required where the token has one; every other token refuses in the live door's words.\n */\nexport function memoryEntityCreate(e: MemoryEntity, organizationId: string | null, columns: Json): Answer {\n  if ((e.create_via ?? \"refuse\") !== \"insert\") {\n    return refuse(`New ${e.label} records are added in AI Matrx, which checks for duplicates.`, \"0A000\", \"This API changes records that already exist.\");\n  }\n  if (!organizationId) return refuse(`Name the organization this new ${e.label} belongs to.`, \"22004\");\n  const title = TITLE_KEYS.map((k) => e.columns.find((c) => c.api_name === k)).find(Boolean);\n  if (title && String(columns?.[title.api_name] ?? \"\").trim() === \"\") {\n    return refuse(`A new ${e.label} needs a name.`, \"22004\", `Send \"${title.api_name}\".`);\n  }\n  const row: Json = { id: `${e.token}-${e.rows.length + 1}-${Math.random().toString(36).slice(2, 10)}`, organization_id: organizationId };\n  for (const c of e.columns) if (!(c.api_name in row)) row[c.api_name] = null;\n  e.rows.push(row);\n  const written = memoryEntityWrite(e, String(row[\"id\"]), columns ?? {});\n  if (written.error) {\n    e.rows.pop();\n    return written;\n  }\n  return ok({ id: row[\"id\"], organization_id: organizationId, token: e.token, created: true });\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      if (args[\"p_record_id\"] === null || args[\"p_record_id\"] === undefined) {\n        return memoryEntityCreate(e, (args[\"p_organization_id\"] as string | null | undefined) ?? null, (args[\"p_columns\"] as Json | undefined) ?? {});\n      }\n      return memoryEntityWrite(e, String(args[\"p_record_id\"] ?? \"\"), (args[\"p_columns\"] as Json | undefined) ?? {});\n    },\n  };\n}\n","// src/aggregate.ts — @ai-matrx/records\n//\n// THE EIGHTH VERB (AGT-N-8). `custom.record_aggregate` groups, buckets, filters\n// and measures INSIDE the read door's own query: the aggregate node sits above\n// the join to `custom.query_visible_ids`, so a chart is computed over the rows\n// this principal may see and the rest are never fetched at all.\n//\n// That is why a chart in this platform is not \"read everything, then sum in the\n// browser\". Summing in the browser would either read rows a person may not see\n// or quietly under-count them, and both of those are a screen telling a lie.\n\nimport type { HiddenFieldNotice } from \"./record\";\nimport type { RuleExpression } from \"./rule\";\n\n/** The measures the store offers. Asked of `custom.agg_operations()` at run time too. */\nexport type AggregateOperation =\n  | \"count\" | \"sum\" | \"avg\" | \"min\" | \"max\"\n  /** GRID-PRIMITIVES G1: the summary bar's other four. Blank = no value, JSON null or \"\". */\n  | \"median\" | \"filled\" | \"empty\" | \"unique\"\n  /**\n   * Notion's calculation row (Spaces N6): the share of the rows asked with no value / a value, as a\n   * percent 0..100 (NULL over no rows); and the RANGE, largest minus smallest (a date column: the days\n   * between its earliest and latest moment).\n   */\n  | \"percent_empty\" | \"percent_filled\" | \"range\";\n\n/** The periods a date Field can be bucketed into (`custom.agg_buckets()`). */\nexport type AggregateBucket = \"day\" | \"week\" | \"month\" | \"quarter\" | \"year\";\n\n/**\n * A HALF-OPEN MOMENT WINDOW: `from` is inclusive, `to` is exclusive. Half-open\n * is the only shape that makes \"September\" and \"October\" meet exactly once —\n * an inclusive `to` either double-counts the boundary moment or drops it,\n * depending on the reader, and both of those are a chart telling a lie.\n */\nexport interface AggregateWindow {\n  from?: string | null;\n  to?: string | null;\n}\n\n/**\n * ONE FILTER VALUE, as `custom.record_aggregate` and `custom.dashboard_run`\n * both read it: a SCALAR is an equality, and an OBJECT is a window. It is not\n * `unknown` on purpose — a filter value the store cannot read is a refusal a\n * caller should get from the compiler, not from the database.\n */\nexport type AggregateFilter = string | number | boolean | null | AggregateWindow;\n\n/**\n * 🚨 THE STORE'S ONE FILTER SHAPE, AND THE ONLY NAME FOR IT.\n *\n * An object of Field key -> value. A scalar is an equality, `null` is UNSET\n * (the third state of a tick box), an object is a half-open time window.\n *\n * It is not the aggregate's private shape and never was. `platform.saved_view`\n * has carried exactly this as `definition -> 'filters'` across five live\n * surface keys since DOOR-18; `custom.view_declare` writes it;\n * `custom.agg_view_admits` reads it to decide whether a change belongs to a\n * saved view; `custom.record_aggregate` takes it as `p_filter` to COMPUTE a\n * dashboard number; and `custom.read_records_matching` takes it to OPEN the\n * rows behind that number. One `custom.record_filter_sql` in the database turns\n * it into SQL for the last two, so the number and the rows cannot disagree.\n *\n * Invent a second one and a chart can compute a total whose drill-through\n * lands somewhere else, which is the only way a drill-through can lie.\n */\nexport type RecordFilter = Record<string, AggregateFilter>;\n\n/**\n * S2-PRIME FILTER-GROUPS — A READ DOOR'S QUESTION, IN EITHER OF ITS TWO SHAPES.\n *\n * The flat `RecordFilter` above (field key → scalar / `null` / window, AND only) is what\n * dashboards, drill-throughs and the notifier carry. A `RuleExpression` — `{op, args}`, ALL / ANY /\n * NOT groups nested to any depth, fields by id — is what the condition builder, a view's own\n * filter and every membership Rule speak. `custom.record_filter_sql(org, table, filter)` turns\n * EITHER into the one WHERE clause the grid (`list`), the aggregate and the board all use, so the\n * three can never disagree about which records a view holds.\n */\nexport type StoreFilter = RecordFilter | RuleExpression;\n\n/**\n * Is this filter a Rule expression? The store's own test (`custom.filter_is_rule`): an object\n * whose `op` is a word and which carries `args`.\n */\nexport function isRuleFilter(filter: unknown): filter is RuleExpression {\n  if (!filter || typeof filter !== \"object\" || Array.isArray(filter)) return false;\n  const node = filter as { op?: unknown; args?: unknown };\n  return typeof node.op === \"string\" && Array.isArray(node.args);\n}\n\n/** One measure. `count` counts rows and needs no Field; the rest read one. */\nexport interface AggregateMeasure {\n  op: AggregateOperation;\n  /** The Field's key. Required for every operation except `count`. */\n  key?: string;\n}\n\n/**\n * One row of an aggregate: which group it is, what each measure came to, and\n * how many records it was worked out from. The measure keys are the store's\n * own (`count`, `sum_amount`, `avg_amount`, …), never renamed on the way out.\n */\n/**\n * One group's key, as the column holds it (CHAIR-SHEET-STORE b): a number column's key is a number, a\n * yes/no column's true/false, a date its ISO text, a date period its first moment, everything else text.\n */\nexport type AggregateGroupValue = string | number | boolean | null;\n\nexport interface AggregateRow {\n  groups: Record<string, AggregateGroupValue>;\n  measures: Record<string, number | null>;\n  /**\n   * AGG-WITHHELD — a measure over a column this reader may not read is `null` in `measures` (the\n   * \"no value\" every number reader already handles) and its reason rides HERE by measure name: the\n   * same notice a withheld cell carries (`reason`, `needs`, `or`) plus the store's own sentence in\n   * `says`. The store never errors a read for a withheld column; it says so. A question that\n   * GROUPS or FILTERS by such a column answers one row with every measure null and `row_count` 0.\n   * Absent when nothing was withheld.\n   */\n  withheld?: Record<string, HiddenFieldNotice & { says?: string; label?: string; field_key?: string }>;\n  row_count: number;\n  /**\n   * S3 — present only when the question carried a comparison. The same group\n   * in the PRIOR window: a bucket is matched by its position in its own window\n   * (week 1 of September beside week 1 of August), so `prior_groups` names the\n   * prior bucket's own date. `null` when the prior window had no such group.\n   */\n  prior_groups?: Record<string, string | null> | null;\n  /** The prior window's measures, keyed exactly like `measures`. */\n  prior_measures?: Record<string, number | null> | null;\n  prior_row_count?: number | null;\n  /** Every measure now and before, the change, and the change as a percent of before. */\n  delta?: Record<string, AggregateDelta> | null;\n  /** The two windows this row was worked out over, and the calendar that cut them. */\n  compare?: AggregateCompareWindows | null;\n  /**\n   * S3 — a compared, bucketed row's POSITION in its window (0 = the first\n   * bucket). A row the current window has not reached yet has a position and\n   * no current bucket, so a chart names it \"Week 6\" rather than inventing a date.\n   */\n  position?: number | null;\n}\n\n/**\n * S3 — WHAT A PERIOD IS COMPARED AGAINST (`custom.agg_compare_kinds()`).\n * `previous_period` is the period before, of the same length (August before\n * September; an explicit window shifted back by its own length);\n * `same_period_last_year`; `range` is a fixed `baseline`.\n */\nexport type AggregateCompareKind = \"previous_period\" | \"same_period_last_year\" | \"range\";\n\n/**\n * S3 — ONE COMPARISON, as `custom.record_aggregate(p_compare)` and a\n * dashboard block's `compare` both take it. The current window is either the\n * calendar `period` holding `at` (default: now, in the organization's time\n * zone) or an explicit `from`/`to`. A date alone (\"2026-09-01\") is that local\n * day in the organization's time zone.\n */\nexport interface AggregateCompare {\n  against?: AggregateCompareKind;\n  /** The date Field the period runs along. Defaults to the bucket's key. */\n  key?: string;\n  period?: AggregateBucket;\n  at?: string;\n  from?: string;\n  to?: string;\n  /** Compare the part of the period that has happened (\"month to date\"). */\n  to_date?: boolean;\n  /** The fixed period `range` compares against. Half-open: `to` is excluded. */\n  baseline?: { from: string; to: string };\n}\n\n/** One measure now and before. `change_pct` is null when before was nothing or zero. */\nexport interface AggregateDelta {\n  current: number | null;\n  prior: number | null;\n  change: number | null;\n  change_pct: number | null;\n}\n\n/**\n * S3 — THE TWO WINDOWS the store actually ran, as local ISO moments with the\n * organization's offset (\"2026-09-01T00:00:00-07:00\"), and the calendar that\n * cut them. A screen labels the comparison from THIS, never from its own clock.\n */\nexport interface AggregateCompareWindows {\n  key: string;\n  against: AggregateCompareKind;\n  period: AggregateBucket | null;\n  to_date: boolean;\n  time_zone: string;\n  week_start: string;\n  /** The bucket grain the windows were counted in, when the question had a bucket. */\n  grain: AggregateBucket | null;\n  /** How many buckets the current window holds — what a target's pace is shared over. */\n  bucket_count: number | null;\n  window: { from: string; to: string };\n  prior_window: { from: string; to: string };\n  /** On a row from `recordAggregate`: that row's bucket position (see `AggregateRow.position`). */\n  position?: number | null;\n}\n\n/** The measure key the store answers with, so a chart can find its own series. */\nexport function measureKey(measure: AggregateMeasure): string {\n  return measure.op === \"count\" ? \"count\" : `${measure.op}_${measure.key ?? \"\"}`;\n}\n\n/**\n * THE QUESTION, AS A STABLE STRING — key-sorted JSON of a `RecordFilter`.\n *\n * A React parent that rebuilds `{ status: \"Cancelled\" }` on every render hands\n * a NEW object every time, and a hook that depends on the object re-reads the\n * whole page on every render forever. Depending on this instead means the page\n * is re-read exactly when the QUESTION changed, which is what a person means.\n *\n * Nested window objects are sorted too, so `{from, to}` and `{to, from}` are\n * one question. `undefined` and an empty filter are both `\"{}\"` — the caller\n * asked nothing, and there is only one way to ask nothing.\n */\nexport function stableFilterKey(filter: StoreFilter | null | undefined): string {\n  if (!filter) return \"{}\";\n  // A Rule expression is ORDERED — the evaluator asks its arguments in order — so its own JSON is\n  // already the question; only a flat map's keys need sorting.\n  if (isRuleFilter(filter)) return JSON.stringify(filter);\n  const keys = Object.keys(filter).sort();\n  if (keys.length === 0) return \"{}\";\n  const parts = keys.map((key) => {\n    const value = filter[key];\n    if (value !== null && typeof value === \"object\") {\n      const window = value as AggregateWindow;\n      return `${JSON.stringify(key)}:{\"from\":${JSON.stringify(window.from ?? null)},\"to\":${JSON.stringify(window.to ?? null)}}`;\n    }\n    return `${JSON.stringify(key)}:${JSON.stringify(value ?? null)}`;\n  });\n  return `{${parts.join(\",\")}}`;\n}\n\n/**\n * AGG-WITHHELD — the store's answer, with the withheld state lifted out of `measures`.\n * `custom.record_aggregate` puts a withheld measure's notice under `measures._withheld`\n * (null beside it); no consumer should ever meet that key among the numbers, so the one door\n * that reads the answer moves it to `row.withheld` and zeroes a count the store left out.\n */\nexport function liftWithheld(rows: AggregateRow[]): AggregateRow[] {\n  // HONEST-REFUSALS 2 — the store says the withheld explanation ONCE, on the first row's `measures._withheld`\n  // (older answers repeated it on every row). Whichever row carries it, every row of the answer gets the same\n  // `withheld`, so a total or a chart reads `row.withheld` exactly as before.\n  let shared: unknown;\n  for (const row of rows) {\n    const m = ((row.measures ?? {}) as Record<string, unknown>)[\"_withheld\"];\n    if (m !== undefined && m !== null && typeof m === \"object\") {\n      shared = m;\n      break;\n    }\n  }\n  return rows.map((row) => {\n    const measures = (row.measures ?? {}) as Record<string, unknown>;\n    const own = measures[\"_withheld\"];\n    const marker = own !== undefined && own !== null && typeof own === \"object\" ? own : shared;\n    const rowCount = (row.row_count as number | null) ?? 0;\n    if (marker === undefined || marker === null || typeof marker !== \"object\") {\n      return rowCount === row.row_count ? row : { ...row, row_count: rowCount };\n    }\n    const { _withheld: _drop, ...rest } = measures;\n    const withheld: NonNullable<AggregateRow[\"withheld\"]> = {};\n    for (const [name, raw] of Object.entries(marker as Record<string, unknown>)) {\n      const m = (raw ?? {}) as { withheld?: Partial<HiddenFieldNotice>; says?: string; label?: string; field_key?: string };\n      withheld[name] = {\n        reason: m.withheld?.reason ?? null,\n        needs: m.withheld?.needs ?? null,\n        or: m.withheld?.or ?? null,\n        ...(m.says ? { says: m.says } : {}),\n        ...(m.label ? { label: m.label } : {}),\n        ...(m.field_key ? { field_key: m.field_key } : {}),\n      };\n    }\n    return { ...row, measures: rest as Record<string, number | null>, withheld, row_count: rowCount };\n  });\n}\n\n/**\n * ROLLUP-FILTER (2026-10-18) — SEVERAL VALUES FOR ONE COLUMN, IN A FLAT FILTER.\n *\n * Beside a single value (`{status: \"Paid\"}`) and a window (`{paid_on: {relative: \"this_month\"}}`), a\n * column of a flat filter (a roll-up's `config.filter`, a saved view's filters) takes\n *   - an any-of list   `{status: [\"Sent\", \"Overdue\"]}`              (the store's list branch, has_any)\n *   - a not-in form    `{status: {not: [\"Draft\", \"Cancelled\"]}}`    (one word works too; list question is_not)\n * Each word is a choice's key or label, any case. This is the ONE reading of that grammar for the TypeScript\n * twins of `custom.record_filter_sql` (the memory world, the template checker); the store's own is the SQL.\n * A blank cell is none of the words, so a not-in form keeps it.\n */\nexport type FilterWords = { mode: \"any\" | \"none\"; words: string[] };\n\n/** `{not: ...}` / a list as the words it asks about, or `null` when the value is neither (a scalar, a window, null). */\nexport function filterWordsOf(want: unknown): FilterWords | null {\n  const strings = (v: unknown): string[] | null => {\n    if (typeof v === \"string\" || typeof v === \"number\" || typeof v === \"boolean\") return [String(v)];\n    if (Array.isArray(v) && v.every((x) => typeof x === \"string\" || typeof x === \"number\" || typeof x === \"boolean\")) return v.map(String);\n    return null;\n  };\n  if (Array.isArray(want)) {\n    const words = strings(want);\n    return words ? { mode: \"any\", words } : null;\n  }\n  if (want && typeof want === \"object\") {\n    const o = want as Record<string, unknown>;\n    const keys = Object.keys(o);\n    if (keys.length === 1 && keys[0] === \"not\") {\n      const words = strings(o[\"not\"]);\n      return words ? { mode: \"none\", words } : null;\n    }\n  }\n  return null;\n}\n\n/**\n * Does a cell (one value, a list, or nothing) satisfy an any-of / not-in question? `aliases` maps a word to the other\n * words that name the same choice (its key and label), so a filter written with the key reads a cell kept as the label.\n */\nexport function cellMatchesWords(cell: unknown, q: FilterWords, aliases?: (word: string) => readonly string[]): boolean {\n  const cellWords = (Array.isArray(cell) ? cell : [cell])\n    .filter((x) => x !== null && x !== undefined && String(x).trim() !== \"\")\n    .map((x) => String(x).trim().toLowerCase());\n  const asked = new Set(q.words.flatMap((w) => [w, ...(aliases?.(w) ?? [])]).map((w) => w.trim().toLowerCase()));\n  const hit = cellWords.some((w) => asked.has(w));\n  return q.mode === \"any\" ? hit : !hit;\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/**\n * BUTTON-STAMPS: the words a row-action step (and a row template) may carry for \"the moment of use\". \"@now\" on a date /\n * datetime column is the instant of the press in the organization's day zone; \"@me\" on a person column is whoever\n * presses. The day words above (\"@today\", \"@today+3d\", \"@next-fri\") are filled at press time too. The store keeps\n * the word as written (custom._stamp_token is the one resolver); the memory preview fills them from world.today and\n * world.user_id.\n */\nexport const STAMP_NOW = \"@now\";\nexport const STAMP_ME = \"@me\";\n/** A day word the press-time resolver knows: \"@now\" or the template seed-date grammar. */\nexport const isPressDayWord = (word: string): boolean => word === STAMP_NOW || RELATIVE_DATE.test(word);\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 catalog\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** The 20 industry groups of the catalog (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  \"view.map\",\n  \"view.orgchart\",\n  \"view.pivot\",\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\", \"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\",\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 colors 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\", \"orange\", \"yellow\", \"pink\", \"brown\", \"gray\"] as const;\n/** The colors a list of choices must use distinct ones of (the original seven; the five added for Notion are extra). */\nexport const CHOICE_COLORS_DISTINCT_UP_TO = 7;\nexport type ChoiceColor = (typeof CHOICE_COLORS)[number];\n/**\n * TEMPLATE-GAPS R3 (4): NOTION'S COLOR NAMES. Notion's ten (default, gray, brown, orange, yellow, green, blue,\n * purple, pink, red) and the common spellings land on the grid's own palette; a pack may write either.\n */\nexport const CHOICE_COLOR_ALIASES = { purple: \"violet\", grey: \"gray\", default: \"slate\", lightgray: \"slate\", light_gray: \"slate\" } as const satisfies Record<string, ChoiceColor>;\nexport type ChoiceColorAlias = keyof typeof CHOICE_COLOR_ALIASES;\n/** The palette color a written color means (case-insensitive), or undefined when it is none. */\nexport function canonicalChoiceColor(color: unknown): ChoiceColor | undefined {\n  if (typeof color !== \"string\") return undefined;\n  const c = color.trim().toLowerCase();\n  if ((CHOICE_COLORS as readonly string[]).includes(c)) return c as ChoiceColor;\n  return (CHOICE_COLOR_ALIASES as Record<string, ChoiceColor>)[c];\n}\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 (normalized, 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 color: choice word → color. */\n  choiceColors?: Record<string, ChoiceColor | ChoiceColorAlias>;\n  /**\n   * THE COLUMN'S LOOK (\"Shows as\", kept on the Field as `display_format`): a plug-in look the\n   * records screens draw — `{ id: \"color_pair\", options: { contrastWith: {...} } }`, `{ id: \"measure\",\n   * options: { unit: \"px\", measurePreview: \"spacing\" } }`, `type_style`, `shadow`, or any format id in\n   * `custom.display_format_ids()`. A choice's colors (`choiceColors`) win over it.\n   */\n  look?: { id: string; options?: Record<string, unknown> };\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   * TEMPLATE-GAPS (c): a `status` column's groups (Notion's Status): choice word → \"todo\" | \"in_progress\" |\n   * \"done\" (custom.status_groups_of). Every choice sits in exactly one group.\n   */\n  statusGroups?: Record<string, \"todo\" | \"in_progress\" | \"done\">;\n  /**\n   * TEMPLATE-GAPS (e): a `button` column (Notion's Button property; custom.button_press) — what a press does:\n   * open a link with `{{field_key}}` filled from the row, run one of this table's row actions (`row_action`\n   * extra token) or one of its automations (`automation` extra token). Holds no value; never seeded.\n   */\n  button?: { do: \"open_url\"; url: string; color?: ChoiceColor } | { do: \"run_action\"; action: string; color?: ChoiceColor } | { do: \"run_automation\"; automation: string; color?: ChoiceColor }\n    /**\n     * TEMPLATE-GAPS R3 (1): ADD A ROW (\"Log workout\", \"New 1:1\"): a new row in `table` (a table token; absent = this\n     * table), starting from that table's row template named `template`, with `prefill` on top: new row's field key →\n     * this row's field key, or \"@row\" for this row itself (a link column back to this table).\n     */\n    | { do: \"add_row\"; table?: string; template?: string; prefill?: Record<string, string>; color?: ChoiceColor };\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\n/** One row template of a table (TemplateTable.rowTemplates). */\nexport interface TemplateRowTemplate {\n  /** What a person picks it by: \"Weekly 1:1\", \"Bug report\". Unique on its table. */\n  name: string;\n  /** Preset values by field key; never a computed field. */\n  values?: Record<string, unknown>;\n  /** The page body a new row's page starts from: a page snapshot `{ v: 1, blocks: [...] }`. */\n  body?: { v: 1; blocks: unknown[] };\n  /** The table's default template: every new row's page starts from it. */\n  default?: boolean;\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), never resets its Dimensions, and\n   * links the template's new tables to it. Uninstall archives only what the install added (its new fields,\n   * views, forms), never the table.\n   *\n   * ITS ROWS (a sample row is never dropped whole): by default it seeds none, and a new table's value that\n   * points at one of its sample rows is left empty. `seedRows` - the caller found the table EMPTY - writes\n   * the template's sample rows into it, so every link to them lands. `rowIds` - the table HAS rows - maps a\n   * sample row's key to the id of the existing row it means; a link to a mapped key lands on that row, a link\n   * to any other key is left empty (and the field stops being required, so the new row still installs).\n   */\n  bindsTo?: { tableId: string; fields: string[]; seedRows?: boolean; rowIds?: Record<string, string> };\n  /**\n   * TEMPLATE-GAPS (a): ROW TEMPLATES (custom.row_template_declare) — what a new row starts as: preset\n   * values (field key → value, e.g. `{ \"status\": \"Draft\" }`) and the page body every new row's page opens\n   * with (`{ \"v\": 1, \"blocks\": [...] }`, Space blocks without ids — the Spaces row page reads the table's\n   * `default` template). At most one is `default`.\n   */\n  rowTemplates?: TemplateRowTemplate[];\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\", \"map\", \"orgchart\", \"pivot\"] as const;\nexport type TemplateViewKind = (typeof TEMPLATE_VIEW_KINDS)[number];\n\nexport interface TemplateViewSort {\n  field: string;\n  direction: \"asc\" | \"desc\";\n}\n\n/** The day ranges custom.relative_window_for_reader knows. `n` (1–3660) only with next_days / past_days. */\nexport const TEMPLATE_RELATIVE_DAYS = [\"today\", \"tomorrow\", \"yesterday\", \"this_week\", \"next_week\", \"last_week\", \"this_month\", \"next_month\", \"last_month\", \"before_today\", \"next_days\", \"past_days\"] as const;\nexport type TemplateRelativeDay = (typeof TEMPLATE_RELATIVE_DAYS)[number];\nexport interface TemplateRelativeWindow {\n  relative: TemplateRelativeDay;\n  n?: number;\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  /**\n   * TEMPLATE-GAPS (b): RELATIVE DAY WINDOWS — date field key → a window counted from the READER's\n   * today (the store's `within` Rule node; custom.relative_window_for_reader): \"Due this week\" =\n   * `{ \"due\": { \"relative\": \"this_week\" } }`, \"Next 7 days\" = `{ \"due\": { \"relative\": \"next_days\", \"n\": 7 } }`,\n   * \"Overdue\" = `{ \"due\": { \"relative\": \"before_today\" } }` (with an anyOf on the open statuses).\n   * Declared into the view's `where`, beside anyOf.\n   */\n  within?: Record<string, TemplateRelativeWindow>;\n  /**\n   * TEMPLATE-GAPS (b): \"ASSIGNED TO ME\" — person field keys (a `member`, `created_by` or `modified_by`\n   * column) that must hold the person reading the view (`eq(field, {me: true})`), so one shared\n   * \"My tasks\" view shows each member their own rows.\n   */\n  me?: 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\n/** W2-A: a map — `map_field` places each record (an address, a place, or a latitude with `mapLngField`). */\nexport interface TemplateMapView extends TemplateViewBase {\n  kind: \"map\";\n  mapField: string;\n  /** `map_lng_field`: the longitude number field when `mapField` is a latitude. */\n  mapLngField?: string;\n}\n\n/** W2-A: an org chart — `parent_field` is the link to the same table saying who a record reports to. */\nexport interface TemplateOrgChartView extends TemplateViewBase {\n  kind: \"orgchart\";\n  parentField: string;\n}\n\n/** PIVOT-VIEW: a cross-tab — `group_field` rows, optional `column_field` columns, one measure per cell. */\nexport interface TemplatePivotView extends TemplateViewBase {\n  kind: \"pivot\";\n  /** `group_field`: the field whose values are the rows. */\n  rowField: string;\n  /** `column_field`: the field whose values are the columns. Absent, one total column. */\n  columnField?: string;\n  /** `measure`: the number field sum, avg, min and max read. */\n  measure?: string;\n  /** `pivot_measure`: what a cell shows. Absent, a count. */\n  op?: \"count\" | \"sum\" | \"avg\" | \"min\" | \"max\";\n}\n\nexport type TemplateView =\n  | TemplateGridView\n  | TemplateKanbanView\n  | TemplateCalendarView\n  | TemplateGalleryView\n  | TemplateTimelineView\n  | TemplateMapView\n  | TemplateOrgChartView\n  | TemplatePivotView;\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, Canceled.\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 (Canceled, 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\n/** When a template automation runs: the reminder events, plus `becomes` (a choice takes `value`) and `assigned` (a Person column fills). */\nexport interface TemplateAutomationWhen extends Omit<UseCaseNotificationTrigger, \"event\"> {\n  event: UseCaseNotificationTrigger[\"event\"] | \"becomes\" | \"assigned\";\n  /** For `becomes`: the choice the column must take. */\n  value?: string;\n}\n\nexport interface TemplateAutomation {\n  kind: \"automation\";\n  token: string;\n  name: string;\n  /**\n   * When it runs (custom.automation_declare): `created` → row_added; `due` → date_arrives on `field`\n   * `daysBefore` days ahead (\"remind me 2 days before\"); `overdue` → date_arrives the day after `field`.\n   * `updated` and `stage_entered` are not automation triggers a template installs (use a notification).\n   */\n  when: TemplateAutomationWhen;\n  /**\n   * AT-TPLAUTO: `becomes` → property_edited on `field` with `to: value`; its action sets the date column `setsToday`\n   * to today (\"when Status becomes Done, set Done date to today\"). `assigned` → tells whoever is put in the Person\n   * column `field` (the two automations custom.field_notify_on_assign declares: an edit, and a new row with someone in it).\n   */\n  setsToday?: string;\n  /** What happens, in the business's words: \"text the owner the pickup window\". */\n  then: string;\n  /** The reminder's words as the person reads them (≤ 600 chars); defaults to `then`. */\n  message?: string;\n  /** Time of day a date reminder fires, HH:MM on a 24-hour clock; defaults to 09:00. */\n  at?: 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 catalog 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 realizes: \"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  /**\n   * Whether the forms this template installs are PUBLISHED on install (default true: a form the box\n   * builds works the moment it is built). `false` leaves them as drafts for the owner to open.\n   */\n  publishForms?: boolean;\n  dimensions: TemplateDimensions[];\n  extras: TemplateExtra[];\n  /**\n   * The template's agent: a copy of a platform agent. Optional ONLY when `mandateKey` is given.\n   */\n  agent?: TemplateAgent;\n  /**\n   * A template that presents a MANDATE instead of an agent copy (design packs: `design_system.build`). The install\n   * copies no agent and records the key on the install (custom.template_install.mandate_key, answered as\n   * `mandate_key`); the surface that opens the installed template presents that mandate. `agent` becomes optional.\n   */\n  mandateKey?: string;\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 catalog 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/formulaLook.ts — THE ONE HOME of the number format a formula (or rollup / lookup) column shows.\n//\n// A formula column carries no look of its own unless one is DECLARED on the field (`display_format`, like any other\n// column's \"Shows as\"). This module answers what that look is when nobody declared it: the template preview, the\n// template installer (it writes the answer onto the field at install time) and the table display of an older or\n// hand-made formula (`withFormulaLooks`, applied where the client reads a table's fields) all call it. Never copy it.\n\ntype Json = Record<string, unknown>;\n\nconst NUMBER_LOOKS = new Set([\"number\", \"decimal\", \"currency\", \"percent\", \"progress\", \"integer\", \"duration\", \"file_size\"]);\nconst CURRENCY_CODES: Record<string, string> = { $: \"USD\", \"£\": \"GBP\", \"€\": \"EUR\", \"¥\": \"JPY\", \"₹\": \"INR\", R$: \"BRL\", C$: \"CAD\", A$: \"AUD\" };\n\n/**\n * THE NUMBER FORMAT A ROLLUP OR LOOKUP INHERITS from the column it reads (BUTTON-STAMPS; the store's\n * custom._picked_look twin): the column's own chosen number look whole, else money keeps its currency, a percent\n * stays a percent and a number keeps its unit as a suffix. `undefined` when the column has no number format worth\n * carrying.\n */\nexport function pickedLookOf(field: Json): { id: string; options?: Json } | undefined {\n  const df = field[\"display_format\"] as { id?: unknown; options?: Json } | undefined;\n  if (df && typeof df === \"object\" && typeof df.id === \"string\" && NUMBER_LOOKS.has(df.id)) return df as { id: string; options?: Json };\n  const unit = typeof field[\"unit\"] === \"string\" && field[\"unit\"].trim() ? field[\"unit\"].trim() : null;\n  const parity = String(field[\"parity_type\"] ?? \"\");\n  if (parity === \"currency\") return { id: \"currency\", options: { currency: CURRENCY_CODES[unit ?? \"$\"] ?? (unit ?? \"USD\").toUpperCase() } };\n  if (parity === \"percent\") return { id: \"percent\" };\n  if ((parity === \"number\" || parity === \"integer\" || parity === \"decimal\") && unit) return { id: \"number\", options: { suffix: ` ${unit}` } };\n  return undefined;\n}\n\n/** A label that says its column is a percent: \"Margin (%)\", \"Fee percent\", \"Win pct\". */\nconst PERCENT_LABEL = /\\(%\\)|%\\s*$|\\bpercent(age)?\\b|\\bpct\\b/i;\n\n/**\n * THE NUMBER FORMAT A FORMULA COLUMN SHOWS when the template declares none: a label that says percent is a\n * percent; otherwise a formula that does arithmetic with money columns (and never divides by one: a ratio is not\n * money) shows money in that currency — \"Net to client\" = offer − fee − costs − liens reads \"$18,247\", not\n * \"18,247\" (ADVERSARIAL-3 D8). `fields` are the table's columns as the store keeps them (their `display_format`\n * already inherited). `undefined` when nothing is worth carrying — a formula answering words stays words.\n */\nexport function formulaLookOf(formula: string, field: Json, fields: readonly Json[]): { id: string; options?: Json } | undefined {\n  const label = String(field[\"label\"] ?? field[\"key\"] ?? \"\");\n  const unit = typeof field[\"unit\"] === \"string\" ? field[\"unit\"].trim() : \"\";\n  if (unit === \"%\" || PERCENT_LABEL.test(label)) return { id: \"percent\" };\n  if (unit && CURRENCY_CODES[unit]) return { id: \"currency\", options: { currency: CURRENCY_CODES[unit] } };\n  if (/^[A-Z]{3}$/.test(unit)) return { id: \"currency\", options: { currency: unit } };\n  const lookOf = (f: Json) => {\n    const df = f[\"display_format\"] as { id?: unknown; options?: Json } | undefined;\n    return df && typeof df.id === \"string\" && NUMBER_LOOKS.has(df.id) ? (df as { id: string; options?: Json }) : pickedLookOf(f);\n  };\n  const escape = (x: string) => x.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n  let money: { id: string; options?: Json } | undefined;\n  for (const m of formula.matchAll(/\\{([^}]+)\\}/g)) {\n    const name = m[1]!;\n    const ref = fields.find((f) => f[\"label\"] === name || f[\"key\"] === name);\n    const look = ref ? lookOf(ref) : undefined;\n    if (look?.id !== \"currency\") continue;\n    const at = `\\\\{${escape(name)}\\\\}`;\n    // Dividing BY money is a ratio (margin / quote), never money.\n    if (new RegExp(`/\\\\s*${at}`).test(formula)) return undefined;\n    // Money is the answer only when the formula computes with it (or is it): a comparison inside IF is not.\n    if (new RegExp(`${at}\\\\s*[-+*/]|[-+*/]\\\\s*${at}`).test(formula) || formula.trim() === `{${name}}`) money ??= look;\n  }\n  return money;\n}\n\n/** The aggregates whose answer is in the unit of the column they read; count, countall, filled, unique… stay plain numbers. */\nconst UNIT_KEEPING_AGGS = new Set([\"sum\", \"min\", \"max\", \"avg\"]);\n\n/** Does this stored field read as a rollup or a lookup (a column that reads another table's column)? */\nexport function isDerivedField(f: Json): boolean {\n  const parity = String(f[\"parity_type\"] ?? \"\");\n  return parity === \"rollup\" || parity === \"lookup\";\n}\n\n/**\n * THE NUMBER FORMAT A ROLLUP OR LOOKUP SHOWS when it declares none (ROLLUP-FORMAT): that of the column it reads\n * (\"Material cost per unit (USD)\" = sum of the BOM lines' \"Line cost\" reads \"$56\", a lookup of a money column reads\n * \"$\"). sum / min / max / avg keep the source's look; count and the other measures stay plain numbers. `farFieldsOf`\n * answers the candidate far tables' columns (their own looks already worked out) for the field's `via` link; the\n * first candidate that holds the picked column and has a look worth carrying wins. `undefined` otherwise.\n */\nexport function derivedLookOf(field: Json, farFieldsOf: (via: string) => ReadonlyArray<readonly Json[]>): { id: string; options?: Json } | undefined {\n  const parity = String(field[\"parity_type\"] ?? \"\");\n  const cfg = (field[\"config\"] ?? {}) as Json;\n  if (parity !== \"rollup\" && parity !== \"lookup\") return undefined;\n  if (parity === \"rollup\" && !UNIT_KEEPING_AGGS.has(String(cfg[\"agg\"] ?? \"\"))) return undefined;\n  const via = String(cfg[\"via\"] ?? \"\");\n  const pick = String((parity === \"rollup\" ? cfg[\"of\"] : cfg[\"pick\"]) ?? \"\");\n  if (!via || !pick) return undefined;\n  for (const far of farFieldsOf(via)) {\n    const source = far.find((f) => f[\"key\"] === pick);\n    const look = source ? pickedLookOf(source) : undefined;\n    if (look) return look;\n  }\n  return undefined;\n}\n\n/** Does this stored field read as a formula column (a typed expression, not a rollup or lookup)? */\nfunction isPlainFormula(f: Json): boolean {\n  if (String(f[\"type\"] ?? \"\") !== \"formula\" && String(f[\"parity_type\"] ?? \"\") !== \"formula\") return false;\n  const cfg = (f[\"config\"] ?? {}) as Json;\n  return !cfg[\"agg\"] && !cfg[\"pick\"] && !cfg[\"via\"];\n}\n\n/**\n * THE DISPLAY FALLBACK: every formula column with no declared `display_format` gets the inferred one, so an older\n * install or a hand-made formula reads \"$18,247\" / \"42%\" like a new one. A declared format is never touched; a\n * formula with nothing worth carrying stays as it is. Returns the same array when nothing changed.\n */\nexport function withFormulaLooks<F extends object>(fields: readonly F[]): F[] {\n  const work = [...(fields as unknown as Json[])];\n  let changed = false;\n  work.forEach((f, i) => {\n    if (!isPlainFormula(f) || (f[\"display_format\"] && typeof f[\"display_format\"] === \"object\")) return;\n    const text = String(((f[\"config\"] ?? {}) as Json)[\"formula_text\"] ?? \"\");\n    const look = formulaLookOf(text, f, work);\n    if (!look) return;\n    work[i] = { ...f, display_format: look };\n    changed = true;\n  });\n  return (changed ? work : (fields as unknown as Json[])) as unknown as F[];\n}\n\n/**\n * THE DISPLAY FALLBACK FOR ROLLUPS AND LOOKUPS: every rollup / lookup with no declared `display_format` gets the\n * look of the column it reads (`derivedLookOf`). A formula that reads such a column is worked out again after, so\n * chains (lookup -> formula -> rollup) settle. Never touches a declared format.\n */\nexport function withDerivedLooks<F extends object>(fields: readonly F[], farFieldsOf: (via: string) => ReadonlyArray<readonly Json[]>): F[] {\n  let work = withFormulaLooks(fields) as unknown as Json[];\n  for (let pass = 0; pass < 3; pass++) {\n    let changed = false;\n    work = work.map((f) => {\n      if (!isDerivedField(f) || (f[\"display_format\"] && typeof f[\"display_format\"] === \"object\")) return f;\n      const look = derivedLookOf(f, farFieldsOf);\n      if (!look) return f;\n      changed = true;\n      return { ...f, display_format: look };\n    });\n    if (!changed) break;\n    work = withFormulaLooks(work) as unknown as Json[];\n  }\n  return work as unknown as F[];\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 { canonicalChoiceColor } from \"./types\";\nimport { formulaLookOf } from \"../formulaLook\";\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\", \"button\"]);\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 */\n/**\n * TEMPLATE-GAPS (c): the store's stamps — filled by the store, never typed or seeded. Declared through\n * custom.field_declare BEFORE the rows, so an autonumber numbers the seed rows as they are written.\n */\nexport const STAMP_KINDS: ReadonlySet<string> = new Set([\"created_time\", \"modified_time\", \"autonumber\", \"created_by\", \"modified_by\"]);\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\" || STAMP_KINDS.has(f.parityType) || f.parityType === \"status\");\n/** A colored 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) => canonicalChoiceColor(field.choiceColors?.[c]))\n        .map((c) => ({ value: c, color: canonicalChoiceColor(field.choiceColors![c])! })),\n    },\n  };\n}\n\n/** The look a column is made wearing: its colored choices, else the template's declared look. */\nexport function fieldDisplayFormat(field: TemplateField): { id: string; options?: Record<string, unknown> } | undefined {\n  return choiceDisplayFormat(field) ?? field.look;\n}\n\n/**\n * `custom.table_from_example`'s `p_example` for ONE table: its own columns (colored 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 = fieldDisplayFormat(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 colored 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  if (STAMP_KINDS.has(field.parityType)) {\n    return { key: field.key, label: field.label, type: field.parityType, sensitivity: field.sensitivity, context_policy: field.contextPolicy };\n  }\n  const displayFormat = fieldDisplayFormat(field);\n  return {\n    ...(field.parityType === \"status\" && field.statusGroups ? { status_groups: field.statusGroups } : {}),\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, inverseKey?: string): Record<string, unknown> {\n  return {\n    key: field.key,\n    label: field.label,\n    type: \"relation\",\n    relation_target: targetTableId,\n    // TEMPLATE-GAPS (d): TWO-WAY. The relationship's inverseKey becomes the link's back-link key on the target\n    // table (REL-9): the target lists its linked rows with no column of its own to seed, and a rollup or\n    // lookup on the target reads THROUGH it (custom._back_link_relation).\n    ...(inverseKey ? { inverse_key: inverseKey } : {}),\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 */\n/** TEMPLATE-GAPS R3 (3): the seed word for \"the person installing this template\" in a member column. */\nexport const INSTALLER = \"@installer\";\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 members = new Set(table.fields.filter((f) => f.parityType === \"member\").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      // TEMPLATE-GAPS R3 (3): \"@installer\" in a member column is whoever installs (the door fills ${installer}).\n      if (members.has(key)) {\n        const one = (v: unknown) => (v === INSTALLER ? \"${installer}\" : v);\n        values[key] = Array.isArray(value) ? value.map(one) : one(value);\n        continue;\n      }\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    // The row's icon is the record's own (a platform key, not a column).\n    if (typeof r.icon === \"string\" && r.icon.trim()) values[\"icon\"] = r.icon.trim();\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, look?: { id: string; options?: Record<string, unknown> }): Record<string, unknown> {\n  // ROLLUP-FORMAT: the number format is DECLARED on the column like a formula's: the template's own `look`, else the\n  // look of the column it reads (`templateLooksOf`), written onto the field as its \"Shows as\".\n  const declared = field.look ?? look;\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    ...(declared ? { display_format: declared } : {}),\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 = viewWhere(view, 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    case \"map\":\n      definition[\"map_field\"] = view.mapField;\n      if (view.mapLngField) definition[\"map_lng_field\"] = view.mapLngField;\n      break;\n    case \"orgchart\":\n      definition[\"parent_field\"] = view.parentField;\n      break;\n    case \"pivot\":\n      definition[\"group_field\"] = view.rowField;\n      if (view.columnField) definition[\"column_field\"] = view.columnField;\n      if (view.measure) definition[\"measure\"] = view.measure;\n      if (view.op) definition[\"pivot_measure\"] = view.op;\n      break;\n  }\n  return { name: view.name, definition, ...(view.filters ? { filters: view.filters } : {}) };\n}\n\n/**\n * A view's whole `where` (S2-PRIME, Fields by id): its any-of conditions, its relative day windows\n * (`within`, read in the reader's zone) and its \"me\" person columns, ANDed. Undefined when it has none.\n */\nexport function viewWhere(view: Pick<TemplateView, \"anyOf\" | \"within\" | \"me\">, fieldIds: Record<string, string>): Record<string, unknown> | undefined {\n  const idOf = (key: string, what: string) => {\n    const id = fieldIds[key];\n    if (!id) throw new Error(`The view ${what} \"${key}\", which the install has no field id for.`);\n    return id;\n  };\n  const args: Record<string, unknown>[] = [];\n  const anyOf = anyOfWhere(view.anyOf, fieldIds);\n  if (anyOf) args.push(...(anyOf[\"args\"] as Record<string, unknown>[]));\n  for (const [key, w] of Object.entries(view.within ?? {})) {\n    const window = { relative: w.relative, ...(w.n !== undefined ? { n: w.n } : {}) };\n    args.push({ op: \"within\", args: [{ field: idOf(key, \"counts days on\") }, { const: window }] });\n  }\n  for (const key of view.me ?? []) args.push({ op: \"eq\", args: [{ field: idOf(key, \"narrows to the reader on\") }, { const: { me: true } }] });\n  return args.length ? { op: \"and\", args } : undefined;\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/**\n * `custom.field_declare`'s spec for a formula column: the store parses `formula_text` and computes it on read.\n * `look` is the number format the column is DECLARED with (a template's own `look` wins, else `formulaLooksOf`'s\n * inference), written onto the field like any other column's \"Shows as\".\n */\nexport function formulaFieldSpec(field: TemplateField, look?: { id: string; options?: Record<string, unknown> }): Record<string, unknown> {\n  const declared = field.look ?? look;\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    ...(declared ? { display_format: declared } : {}),\n    sensitivity: field.sensitivity,\n    context_policy: field.contextPolicy,\n  };\n}\n\n/**\n * THE NUMBER FORMAT EACH FORMULA COLUMN OF A TABLE IS INSTALLED WITH, by field key: the one inference\n * (`formulaLookOf`, shared with the preview and the table display) over the table's own columns, formulas in the\n * order the store parses them so a formula that reads a money formula is money too. A column with nothing worth\n * carrying has no entry. `inherited` are the looks a rollup or lookup of the table already took from the column it\n * reads (`templateLooksOf`), so a formula over such a column is money too.\n */\nexport function formulaLooksOf(\n  table: TemplateTable,\n  inherited?: ReadonlyMap<string, { id: string; options?: Record<string, unknown> }>,\n): Map<string, { id: string; options?: Record<string, unknown> }> {\n  const asStored = (f: TemplateField): Record<string, unknown> => {\n    const look = fieldDisplayFormat(f) ?? inherited?.get(f.key);\n    return {\n      key: f.key,\n      label: f.label,\n      parity_type: f.parityType,\n      ...(f.unit ? { unit: f.unit } : {}),\n      ...(look ? { display_format: look } : {}),\n    };\n  };\n  const work = table.fields.map(asStored);\n  const out = new Map<string, { id: string; options?: Record<string, unknown> }>();\n  for (const f of formulaOrder(table)) {\n    const i = table.fields.indexOf(f);\n    if (work[i]![\"display_format\"]) continue;\n    const look = formulaLookOf(f.formula ?? \"\", work[i]!, work);\n    if (!look) continue;\n    work[i] = { ...work[i]!, display_format: look };\n    out.set(f.key, look as { id: string; options?: Record<string, unknown> });\n  }\n  return out;\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}\" has a trigger the install cannot set up (${a.when.event}); a template automation runs on created, due, overdue, becomes or assigned.`;\n}\n\n/** The triggers a template automation installs, by the use-case event word. */\nexport const AUTOMATION_EVENTS = [\"created\", \"due\", \"overdue\", \"becomes\", \"assigned\"] as const;\n\n/**\n * custom.automation_declare's spec for one template automation: a reminder that tells the person who set\n * it up (the installer — `to: {author: true}`). `due` waits for the date `daysBefore` days ahead\n * (offset_days negative), `overdue` the day after it, `created` runs on every new row. Field ids are\n * install-time refs (`${ref:fields.<table>.<key>}`).\n */\nexport function automationSpec(a: TemplateAutomation, fieldIds: Record<string, string>): Record<string, unknown> {\n  return automationSpecs(a, fieldIds)[0]!;\n}\n\n/**\n * Every custom.automation_declare spec one template automation installs: one, except `assigned`, which is two\n * (an edit of the Person column, and a new row with someone already in it) exactly as custom.field_notify_on_assign\n * declares them. The first is the template's own name; the second adds \" (new)\".\n */\nexport function automationSpecs(a: TemplateAutomation, fieldIds: Record<string, string>): Record<string, unknown>[] {\n  const text = (a.message?.trim() || a.then.trim()).slice(0, 600);\n  const actions = [{ do: \"notify\", to: { author: true }, text }];\n  const at = a.at && /^([01][0-9]|2[0-3]):[0-5][0-9]$/.test(a.at) ? a.at : \"09:00\";\n  if (a.when.event === \"created\") return [{ name: a.name, trigger: { on: \"row_added\" }, actions }];\n  if (a.when.event === \"becomes\") {\n    const field = a.when.field ? fieldIds[a.when.field] : undefined;\n    const date = a.setsToday ? fieldIds[a.setsToday] : undefined;\n    if (!field) throw new Error(`The automation \"${a.name}\" waits for \"${a.when.field ?? \"?\"}\", which \"${a.when.table}\" does not declare.`);\n    if (!date) throw new Error(`The automation \"${a.name}\" sets \"${a.setsToday ?? \"?\"}\", which \"${a.when.table}\" does not declare.`);\n    return [{ name: a.name, trigger: { on: \"property_edited\", field, to: a.when.value }, actions: [{ do: \"set\", values: { [date]: { now: true } } }] }];\n  }\n  if (a.when.event === \"assigned\") {\n    const field = a.when.field ? fieldIds[a.when.field] : undefined;\n    if (!field) throw new Error(`The automation \"${a.name}\" waits for \"${a.when.field ?? \"?\"}\", which \"${a.when.table}\" does not declare.`);\n    const tell = { do: \"notify\", to: { field }, text };\n    return [\n      { name: a.name, trigger: { on: \"property_edited\", field }, actions: [tell] },\n      {\n        name: `${a.name} (new)`,\n        trigger: { on: \"row_added\" },\n        actions: [{ do: \"if\", branches: [{ label: \"Someone is assigned\", when: { all: [{ value: `{{trigger.${field}}}`, is: \"not_empty\" }] }, actions: [tell] }] }],\n      },\n    ];\n  }\n  if (a.when.event === \"due\" || a.when.event === \"overdue\") {\n    const field = a.when.field ? fieldIds[a.when.field] : undefined;\n    if (!field) throw new Error(`The automation \"${a.name}\" waits for \"${a.when.field ?? \"?\"}\", which \"${a.when.table}\" does not declare.`);\n    const offset = a.when.event === \"due\" ? -Math.max(0, Math.round(a.when.daysBefore ?? 0)) : 1;\n    return [{ name: a.name, trigger: { on: \"date_arrives\", field, offset_days: offset, at }, actions }];\n  }\n  throw new Error(automationHeld(a));\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 labeled 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\n/**\n * TEMPLATE-GAPS (e): `custom.field_declare`'s spec for a button column, every id as an install token: a link's\n * `{{field_key}}` becomes `{{<field id>}}`, a row action its saved id, an automation its saved id.\n */\nexport function buttonFieldSpec(table: string, field: TemplateField): Record<string, unknown> {\n  const b = field.button;\n  const button: Record<string, unknown> = { label: field.label, ...(b?.color ? { color: b.color } : {}) };\n  if (b?.do === \"open_url\") Object.assign(button, { do: \"open_url\", url: b.url.replace(/\\{\\{\\s*([a-z0-9_]+)\\s*\\}\\}/g, (_m, k: string) => `{{\\${ref:fields.${table}.${k}}}}`) });\n  else if (b?.do === \"run_action\") Object.assign(button, { do: \"run_action\", action_id: `\\${ref:actions.${table}.${b.action}}` });\n  else if (b?.do === \"run_automation\") Object.assign(button, { do: \"run_automation\", automation_id: `\\${ref:automations.${b.automation}}` });\n  else if (b?.do === \"add_row\") {\n    const target = b.table ?? table;\n    Object.assign(button, {\n      do: \"add_row\",\n      ...(target !== table ? { table_id: `\\${ref:tables.${target}}` } : {}),\n      ...(b.template ? { template_id: `\\${ref:row_template_by_name.${target}.${b.template}}` } : {}),\n      ...(b.prefill && Object.keys(b.prefill).length ? { prefill: b.prefill } : {}),\n    });\n  }\n  return { key: field.key, label: field.label, type: \"button\", button, sensitivity: field.sensitivity, context_policy: field.contextPolicy };\n}\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 { isUuidShape } from \"@ai-matrx/kit/uuid\";\nimport { FORMULA_FUNCTIONS as KIT_FORMULA_FUNCTIONS, parseFormula as parseFormulaText, type FormulaAst } from \"@ai-matrx/kit/formula\";\nimport { tableSettingsProblems } from \"./confidential\";\nimport { extrasProblems } from \"./extras\";\nimport { DECLARABLE_FIELD_KINDS, PARITY_FIELD_TYPES, STORE_DOORS } from \"../store.generated\";\nimport { cellMatchesWords, filterWordsOf, isRuleFilter, type AggregateFilter, type 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 { AUTOMATION_EVENTS, bookingColumnsProblem, isTimedField } from \"./payloads\";\nimport {\n  CAPABILITY_WORDS,\n  CHOICE_COLORS,\n  CHOICE_COLORS_DISTINCT_UP_TO,\n  canonicalChoiceColor,\n  ENTITY_REFERENCE_KINDS,\n  DEFAULT_TEMPLATE_AGENT,\n  INDUSTRY_GROUPS,\n  RELATIVE_DATE,\n  STAMP_ME,\n  isPressDayWord,\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  TEMPLATE_RELATIVE_DAYS,\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    // ROLLUP-FILTER: an any-of list or a {not: [...]} form, key or label, any case (see filterWordsOf).\n    const words = filterWordsOf(want);\n    if (words) return cellMatchesWords(unwrap(row.values[key]), words);\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/range 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,'')`; percent_empty/percent_filled as 100 x share of the rows (NULL over none). 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/**\n * The functions a formula may call — THE one list, `@ai-matrx/kit/formula` (mirrors the store's\n * custom.formula_node_kinds(); architecture D6). The gate parses with kit's parser too, and keeps\n * only its own EXACT evaluator below: numbers are read from the digits as typed into fractions.\n */\nexport const FORMULA_FUNCTION_NAMES: ReadonlySet<string> = new Set(KIT_FORMULA_FUNCTIONS.map((f) => f.name));\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\nfunction toFx(n: FormulaAst): FxNode {\n  switch (n.kind) {\n    case \"number\":\n      return { k: \"num\", v: parseNumeric(n.raw)! };\n    case \"string\":\n      return { k: \"str\", v: n.value };\n    case \"boolean\":\n      return { k: \"call\", f: n.value ? \"TRUE\" : \"FALSE\", args: [] };\n    case \"reference\":\n      return { k: \"ref\", v: n.name };\n    case \"unary\":\n      return { k: \"neg\", a: toFx(n.operand) };\n    case \"binary\":\n      return { k: \"bin\", op: n.operator, a: toFx(n.left), b: toFx(n.right) };\n    case \"call\":\n      return { k: \"call\", f: n.name, args: n.args.map(toFx) };\n  }\n}\n\n/** Parse a formula text with the one parser, or say what is wrong with it. */\nexport function parseGateFormula(text: string): FxNode | string {\n  const parsed = parseFormulaText(text);\n  return parsed.ok ? toFx(parsed.ast) : parsed.error;\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: `${n.op} 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  if (op === \"percent_empty\" || op === \"percent_filled\") {\n    if (!live.length) return { ok: true, value: null, exact: true };\n    const share = q(100n * BigInt(op === \"percent_filled\" ? present.length : live.length - present.length), BigInt(live.length));\n    const pct = qToNumber(share);\n    return pct === null ? { ok: true, value: Number(share.n) / Number(share.d), exact: false } : { ok: true, value: pct, exact: true };\n  }\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 === \"range\") {\n    const lo = nums.reduce((a, b) => (qCmp(b, a) < 0 ? b : a));\n    const hi = nums.reduce((a, b) => (qCmp(b, a) > 0 ? b : a));\n    result = qAdd(hi, q(-lo.n, lo.d));\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\", \"created_by\", \"modified_by\"].includes(f.parityType);\nconst isChoice = (f: { parityType: string }) => [\"select\", \"multi_select\", \"list\", \"status\"].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\", \"percent_empty\", \"percent_filled\", \"range\"];\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]) => {\n      // ROLLUP-FILTER: an any-of list and a not-in form are explained by their words, not as a window.\n      const words = filterWordsOf(v);\n      if (words) return `${k} is ${words.mode === \"any\" ? \"any of\" : \"none of\"} ${words.words.join(\", \")}`;\n      return v === null ? `${k} is empty` : typeof v === \"object\" ? `${k} is in the window` : `${k} is ${String(v)}`;\n    })\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\", \"chart\", \"map\", \"orgchart\", \"pivot\", \"swipe\"] 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  automation: \"automation_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\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// Upgrade warnings (TEMPLATE-FRESH-3): offers an author should see, never a block\n// ═════════════════════════════════════════════════════════════════════════════\n\n/**\n * A NEW table whose sample rows point at sample rows the PREVIOUS version did not have. The upgrade handles it (it\n * adds the new rows first and fills each link once its target exists), but a person upgrading sees rows appear in\n * more than one table at once, and a link whose target the person deleted is left empty; the author should know.\n * Pure: reads two specs, returns one warning per (new table, link field). Never counted against `ok`.\n */\nexport function newRowsPointAtNewRows(previous: Pick<TemplateSpec, \"tables\" | \"sharedBlocks\">, current: Pick<TemplateSpec, \"tables\" | \"sharedBlocks\">): UseCaseProblem[] {\n  const before = new Map(allTables(previous).map((t) => [t.token, t]));\n  const out: UseCaseProblem[] = [];\n  const now = allTables(current);\n  const nowBy = new Map(now.map((t) => [t.token, t]));\n  for (const t of now) {\n    if (before.has(t.token)) continue;\n    for (const f of t.fields) {\n      if (!f.relationTarget || f.parityType === \"attachment\") continue;\n      const far = nowBy.get(f.relationTarget);\n      if (!far) continue;\n      const hadKeys = new Set((before.get(f.relationTarget)?.rows ?? []).map((r) => r.key));\n      const newKeys = new Set(far.rows.map((r) => r.key).filter((k) => !hadKeys.has(k)));\n      const hits = new Set<string>();\n      for (const r of t.rows ?? []) {\n        const v = r.values?.[f.key];\n        for (const k of (Array.isArray(v) ? v : v == null ? [] : [v]).map((x) => String(x))) if (newKeys.has(k)) hits.add(k);\n      }\n      if (hits.size) {\n        out.push({\n          at: `tables (${t.token}).rows`,\n          says: `\"${t.token}\" is new in this version and its sample rows point (through \"${f.label}\") at ${hits.size} sample row${hits.size === 1 ? \"\" : \"s\"} of \"${f.relationTarget}\" that the previous version did not have (${[...hits].slice(0, 3).join(\", \")}${hits.size > 3 ? \", …\" : \"\"}). The upgrade adds them together and fills the links after; an installation whose person removed that table is left with those links empty.`,\n        });\n      }\n    }\n  }\n  return out;\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   * OFFERS, NEVER BLOCKS (TEMPLATE-GAPS 7): what the checker would ADD (state how a child's dates or statuses\n   * agree with its parent's). Never counted against `ok`. A rule a template DOES state is still checked\n   * against its rows and refuses when broken.\n   */\n  suggestions?: UseCaseProblem[];\n  /** TEMPLATE-FRESH-3: upgrade notes for the author (see newRowsPointAtNewRows); only when `options.previous` is given. Never blocks. */\n  warnings?: UseCaseProblem[];\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 — catalog 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  /** The previous published version of this template: asks for the upgrade warnings (`verdict.warnings`). */\n  previous?: TemplateSpec;\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_.-]+)$/;\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): void => void 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 || !isUuidShape(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): void => void problems.push({ at, says });\n  const suggestions: UseCaseProblem[] = [];\n  const suggest = (at: string, says: string): void => void suggestions.push({ at, says });\n  const upgradeWarnings = options.previous ? newRowsPointAtNewRows(options.previous, raw) : [];\n  // TEMPLATE-FRESH (2026-10-18): a fresh copy (custom.template_install_fresh) names every table \"<Table> · <title>\" and\n  // wires everything to its own tables. A table that binds to an EXISTING table is the one thing every copy shares, and a\n  // table name that already carries \" · \" reads like another copy's. Offers, never blocks.\n  for (const [ti, t] of (raw.tables ?? []).entries()) {\n    if (t.bindsTo) suggest(`tables[${ti}] (${t.token}).bindsTo`, `Every fresh copy of this template uses the same existing table here, so copies share its rows; leave bindsTo out if each copy needs its own.`);\n    if (typeof t.name === \"string\" && t.name.includes(\" · \")) suggest(`tables[${ti}] (${t.token}).name`, `A fresh copy appends \" · <title>\" to every table name; a name that already has \" · \" reads like another copy's.`);\n  }\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) say(`tables (${table.token}).titleField`, `The title field \"${table.titleField}\" is not one of this table's fields; name a plain text-like field of \"${table.token}\" (a name, a title) — the install refuses anything else.`);\n    else if (isRelation(tf) || [\"lookup\", \"rollup\", \"formula\"].includes(tf.parityType) || isTimedField(tf) || tf.parityType === \"entity_reference\") {\n      say(`tables (${table.token}).titleField`, `The title field \"${tf.key}\" is a ${isRelation(tf) ? \"link to another table\" : tf.parityType} column, which the store adds after the table is made; the title has to be a plain text-like field made with the table (a name or title). Add one, or point titleField at it.`);\n    }\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(\"@\") && !(value === \"@installer\" && f.parityType === \"member\")) 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 catalog 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 realizes, 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\n  /** TEMPLATE-GAPS (d): table `table`'s back-link `key` — the relation (on `table` of the result) whose relationships[] inverseKey is `key` and points here. */\n  const backLinkOf = (table: string, key: string): { table: string; field: string } | undefined => {\n    const r = (spec.relationships ?? []).find((x) => x.toTable === table && x.inverseKey === key);\n    return r && fieldOf(r.fromTable, r.fromField) ? { table: r.fromTable, field: r.fromField } : undefined;\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 = parseGateFormula(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        // A formula over a lookup or a rollup reads its worked-out answer (CHAIR-MATH a, store since\n        // 2026-10-03: custom.formula_value resolves read-time columns first), so the gate works it out too.\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    if (f.parityType === \"rollup\" && f.via && f.agg) {\n      // custom.rollup_value: the linked records once each, narrowed by the rollup's filter, the far column aggregated.\n      const bl = fieldOf(table, f.via) ? undefined : backLinkOf(table, f.via);\n      const target = bl ? bl.table : fieldOf(table, f.via)?.relationTarget;\n      if (!target) return { ok: false, why: `the rollup \"${f.label}\" reads through \"${f.via}\", which is not a relation of \"${table}\"` };\n      const ref = r.values?.[f.via];\n      const keys = new Set((Array.isArray(ref) ? ref : ref == null ? [] : [ref]).map((x) => String(x)));\n      // Through a back-link: the linking table's rows whose link holds this row.\n      const linked = (x: { key: string; values?: Record<string, unknown> }) => {\n        if (!bl) return keys.has(x.key);\n        const v = x.values?.[bl.field];\n        return (Array.isArray(v) ? v : [v]).map((y) => String(y)).includes(r.key);\n      };\n      let far: SeedRow[] = (byToken.get(target)?.rows ?? []).filter((x) => linked(x) && x.key !== r.key).map((x) => ({ key: x.key, values: x.values ?? {} }) as SeedRow);\n      const pf = f.pick ? fieldOf(target, f.pick) : undefined;\n      if (pf && isComputed(pf)) {\n        const filled = withComputed(target, pf.key, far);\n        if (\"why\" in filled) return { ok: false, why: filled.why };\n        far = filled.rows;\n      }\n      if (f.filter && isRuleFilter(f.filter)) return { ok: false, why: `the rollup \"${f.label}\" narrows with a Rule filter the gate does not mirror` };\n      // A relative window ({\"relative\": \"this_month\"}) is read on the READER's day (TEMPLATE-GAPS c); the seed has no such day.\n      if (f.filter && Object.values(f.filter).some((w) => !!w && typeof w === \"object\" && \"relative\" in (w as object))) return { ok: false, why: `the rollup \"${f.label}\" counts a relative window, which depends on the day it is read` };\n      const out = storeAggregate(far, { op: f.agg, ...(f.agg === \"count\" ? {} : { key: f.pick }) }, f.filter as Record<string, AggregateFilter> | undefined, \"UTC\");\n      return out.ok ? { ok: true, v: out.value } : { ok: false, why: out.says };\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 = parseGateFormula(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  // A gallery card teaches with 2–8 related tables; a one-off describe setup may be the ONE table its sentence names.\n  if (own.length === 0 || own.length > TABLES_MAX) say(\"tables\", `A template installs ${TABLES_MIN}–${TABLES_MAX} related tables; this one has ${own.length}.`);\n  else if (own.length < TABLES_MIN) sayGallery(\"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: colors, 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 written = field.choices.map((c) => field.choiceColors?.[c]);\n        const colors = written.map((w) => canonicalChoiceColor(w));\n        field.choices.forEach((c, i) => {\n          if (!written[i]) say(`${at}.choiceColors`, `The choice \"${c}\" wears no color. Give every choice one of: ${CHOICE_COLORS.join(\", \")}.`);\n          else if (!colors[i]) say(`${at}.choiceColors`, `\"${written[i]}\" is not a color the grid can paint (${CHOICE_COLORS.join(\", \")}, or Notion's purple / gray / default).`);\n        });\n        for (const k of Object.keys(field.choiceColors ?? {})) if (!field.choices.includes(k)) say(`${at}.choiceColors`, `It colors \"${k}\", which is not one of the field's choices.`);\n        // Distinct per choice up to the palette (7 colors today; the ruling's \"up to 8\"\n        // is capped by what the grid can paint), every color used above that.\n        const distinct = new Set(colors.filter(Boolean)).size;\n        const need = Math.min(field.choices.length, CHOICE_COLORS_DISTINCT_UP_TO);\n        if (distinct < need) say(`${at}.choiceColors`, `${field.choices.length} choices wear only ${distinct} distinct color(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        // Bounds read against the SEED (a gallery card's rows); a one-off describe setup's example rows never refuse its bounds.\n        if (seeds.length) {\n          const hi = Math.max(...seeds);\n          const lo = Math.min(...seeds);\n          if (new Set(seeds).size < 2) saySeed(`${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) saySeed(`${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)) saySeed(`${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) saySeed(`${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\") && field.via && !fieldOf(table.token, field.via) && backLinkOf(table.token, field.via)) {\n        // TEMPLATE-GAPS (d): through a BACK-LINK — another table's relation whose inverseKey names this table's side.\n        const bl = backLinkOf(table.token, field.via)!;\n        hasLookupOrRollup = true;\n        if (!field.pick || !fieldOf(bl.table, field.pick)) say(`${at}.pick`, `It reads \"${field.pick ?? \"(nothing)\"}\" on \"${bl.table}\", 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      } else 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        // Two rows that differ in EVERY field they carry are different records, even when the table has fewer than three fields.\n        if (differ < Math.min(3, keys.size)) 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  // An opinion, not a store rule: a habit tracker or a reading list may honestly hold nothing confidential, and the\n  // per-field floors (sensitivityFloorOf) already refuse a phone, an email or a code marked internal. So this is the\n  // published gallery card's teaching bar only; a describe / Spaces pack is never blocked by it (TEMPLATE-GAPS Q2).\n  if (!ownFields.some((f) => f.sensitivity !== \"internal\")) sayGallery(\"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    // A QUOTA a published card owes (it TEACHES governance). A person's own one-off setup owes only the floor, which the\n    // describe autofix already raises (sensitivityFloorOf): a creator's post tracker is mostly internal and is still\n    // right (owner's /make run, 2026-10-08 — refused at \"Only 2 of 27\" after the answer was recovered).\n    sayGallery(\"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      void contactOfSomeone;\n      // MEANING (TEMPLATE-GAPS R3 5): a contact list (name, role, email, phone) is anybody's people — clients,\n      // vendors, guests, a CRM. It is a copy of the team only when it plays the TEAM's role (hired, paid) or holds\n      // the SAME people the template seeds into the block. And it is offered, never refused.\n      const blockNames = new Set((spec.sharedBlocks ?? []).filter((u) => u.block === id).flatMap((u) => u.rows.map((r) => norm(String(storeText(r.values?.[\"full_name\"]) ?? \"\")))).filter(Boolean));\n      const nameKey = table.fields.find((f) => behaviorOf(f) === \"text\" && labelMeans(f, block.fields[0]!.sameAs as readonly string[]))?.key ?? table.titleField;\n      const sameNames = table.rows.filter((r) => blockNames.has(norm(String(storeText(r.values?.[nameKey]) ?? \"\")))).length;\n      const mirrorsPeople = table.rows.length > 0 && sameNames >= Math.max(2, Math.ceil(table.rows.length / 2));\n      const staffOnly = hired || (paid && hits.some((h) => h.key === \"role\")) || mirrorsPeople;\n      if (hits.length >= block.copyThreshold && staffOnly) {\n        suggest(`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 recognizes.\");\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.kind === \"map\") {\n      need(\"mapField\", view.mapField, null, \"a place, address or latitude field\");\n      if (view.mapLngField) need(\"mapLngField\", view.mapLngField, (f) => isNumberish(view.table, f), \"a longitude number field\");\n    } else if (view.kind === \"orgchart\") need(\"parentField\", view.parentField, (f) => isRelation(f), \"a link to the same table saying who each record reports to\");\n    else if (view.kind === \"pivot\") {\n      need(\"rowField\", view.rowField, null, \"a field whose values are the rows\");\n      if (view.columnField) need(\"columnField\", view.columnField, null, \"a field whose values are the columns\");\n      if (view.op && view.op !== \"count\") need(\"measure\", view.measure, (f) => isNumberish(view.table, f), `a number field to ${view.op}`);\n      else if (view.measure) need(\"measure\", view.measure, (f) => isNumberish(view.table, f), \"a number field\");\n    }\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    // TEMPLATE-GAPS (b): relative day windows (`within`) on a date column; \"me\" on a person column.\n    for (const [key, w] of Object.entries(view.within ?? {})) {\n      const f = fieldOf(view.table, key);\n      if (!f) {\n        say(`${at}.within.${key}`, `It counts days on \"${key}\", which \"${view.table}\" does not declare.`);\n        continue;\n      }\n      if (!isDate(f) && ![\"created_time\", \"modified_time\"].includes(f.parityType)) say(`${at}.within.${key}`, `\"${f.label}\" is not a date; a relative day window reads a date or datetime column.`);\n      if (key in (view.filters ?? {})) say(`${at}.within.${key}`, `\"${key}\" is in both filters and within; keep it in one.`);\n      if (!w || !(TEMPLATE_RELATIVE_DAYS as readonly string[]).includes(w.relative)) say(`${at}.within.${key}`, `\"${String(w?.relative)}\" is not a day range: ${TEMPLATE_RELATIVE_DAYS.join(\", \")}.`);\n      else if (w.relative === \"next_days\" || w.relative === \"past_days\") {\n        if (!Number.isInteger(w.n) || (w.n as number) < 1 || (w.n as number) > 3660) say(`${at}.within.${key}.n`, `${w.relative} counts a whole number of days, 1 to 3660 (\"n\": 7).`);\n      } else if (w.n !== undefined) say(`${at}.within.${key}.n`, `n is only for next_days / past_days; \"${w.relative}\" is a fixed range.`);\n    }\n    for (const key of view.me ?? []) {\n      const f = fieldOf(view.table, key);\n      if (!f) say(`${at}.me`, `It narrows to the reader on \"${key}\", which \"${view.table}\" does not declare.`);\n      else if (![\"member\", \"created_by\", \"modified_by\"].includes(f.parityType)) say(`${at}.me`, `\"${f.label}\" is not a person column (member, created_by, modified_by); \"me\" matches a signed-in member, never a row of a table.`);\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\", \"range\"].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) || (m.op === \"range\" && !isDate(f))) && !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            // BUTTON-STAMPS: \"@now\" / \"@today\" / \"@today+3d\" fill a date column and \"@me\" a person column AT PRESS TIME\n            // (custom._stamp_value). Anywhere else the store would write the word itself, so the checker says so.\n            else if (step.set === \"value\" && typeof step.value === \"string\" && step.value.startsWith(\"@\")) {\n              const word = step.value;\n              if (f.parityType === \"member\") {\n                if (word !== STAMP_ME) say(`${at}.steps`, `\"${f.label}\" holds a person; a button sets it to \"@me\" (whoever presses it), and \"${word}\" is not that.`);\n              } else if (isDate(f)) {\n                if (!isPressDayWord(word)) say(`${at}.steps`, `\"${word}\" is not a day word for \"${f.label}\" (\"@now\", \"@today\", \"@today+3d\", \"@next-fri 09:30\").`);\n              } else if (word === STAMP_ME || isPressDayWord(word)) {\n                say(`${at}.steps`, `\"${word}\" only fills a ${word === STAMP_ME ? \"person\" : \"date\"} column; \"${f.label}\" is not one, so a press would write the word itself.`);\n              }\n            }\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        const ev = extra.when?.event;\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 (!(AUTOMATION_EVENTS as readonly string[]).includes(ev)) say(`${at}.when.event`, `An automation runs on ${AUTOMATION_EVENTS.join(\", \")}; for \"${ev}\" use a notification.`);\n        if (ev === \"due\" || ev === \"overdue\") {\n          const f = extra.when.field ? fieldOf(extra.when.table, extra.when.field) : undefined;\n          if (!extra.when.field) say(`${at}.when.field`, \"A date reminder names the date field it waits for.\");\n          else if (f && f.parityType !== \"datetime\") say(`${at}.when.field`, `\"${extra.when.field}\" is not a date or datetime field, so nothing arrives to remind about.`);\n          const d = extra.when.daysBefore;\n          if (d != null && (!Number.isInteger(d) || d < 0 || d > 365)) say(`${at}.when.daysBefore`, \"Say how many whole days before the date, 0 to 365.\");\n        }\n        if (ev === \"becomes\") {\n          const f = extra.when.field ? fieldOf(extra.when.table, extra.when.field) : undefined;\n          if (!extra.when.field) say(`${at}.when.field`, \"A \\\"becomes\\\" automation names the choice column it watches.\");\n          else if (f && ![\"select\", \"status\"].includes(String(f.parityType))) say(`${at}.when.field`, `\"${extra.when.field}\" is not a choice column, so nothing \"becomes\" a value in it.`);\n          else if (f && !(f.choices ?? []).includes(String(extra.when.value))) say(`${at}.when.value`, `\"${String(extra.when.value)}\" is not one of the choices of \"${extra.when.field}\" (${(f.choices ?? []).join(\", \")}).`);\n          const d = extra.setsToday ? fieldOf(extra.when.table, extra.setsToday) : undefined;\n          if (!extra.setsToday) say(`${at}.setsToday`, \"Say which date column is set to today when it happens.\");\n          else if (!d) say(`${at}.setsToday`, `\"${extra.when.table}\" does not declare a field \"${extra.setsToday}\".`);\n          else if (d.parityType !== \"datetime\") say(`${at}.setsToday`, `\"${extra.setsToday}\" is not a date or datetime field, so today cannot be written into it.`);\n        }\n        if (ev === \"assigned\") {\n          const f = extra.when.field ? fieldOf(extra.when.table, extra.when.field) : undefined;\n          if (!extra.when.field) say(`${at}.when.field`, \"An \\\"assigned\\\" automation names the person column it watches.\");\n          else if (f && f.parityType !== \"member\") say(`${at}.when.field`, `\"${extra.when.field}\" does not hold people, so nobody can be assigned in it.`);\n          if (extra.name.length > 34 || extra.name.trim().split(/\\s+/).length > 5) say(`${at}.name`, \"An \\\"assigned\\\" automation also saves a \\\"(new)\\\" twin, so its name is at most 34 characters and 5 words.\");\n        }\n        if (extra.at != null && !/^([01][0-9]|2[0-3]):[0-5][0-9]$/.test(extra.at)) say(`${at}.at`, \"Say the time of day as HH:MM on a 24-hour clock, like 09:00.\");\n        if (!extra.then?.trim()) say(`${at}.then`, \"Say what happens, in the business's words.\");\n        break;\n      }\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 (spec.mandateKey !== undefined && !/^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$/.test(String(spec.mandateKey))) say(\"mandateKey\", `\"${spec.mandateKey}\" is not a mandate key; write it like \"design_system.build\" (lowercase words joined by _ and .).`);\n  if (!agent) {\n    if (!spec.mandateKey) say(\"agent\", \"Every template ships one agent: a copy of a platform agent with its variables bound to these tables (or names the mandate it presents in mandateKey).\");\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 catalog 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 catalog 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  /** Opaque break keys join their parts on a unit separator (never a pipe: a key is not markdown). */\n  const KEY_PART = \"\\u001f\";\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].join(KEY_PART), `\"${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].join(KEY_PART), `\"${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(KEY_PART);\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 ?? {}), ...Object.keys(v.within ?? {})]) 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      if (Object.keys(v?.within ?? {}).length || v?.me?.length) say(`extras (${e.token})`, `The digest reads \"${v?.name}\", whose within / me filter digests never apply (they read only the flat filters); point it at a view without them.`);\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 = parseGateFormula(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 labeled that.`);\n        else if (target.key === f.key) say(fat, \"A formula never reads itself.\");\n        // A formula may read a lookup or a rollup: the store works the read-time column out first (CHAIR-MATH a).\n      }\n    }\n  }\n\n  // ── status groups (TEMPLATE-GAPS c): every choice of a status column in exactly one of todo / in_progress / done ──\n  for (const t of own) {\n    for (const f of t.fields) {\n      const fat = `tables (${t.token}).fields (${f.key})`;\n      if (f.statusGroups && f.parityType !== \"status\") say(`${fat}.statusGroups`, `\"${f.label}\" is a ${f.parityType}; statusGroups belong to a status column (\"parityType\": \"status\").`);\n      if (f.parityType !== \"status\" || !f.statusGroups) continue;\n      for (const [choice, group] of Object.entries(f.statusGroups)) {\n        if (!(f.choices ?? []).includes(choice)) say(`${fat}.statusGroups`, `\"${choice}\" is not one of \"${f.label}\"'s choices.`);\n        if (![\"todo\", \"in_progress\", \"done\"].includes(group)) say(`${fat}.statusGroups`, `\"${choice}\" is put in \"${String(group)}\"; the groups are todo, in_progress and done.`);\n      }\n      const missing = (f.choices ?? []).filter((c) => !(c in f.statusGroups!));\n      if (missing.length) say(`${fat}.statusGroups`, `Put every choice in a group; ${missing.map((c) => `\"${c}\"`).join(\", \")} ${missing.length === 1 ? \"is\" : \"are\"} in none.`);\n    }\n  }\n\n  // ── member seeds (TEMPLATE-GAPS R3 3): a person column's sample value is \"@installer\" — nobody else exists yet ──\n  for (const t of own) {\n    for (const f of t.fields.filter((x) => x.parityType === \"member\")) {\n      for (const r of t.rows) {\n        const v = r.values?.[f.key];\n        if (v === undefined || v === null) continue;\n        const vals = Array.isArray(v) ? v : [v];\n        if (vals.some((x) => x !== \"@installer\")) say(`tables (${t.token}).rows (${r.key}).${f.key}`, `\"${f.label}\" holds a signed-in person, and none exists until someone installs; seed it \"@installer\" (the person installing) or leave it empty.`);\n      }\n    }\n  }\n\n  // ── buttons (TEMPLATE-GAPS e): a press does something real on THIS table ──\n  for (const t of own) {\n    for (const f of t.fields.filter((x) => x.parityType === \"button\")) {\n      const fat = `tables (${t.token}).fields (${f.key}).button`;\n      const b = f.button;\n      if (!b) { say(fat, `\"${f.label}\" is a button; say what a press does: {\"do\": \"open_url\", \"url\": …}, {\"do\": \"run_action\", \"action\": \"<row_action token>\"} or {\"do\": \"run_automation\", \"automation\": \"<automation token>\"}.`); continue; }\n      if (b.do === \"open_url\") {\n        // TEMPLATE-GAPS R3 2: the whole target may be a link column of the row ({{posting_url}}); the store fills it\n        // unencoded and still opens only http(s) / mailto / tel after filling (custom.button_press).\n        const lead = /^\\{\\{\\s*([a-z0-9_]+)\\s*\\}\\}/i.exec(b.url ?? \"\")?.[1];\n        const leadField = lead ? t.fields.find((x) => x.key === lead) : undefined;\n        if (lead && leadField && leadField.parityType !== \"url\") say(fat, `A button's link may start with a field only when it holds a link: \"${leadField.label}\" is a ${leadField.parityType}, not a url.`);\n        else if (!lead && !/^(https?:\\/\\/|mailto:|tel:)/i.test(b.url ?? \"\")) say(fat, `A button's link starts with https://, mailto:, tel: or a url column ({{website}}); \"${b.url}\" does not.`);\n        for (const m of (b.url ?? \"\").matchAll(/\\{\\{\\s*([^}\\s]+)\\s*\\}\\}/g)) if (!t.fields.some((x) => x.key === m[1])) say(fat, `The link fills {{${m[1]}}}, and \"${t.token}\" has no field \"${m[1]}\".`);\n      } else if (b.do === \"run_action\") {\n        if (!spec.extras.some((e) => e.kind === \"row_action\" && e.table === t.token && e.token === b.action)) say(fat, `\"${b.action}\" is not a row_action extra on \"${t.token}\".`);\n      } else if (b.do === \"run_automation\") {\n        if (!spec.extras.some((e) => e.kind === \"automation\" && e.token === b.automation && (e as { when?: { table?: string } }).when?.table === t.token)) say(fat, `\"${b.automation}\" is not an automation extra on \"${t.token}\".`);\n      } else if (b.do === \"add_row\") {\n        const target = b.table ?? t.token;\n        const tt = tables.find((x) => x.token === target);\n        if (!tt) say(fat, `It adds a row to \"${target}\", which is neither a table nor a shared block of this template.`);\n        else {\n          if (b.template && !(tt.rowTemplates ?? []).some((rt) => rt.name === b.template)) say(fat, `\"${b.template}\" is not a row template on \"${target}\"; declare it in that table's rowTemplates.`);\n          // custom.record_write refuses a new row missing a required column with no default: the press would fail.\n          const preset = { ...((tt.rowTemplates ?? []).find((rt) => rt.name === b.template)?.values ?? {}), ...(b.prefill ?? {}) };\n          const missing = tt.fields.filter((x) => x.required && x.default === undefined && !isComputed(x) && !(x.key in preset));\n          if (missing.length) say(fat, `A press adds a \"${target}\" row without ${missing.map((x) => `\"${x.label}\"`).join(\", \")}, which ${missing.length === 1 ? \"is\" : \"are\"} required; set ${missing.length === 1 ? \"it\" : \"them\"} in the row template's values or the prefill.`);\n          for (const [to, from] of Object.entries(b.prefill ?? {})) {\n            const tf = tt.fields.find((x) => x.key === to);\n            if (!tf) say(fat, `It prefills \"${to}\", which \"${target}\" does not declare.`);\n            else if (isComputed(tf)) say(fat, `\"${tf.label}\" is computed by the store; a new row cannot be given it.`);\n            if (from === \"@row\") {\n              if (tf && !(isRelation(tf) && tf.relationTarget === t.token)) say(fat, `\"@row\" links the new row back to this one, so \"${to}\" must be a relation to \"${t.token}\".`);\n            } else if (!t.fields.some((x) => x.key === from)) say(fat, `It copies \"${from}\" from the pressed row, which \"${t.token}\" does not declare.`);\n          }\n        }\n      } else say(fat, `\"${String((b as { do?: string }).do)}\" is not something a button does: open_url, run_action, run_automation or add_row.`);\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 a button and holds no value; ${seeded} seed row(s) write one.`);\n    }\n  }\n\n  // ── row templates (custom.row_template_declare): named, preset stored columns, a page snapshot body ──\n  for (const t of tables) {\n    const names = new Set<string>();\n    let defaults = 0;\n    (t.rowTemplates ?? []).forEach((rt, i) => {\n      const at = `tables (${t.token}).rowTemplates[${i}]`;\n      const name = rt.name?.trim() ?? \"\";\n      if (!name) say(`${at}.name`, \"Name the row template the way a person picks it (\\\"Weekly 1:1\\\", \\\"Bug report\\\").\");\n      else if (names.has(name.toLowerCase())) say(`${at}.name`, `\"${name}\" names two row templates on \"${t.token}\"; a template is picked by its name.`);\n      names.add(name.toLowerCase());\n      if (rt.default) defaults += 1;\n      for (const k of Object.keys(rt.values ?? {})) {\n        const f = t.fields.find((x) => x.key === k);\n        if (!f) say(`${at}.values.${k}`, `\"${t.token}\" has no field \"${k}\"; a row template presets the table's own columns by key.`);\n        else if (isComputed(f)) say(`${at}.values.${k}`, `\"${f.label}\" is computed by the store (${f.parityType}); a row template cannot preset it.`);\n        // A relative date (\"@today+3d\") is filled on the day the template is used (custom._row_template_values_now).\n        else if (isDate(f) && typeof rt.values![k] === \"string\" && (rt.values![k] as string).startsWith(\"@\") && !isPressDayWord(rt.values![k] as string)) say(`${at}.values.${k}`, `\"${rt.values![k]}\" is not in the relative-date grammar (\"@now\", \"@today\", \"@today+3d\", \"@next-fri 09:30\").`);\n        else if (f.parityType === \"member\" && typeof rt.values![k] === \"string\" && (rt.values![k] as string) !== STAMP_ME) say(`${at}.values.${k}`, `\"${f.label}\" holds a person; a row template presets it with \"@me\" (whoever starts the row) or leaves it empty.`);\n        else if (isChoice(f) && f.choices?.length) {\n          const vals = Array.isArray(rt.values![k]) ? (rt.values![k] as unknown[]) : [rt.values![k]];\n          for (const v of vals) if (typeof v === \"string\" && !f.choices.includes(v)) say(`${at}.values.${k}`, `\"${v}\" is not one of \"${f.label}\"'s choices: ${f.choices.join(\", \")}.`);\n        }\n      }\n      if (rt.body !== undefined) {\n        const b = rt.body as { v?: unknown; blocks?: unknown };\n        if (!b || b.v !== 1 || !Array.isArray(b.blocks)) say(`${at}.body`, 'A row template body is a page snapshot: { \"v\": 1, \"blocks\": [ ... ] }.');\n      }\n      if (rt.values === undefined && rt.body === undefined) say(at, \"A row template presets values, a page body, or both.\");\n    });\n    if (defaults > 1) say(`tables (${t.token}).rowTemplates`, `${defaults} row templates say default; a table has at most one (the one a new row's page opens with).`);\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  const DAY_WORD = /\\b(?:today|tomorrow|yesterday|tonight)\\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        // \"today / tomorrow / yesterday / tonight\" pin an event to the writing day wherever they sit (\"Owner home\n        // tomorrow after 2\"). MEANING, NOT WORDS (TEMPLATE-GAPS 6) for \"this / next / last <period>\": \"Plan next week's sprint\", \"What went well last week\" and \"Review\n        // this month's goals\" are recurring titles, true on any day. A value goes stale only when it STANDS FOR a\n        // date: the whole value is the day phrase (\"Tomorrow\", \"Due next Friday\", \"by end of this week\"), or the\n        // column itself holds a when (a text \"Due\" / \"Deadline\" / \"Date\" column).\n        const whenColumn = /\\b(date|due|deadline|when|day|eta|scheduled|starts?|ends?)\\b/i.test(`${f.key.replace(/_/g, \" \")} ${f.label}`);\n        const standsForDate = typeof text === \"string\" && new RegExp(`^\\\\s*(?:(?:due|by|until|till|on|from|starting|ends?|before|after)\\\\s+)?(?:(?:the\\\\s+)?end\\\\s+of\\\\s+)?(?:${STALE.source})[\\\\s.!,]*$`, \"i\").test(text);\n        if (typeof text === \"string\" && !RELATIVE_DATE.test(text) && STALE.test(text) && (DAY_WORD.test(text) || whenColumn || standsForDate)) {\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 colors mean something: done is never red, failed is never green ──\n  const GOOD = GOOD_OUTCOME;\n  const BAD = BAD_OUTCOME;\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    // The install door types every availability key; a value of the wrong type (days as a weekday list) passed here once and failed at install.\n    type AvKey = \"slotMinutes\" | \"bufferMinutes\" | \"leadMinutes\" | \"maxPerDay\" | \"days\";\n    const wholeNumber = (key: AvKey, what: string): boolean => {\n      const v = (a as Record<string, unknown>)[key];\n      if (v === undefined || (typeof v === \"number\" && Number.isInteger(v))) return true;\n      say(`${at}.availability.${key}`, key === \"days\" ? `${what} is ONE whole number such as 21 (how many days ahead a person may book); the weekdays belong in windows, not here.` : `${what} is one whole number; this says ${JSON.stringify(v)}.`);\n      return false;\n    };\n    const rng = (v: number | undefined, lo: number, hi: number, what: string, key: AvKey) => {\n      if (v !== undefined && wholeNumber(key, what) && (v < lo || v > hi)) say(`${at}.availability`, `${what} is between ${lo} and ${hi}; this says ${v}.`);\n    };\n    (a.windows ?? []).forEach((w, wi) => {\n      const ww = w as unknown as Record<string, unknown>;\n      if (!Number.isInteger(ww.weekday)) say(`${at}.availability.windows[${wi}]`, `A window's weekday is one whole number, 0 (Sunday) to 6 (Saturday); this says ${JSON.stringify(ww.weekday)}.`);\n      for (const k of [\"from\", \"to\"]) if (typeof ww[k] !== \"string\" || !/^\\d{2}:\\d{2}$/.test(ww[k] as string)) say(`${at}.availability.windows[${wi}]`, `A window's \"${k}\" is a time of day written \"09:00\"; this says ${JSON.stringify(ww[k])}.`);\n    });\n    rng(a.slotMinutes, 5, 480, \"Slot length (minutes)\", \"slotMinutes\");\n    rng(a.bufferMinutes, 0, 480, \"The buffer (minutes)\", \"bufferMinutes\");\n    rng(a.leadMinutes, 0, 43200, \"Lead time (minutes)\", \"leadMinutes\");\n    rng(a.maxPerDay, 1, 100, \"Appointments a day\", \"maxPerDay\");\n    rng(a.days, 1, 90, \"Days ahead\", \"days\");\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) suggest(`${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) suggest(`${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    suggest(\"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      ...(suggestions.length ? { suggestions } : {}),\n      ...(upgradeWarnings.length ? { warnings: upgradeWarnings } : {}),\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, ...(suggestions.length ? { suggestions } : {}), ...(upgradeWarnings.length ? { warnings: upgradeWarnings } : {}) };\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|card_on_file|credit_card|debit_card|payment_card|cvv|cvc)($|_)/;\n// A bare \"card\" is a flashcard, a gallery card, a kanban card or a recipe card; only the payment words above floor it.\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/** Choice words that are a good outcome (never painted red) and a bad one (never painted green). One reading for the check and the describe autofix. */\nexport const GOOD_OUTCOME = /^(completed?|done|paid|approved|won|closed won|booked|confirmed|delivered|resolved|published|signed|passed|hired|accepted)$/i;\nexport const BAD_OUTCOME = /^(cancell?ed|skipped|lost|closed lost|denied|rejected|no[- ]show|failed|overdue|declined|void(ed)?|refunded|churned|expired|blocked)$/i;\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/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 catalog 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 catalog 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 catalog — 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, 32 declarable field kinds,\n// 158 rule node kinds,\n// 9 kernel Tables, 1065 doors, 78 knobs,\n// 1303 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 behavior 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 behaviors 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: \"button\", behavior: \"text\", parity: false, made_of: \"NOTION-PROPS-2: behaviour text, format button; holds no value. config.button says what a press does through custom.button_press: open_url (url, {{field id}} filled from the row), run_automation (one of the table's automations, on this row) or run_action (one of its row actions, which sets fields), or add_row (a new row in this table or table_id's, prefilled from this row by prefill, opened); a button with no do yet is a label only\" },\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: \"json\", behavior: \"text\", parity: false, made_of: \"W2-A: behaviour text, format json; any JSON value (object, list, number, words, yes/no) kept as jsonb, shown collapsed\" },\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: \"time\", behavior: \"text\", parity: false, made_of: \"W2-A: behaviour text, format time; a time of day with no date kept as 24-hour HH:MM or HH:MM:SS (zero-padded, so its text order is its time order); HOUR, MINUTE and SECOND read 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: \"contains\", evaluated_by: \"NOTION-Q\" },\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.arrayflatten\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.arrayjoin\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.arrayslice\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.arrayunique\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.at\", 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.ceiling\", 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.count\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.counta\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.countall\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.created_time\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.current\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.current1\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.current2\", 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.datestr\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.datetime_diff\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.datetime_format\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.datetime_parse\", 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.encode_url_component\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.eq\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.error\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.even\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.every\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.exp\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.false\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.filter\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.find\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.findfirst\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.first\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.floor\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.fromnow\", 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.hour\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.if\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.includes\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.index\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.int\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.is_after\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.is_before\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.is_same\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.isblank\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.iserror\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.join\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.last\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.last_modified_time\", 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.length\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.log\", 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.map\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.max\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.median\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.mid\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.min\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.minute\", 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.odd\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.or\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.power\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.record_id\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.recprop\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.regex_extract\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.regex_match\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.regex_replace\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.regexreplace\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.replace\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.rept\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.reverse\", 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.rounddown\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.roundup\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.search\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.second\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.set_locale\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.set_timezone\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.slice\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.some\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.sort\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.split\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.sqrt\", 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.t\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.timestr\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.today\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.tonow\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.trim\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.true\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.unique\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.upper\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.value\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.weekday\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.weeknum\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.workday\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.workday_diff\", evaluated_by: \"GRID-PRIMITIVES G3 (custom.formula_eval)\" },\n  { node: \"fx.xor\", 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: \"has_all\", evaluated_by: \"NOTION-Q\" },\n  { node: \"has_any\", evaluated_by: \"NOTION-Q\" },\n  { node: \"has_none\", evaluated_by: \"NOTION-Q\" },\n  { node: \"is_empty\", evaluated_by: \"NOTION-Q\" },\n  { node: \"is_exactly\", evaluated_by: \"NOTION-Q\" },\n  { node: \"is_not_empty\", evaluated_by: \"NOTION-Q\" },\n  { node: \"length\", evaluated_by: \"W1-RULE\" },\n  { node: \"linked\", evaluated_by: \"NOTION-Q\" },\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: \"not_contains\", evaluated_by: \"NOTION-Q\" },\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/**\n * What each formula node answers (`custom.formula_node_kinds()`): number, text, boolean, date or unknown.\n * Generated, so a function the store adds can never be missing from a screen that types a formula.\n */\nexport const FORMULA_NODE_RESULTS: Readonly<Record<string, string>> = {\n  \"fx.abs\": \"number\",\n  \"fx.add\": \"number\",\n  \"fx.and\": \"boolean\",\n  \"fx.arraycompact\": \"unknown\",\n  \"fx.arrayflatten\": \"unknown\",\n  \"fx.arrayjoin\": \"text\",\n  \"fx.arrayslice\": \"unknown\",\n  \"fx.arrayunique\": \"unknown\",\n  \"fx.at\": \"unknown\",\n  \"fx.autonumber\": \"number\",\n  \"fx.average\": \"number\",\n  \"fx.blank\": \"unknown\",\n  \"fx.ceiling\": \"number\",\n  \"fx.concatenate\": \"text\",\n  \"fx.contains\": \"boolean\",\n  \"fx.count\": \"number\",\n  \"fx.counta\": \"number\",\n  \"fx.countall\": \"number\",\n  \"fx.created_time\": \"date\",\n  \"fx.current\": \"unknown\",\n  \"fx.current1\": \"unknown\",\n  \"fx.current2\": \"unknown\",\n  \"fx.dateadd\": \"date\",\n  \"fx.datediff\": \"number\",\n  \"fx.datestr\": \"text\",\n  \"fx.datetime_diff\": \"number\",\n  \"fx.datetime_format\": \"text\",\n  \"fx.datetime_parse\": \"date\",\n  \"fx.day\": \"number\",\n  \"fx.div\": \"number\",\n  \"fx.encode_url_component\": \"text\",\n  \"fx.eq\": \"boolean\",\n  \"fx.error\": \"unknown\",\n  \"fx.even\": \"number\",\n  \"fx.every\": \"boolean\",\n  \"fx.exp\": \"number\",\n  \"fx.false\": \"boolean\",\n  \"fx.filter\": \"unknown\",\n  \"fx.find\": \"number\",\n  \"fx.findfirst\": \"unknown\",\n  \"fx.first\": \"unknown\",\n  \"fx.floor\": \"number\",\n  \"fx.fromnow\": \"number\",\n  \"fx.gt\": \"boolean\",\n  \"fx.gte\": \"boolean\",\n  \"fx.hour\": \"number\",\n  \"fx.if\": \"unknown\",\n  \"fx.includes\": \"boolean\",\n  \"fx.index\": \"number\",\n  \"fx.int\": \"number\",\n  \"fx.is_after\": \"boolean\",\n  \"fx.is_before\": \"boolean\",\n  \"fx.is_same\": \"boolean\",\n  \"fx.isblank\": \"boolean\",\n  \"fx.iserror\": \"boolean\",\n  \"fx.join\": \"text\",\n  \"fx.last\": \"unknown\",\n  \"fx.last_modified_time\": \"date\",\n  \"fx.left\": \"text\",\n  \"fx.len\": \"number\",\n  \"fx.length\": \"number\",\n  \"fx.log\": \"number\",\n  \"fx.lower\": \"text\",\n  \"fx.lt\": \"boolean\",\n  \"fx.lte\": \"boolean\",\n  \"fx.map\": \"unknown\",\n  \"fx.max\": \"number\",\n  \"fx.median\": \"number\",\n  \"fx.mid\": \"text\",\n  \"fx.min\": \"number\",\n  \"fx.minute\": \"number\",\n  \"fx.mod\": \"number\",\n  \"fx.modified_time\": \"date\",\n  \"fx.month\": \"number\",\n  \"fx.mul\": \"number\",\n  \"fx.ne\": \"boolean\",\n  \"fx.neg\": \"number\",\n  \"fx.not\": \"boolean\",\n  \"fx.now\": \"date\",\n  \"fx.odd\": \"number\",\n  \"fx.or\": \"boolean\",\n  \"fx.power\": \"number\",\n  \"fx.record_id\": \"text\",\n  \"fx.recprop\": \"unknown\",\n  \"fx.regex_extract\": \"text\",\n  \"fx.regex_match\": \"boolean\",\n  \"fx.regex_replace\": \"text\",\n  \"fx.regexreplace\": \"text\",\n  \"fx.replace\": \"text\",\n  \"fx.rept\": \"text\",\n  \"fx.reverse\": \"unknown\",\n  \"fx.right\": \"text\",\n  \"fx.round\": \"number\",\n  \"fx.rounddown\": \"number\",\n  \"fx.roundup\": \"number\",\n  \"fx.search\": \"number\",\n  \"fx.second\": \"number\",\n  \"fx.set_locale\": \"date\",\n  \"fx.set_timezone\": \"date\",\n  \"fx.slice\": \"unknown\",\n  \"fx.some\": \"boolean\",\n  \"fx.sort\": \"unknown\",\n  \"fx.split\": \"unknown\",\n  \"fx.sqrt\": \"number\",\n  \"fx.sub\": \"number\",\n  \"fx.substitute\": \"text\",\n  \"fx.sum\": \"number\",\n  \"fx.switch\": \"unknown\",\n  \"fx.t\": \"text\",\n  \"fx.timestr\": \"text\",\n  \"fx.today\": \"date\",\n  \"fx.tonow\": \"number\",\n  \"fx.trim\": \"text\",\n  \"fx.true\": \"boolean\",\n  \"fx.unique\": \"unknown\",\n  \"fx.upper\": \"text\",\n  \"fx.value\": \"number\",\n  \"fx.weekday\": \"number\",\n  \"fx.weeknum\": \"number\",\n  \"fx.workday\": \"date\",\n  \"fx.workday_diff\": \"number\",\n  \"fx.xor\": \"boolean\",\n  \"fx.year\": \"number\",\n};\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 * catalog 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: \"admin_all_tables\", args: \"\", returns: \"TABLE(table_id uuid, table_name text, organization_id uuid, organization_name text, updated_at timestamp with time zone, platform_owned boolean, system boolean)\", 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_group_value\", args: \"p_value text, p_kind text\", returns: \"jsonb\", 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_split_parts\", args: \"p_organization_id uuid, p_table_id uuid, p_key text, p_alias text\", 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, p_split_multi boolean DEFAULT false\", 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: \"archive_guard_count\", args: \"p_value jsonb\", returns: \"integer\", security: \"invoker\" },\n  { name: \"archive_guard_decide\", args: \"p_organization_id uuid, p_scope text, p_live_before integer, p_ids text[], p_confirm text, p_log jsonb, p_now timestamp with time zone DEFAULT now(), p_share numeric DEFAULT NULL::numeric, p_hours numeric DEFAULT NULL::numeric\", returns: \"jsonb\", security: \"invoker\" },\n  { name: \"archive_guard_knob\", args: \"p_key text, p_organization_id uuid\", returns: \"numeric\", security: \"invoker\" },\n  { name: \"archive_guard_log_add\", args: \"p_log jsonb, p_entry jsonb, p_organization_id uuid, p_now timestamp with time zone DEFAULT now()\", returns: \"jsonb\", security: \"invoker\" },\n  { name: \"archive_guard_when\", args: \"p_value jsonb\", returns: \"timestamp with time zone\", security: \"invoker\" },\n  { name: \"archive_hold_answer\", args: \"p_organization_id uuid, p_table_id uuid, p_answer text, p_token text\", returns: \"jsonb\", 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_public_reader_names_a_public_table\", args: \"p_organization_id uuid, p_table_id uuid, p_door text\", returns: \"void\", security: \"definer\" },\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: \"automation_app_event\", args: \"p_automation_id uuid, p_items jsonb, p_cursor jsonb, p_expected_owner text\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automation_app_may_edit\", args: \"p_automation_id uuid, p_user_id uuid\", returns: \"boolean\", security: \"definer\" },\n  { name: \"automation_app_note\", args: \"p_automation_id uuid, p_says text, p_cursor jsonb, p_expected_owner text\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automation_app_stop\", args: \"p_automation_id uuid, p_says text, p_expected_owner text\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automation_app_watch\", args: \"p_automation_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automation_archive\", args: \"p_organization_id uuid, p_automation_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automation_claim_pending\", args: \"p_worker text, p_limit integer DEFAULT 5, p_lease_seconds integer DEFAULT 180\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automation_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_spec jsonb, p_automation_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automation_delivery_tick\", args: \"\", returns: \"integer\", security: \"invoker\" },\n  { name: \"automation_note\", args: \"p_run_id uuid, p_says text\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automation_restore\", args: \"p_organization_id uuid, p_automation_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automation_resume\", args: \"p_run_id uuid, p_output jsonb, p_error text DEFAULT NULL::text, p_logs jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automation_revision_restore\", args: \"p_organization_id uuid, p_automation_id uuid, p_revision_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automation_revisions\", args: \"p_organization_id uuid, p_automation_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automation_runs\", args: \"p_automation_id uuid, p_limit integer DEFAULT 50, p_cursor timestamp with time zone DEFAULT NULL::timestamp with time zone, p_organization_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automation_set_enabled\", args: \"p_organization_id uuid, p_automation_id uuid, p_enabled boolean\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automation_step_mark\", args: \"p_run_id uuid, p_n integer, p_state text, p_output jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automation_test\", args: \"p_organization_id uuid, p_automation_id uuid, p_record_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automation_time_tick\", args: \"\", returns: \"jsonb\", security: \"invoker\" },\n  { name: \"automation_webhook_receive\", args: \"p_automation_id uuid, p_secret text, p_body jsonb\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"automations\", args: \"p_table_id uuid, p_organization_id uuid DEFAULT NULL::uuid, p_include_archived boolean DEFAULT false\", returns: \"jsonb\", security: \"definer\" },\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: \"base_activity\", args: \"p_organization_id uuid, p_subject_id uuid, p_limit integer DEFAULT 50, p_before bigint DEFAULT NULL::bigint\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"base_copy_finish\", args: \"p_organization_id uuid, p_pairs jsonb\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"base_move\", args: \"p_home_id uuid, p_to_organization_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"base_move_access_kept\", args: \"p_home_id uuid, p_to_organization_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"base_move_remove_access\", args: \"p_home_id uuid, p_user_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"booking_busy_due\", args: \"p_form_id uuid\", returns: \"TABLE(feed text, due boolean, timezone text, days integer, read_at timestamp with time zone)\", security: \"definer\" },\n  { name: \"booking_busy_set\", args: \"p_form_id uuid, p_busy jsonb, p_problem text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\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_messages\", args: \"p_organization_id uuid, p_form_id uuid, p_record_id uuid, p_submission_id uuid, p_event text\", returns: \"jsonb\", security: \"invoker\" },\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: \"booking_sms_consent\", args: \"p_booking_ref text, p_phone text, p_text_shown text, p_origin text DEFAULT NULL::text\", returns: \"jsonb\", 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: \"button_press\", args: \"p_organization_id uuid, p_record_id uuid, p_field_id uuid\", returns: \"jsonb\", 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_value_keys\", args: \"p_field jsonb, p_value jsonb\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"choice_words\", args: \"p_field jsonb\", returns: \"text\", security: \"invoker\" },\n  { name: \"choice_words_normalize\", args: \"p_field jsonb, p_const jsonb\", returns: \"jsonb\", security: \"invoker\" },\n  { name: \"client_write_grants\", args: \"\", returns: \"TABLE(role_name text, object_name text, privilege text)\", security: \"invoker\" },\n  { name: \"comment_counts\", args: \"p_organization_id uuid, p_record_ids uuid[]\", returns: \"jsonb\", security: \"definer\" },\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: \"computed_refresh\", args: \"p_org uuid, p_table uuid, p_ids uuid[]\", returns: \"integer\", security: \"invoker\" },\n  { name: \"computed_refresh\", args: \"p_table_id uuid, p_max_rows integer DEFAULT 200\", returns: \"integer\", security: \"definer\" },\n  { name: \"computed_refresh_drain\", args: \"p_ms integer DEFAULT 8000\", returns: \"integer\", security: \"invoker\" },\n  { name: \"computed_refresh_progress\", args: \"p_org uuid\", returns: \"jsonb\", security: \"invoker\" },\n  { name: \"computed_sort_ceiling\", args: \"\", returns: \"integer\", security: \"invoker\" },\n  { name: \"computed_warm\", args: \"p_table_id uuid\", returns: \"boolean\", 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: \"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: \"copy_table_extras\", args: \"p_organization_id uuid, p_pairs jsonb\", 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_on\", args: \"p_organization_id uuid, p_table_token text\", returns: \"TABLE(field_id uuid, field_key text, field_label text, field_type text, field_source text, field_required boolean, field_sort numeric, table_label text)\", security: \"definer\" },\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_platform_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_custom_fields\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"TABLE(organization_id uuid, organization_name text, table_token text, table_label text, field_count integer, updated_at timestamp with time zone)\", security: \"definer\" },\n  { name: \"data_home_first\", args: \"p_organization_id uuid DEFAULT NULL::uuid, p_include_platform_tables boolean DEFAULT false, p_limit integer DEFAULT 100\", returns: \"jsonb\", 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_slim\", args: \"p_organization_id uuid DEFAULT NULL::uuid, p_search text DEFAULT NULL::text, p_include_platform_tables boolean DEFAULT false\", returns: \"jsonb\", security: \"invoker\" },\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, platform_owned boolean, kind text, team boolean, system boolean, created_by uuid)\", security: \"definer\" },\n  { name: \"data_home_tables\", args: \"p_organization_id uuid, p_include_platform_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, platform_owned boolean, kind text, team boolean, system boolean, created_by uuid)\", security: \"invoker\" },\n  { name: \"day_zone\", args: \"p_organization_id uuid DEFAULT NULL::uuid\", returns: \"text\", 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: \"definer\" },\n  { name: \"doc_render_delete\", args: \"p_organization_id uuid, p_render_id uuid\", returns: \"boolean\", security: \"definer\" },\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_restore\", args: \"p_organization_id uuid, p_render_id uuid\", returns: \"boolean\", 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: \"door_reads_only\", args: \"p_door text\", returns: \"boolean\", 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: \"effective_level_many\", args: \"p_user_id uuid, p_ids uuid[], p_type text DEFAULT 'record'::text\", returns: \"TABLE(id uuid, level 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_data_source\", args: \"p_ds jsonb, p_inputs jsonb\", returns: \"jsonb\", security: \"invoker\" },\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_refill_due_tick\", args: \"\", returns: \"jsonb\", security: \"invoker\" },\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_back_links\", args: \"p_organization_id uuid, p_token text, p_record_id uuid, p_limit integer DEFAULT 50, p_cursor text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"entity_custom_value_apply\", args: \"p_organization_id uuid, p_token text, p_record_id uuid, p_clear text[], p_patch jsonb, p_expected_version integer DEFAULT NULL::integer\", returns: \"integer\", security: \"definer\" },\n  { name: \"entity_custom_values_lock\", args: \"p_token text\", returns: \"TABLE(locked boolean, reason text)\", 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, p_include_retired boolean DEFAULT false\", 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_access_set\", args: \"p_field_id uuid, p_part text, p_word text\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"field_access_setup\", args: \"p_field_id uuid, p_proposed jsonb DEFAULT NULL::jsonb\", 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_declare_many\", args: \"p_organization_id uuid, p_table_id uuid, p_specs jsonb\", returns: \"uuid[]\", security: \"invoker\" },\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_duplicate\", args: \"p_organization_id uuid, p_field_id uuid\", returns: \"jsonb\", 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_input_closure_many\", args: \"p_organization_id uuid, p_ids uuid[]\", returns: \"TABLE(root_id uuid, input_id uuid, 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_make_automatic\", args: \"p_organization_id uuid, p_field_id uuid, p_kind text\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"field_notify_on_assign\", args: \"p_organization_id uuid, p_field_id uuid, p_on boolean\", returns: \"jsonb\", security: \"definer\" },\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_retype_preview\", args: \"p_organization_id uuid, p_field_id uuid, p_patch jsonb\", returns: \"jsonb\", 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: \"filter_list_op\", args: \"p_op text, p_a jsonb, p_b jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"invoker\" },\n  { name: \"filter_list_op_words\", args: \"\", returns: \"text[]\", security: \"invoker\" },\n  { name: \"find_duplicates\", args: \"p_organization_id uuid, p_table_id uuid, p_fields text[], p_limit integer DEFAULT 50\", returns: \"jsonb\", security: \"definer\" },\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_knobs\", args: \"p_organization_id uuid\", returns: \"jsonb\", 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_preview_route\", args: \"p_organization_id uuid, p_table_id uuid, p_questions jsonb, p_endings jsonb, p_values jsonb\", returns: \"jsonb\", 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_public_options\", args: \"p_form_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"form_public_route\", args: \"p_form_id uuid, p_values jsonb\", returns: \"jsonb\", 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_respondent_copy\", args: \"p_organization_id uuid, p_form_id uuid, p_record_id uuid, p_submission_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"form_response_read\", args: \"p_form_id uuid, p_edit text, p_unlock text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"form_response_update\", args: \"p_form_id uuid, p_edit text, p_origin text, p_payload jsonb, p_bucket text\", returns: \"TABLE(submission_id uuid, record_id uuid, state text, message text)\", security: \"definer\" },\n  { name: \"form_restore\", args: \"p_organization_id uuid, p_form_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"form_results\", args: \"p_organization_id uuid, p_form_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"form_set_password\", args: \"p_organization_id uuid, p_form_id uuid, p_password text DEFAULT NULL::text\", 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: \"form_theme_options\", args: \"\", returns: \"jsonb\", security: \"invoker\" },\n  { name: \"form_unlock\", args: \"p_form_id uuid, p_password text DEFAULT NULL::text, p_unlock text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"form_visit\", args: \"p_form_id uuid, p_visit text, p_event text, p_field text DEFAULT NULL::text\", returns: \"text\", security: \"definer\" },\n  { name: \"form_visit_admit\", args: \"p_form_id uuid, p_bucket text\", returns: \"boolean\", 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: \"forms_archived_everywhere\", args: \"\", returns: \"jsonb\", security: \"invoker\" },\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_history\", args: \"p_organization_id uuid, p_record_id uuid, p_field_key text, p_limit integer DEFAULT 100\", returns: \"TABLE(occurred_at timestamp with time zone, cause text, record_version integer, formula_version integer, formula_text text, value jsonb, refused text, actor jsonb)\", security: \"definer\" },\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_preview\", args: \"p_organization_id uuid, p_table_id uuid, p_record_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_translate_notion\", args: \"p_text text, p_types jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", 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: \"hot_doors_6_on\", args: \"p_person uuid\", returns: \"boolean\", security: \"invoker\" },\n  { name: \"hot_doors_7_on\", args: \"p_person uuid\", returns: \"boolean\", 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: \"hub_changed_by_many\", args: \"p_asks jsonb, p_door text DEFAULT NULL::text\", returns: \"TABLE(organization_id uuid, id uuid, at timestamp with time zone, who text)\", security: \"definer\" },\n  { name: \"hub_row_asked_alone\", args: \"p_org uuid, p_id uuid\", returns: \"boolean\", security: \"invoker\" },\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: \"interface_chart\", args: \"p_interface_id uuid, p_chart_id text\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"interface_chart_formula_ok\", args: \"p_org uuid, p_table uuid, p_key text, p_allowed text[], p_depth integer\", returns: \"boolean\", security: \"invoker\" },\n  { name: \"interface_read\", args: \"p_interface_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"interface_rows\", args: \"p_interface_id uuid, p_element_id text, p_record_id uuid DEFAULT NULL::uuid, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0\", returns: \"jsonb\", security: \"definer\" },\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: \"kernel_viewer_sets\", args: \"p_user uuid, p_orgs uuid[]\", returns: \"TABLE(organization_id uuid, fallback boolean, all_visible boolean, granted_all uuid[], carried_visible uuid[])\", security: \"definer\" },\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: \"may_see_table_structure\", 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: \"my_levels_across\", args: \"p_asks jsonb\", returns: \"TABLE(organization_id uuid, id uuid, level permission_level, refused text)\", security: \"definer\" },\n  { name: \"opening_view_shape\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"invoker\" },\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_has_a_public_table\", args: \"p_organization_id uuid\", returns: \"boolean\", 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_for_selection\", args: \"p_list_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"pick_list_get\", args: \"p_list_id uuid\", 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: \"pick_list_update\", args: \"p_list_id uuid, p_list_name text DEFAULT NULL::text, p_description text DEFAULT NULL::text, p_items jsonb DEFAULT NULL::jsonb\", 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_self_signup\", args: \"p_slug text, p_email text, p_name text\", 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: \"public_definition_owner\", args: \"p_organization_id uuid, p_table_id uuid, p_record_id uuid\", returns: \"uuid\", 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: \"published_view_read\", args: \"p_slug 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: \"reaches_directly_many\", args: \"p_user_id uuid, p_targets uuid[], p_type text DEFAULT 'record'::text, p_required permission_level DEFAULT 'viewer'::permission_level\", returns: \"TABLE(target uuid, reaches 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_keyset\", 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_after jsonb DEFAULT NULL::jsonb, p_limit integer DEFAULT 50, p_time_zone text DEFAULT NULL::text, p_ids uuid[] DEFAULT NULL::uuid[]\", returns: \"jsonb\", 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_presence_topic_admits\", args: \"p_topic text\", returns: \"boolean\", security: \"invoker\" },\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, p_split_multi boolean DEFAULT false\", 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_drill\", args: \"p_organization_id uuid, p_table_id uuid, p_question jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", 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_follow_set\", args: \"p_organization_id uuid, p_record_id uuid, p_follow boolean DEFAULT true\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"record_followers\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"definer\" },\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_org_hint\", args: \"p_id uuid, p_organization_id uuid\", returns: \"uuid\", security: \"invoker\" },\n  { name: \"record_page_bundle\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"jsonb\", security: \"invoker\" },\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: \"jsonb\", 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_limits\", args: \"p_organization_id uuid\", returns: \"jsonb\", 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_platform_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_reverse_field\", args: \"p_organization_id uuid, p_field_id uuid, p_label text DEFAULT NULL::text\", returns: \"uuid\", security: \"definer\" },\n  { name: \"relation_reverse_set\", args: \"p_organization_id uuid, p_record_id uuid, p_field_id uuid, p_add uuid[] DEFAULT '{}'::uuid[], p_remove uuid[] DEFAULT '{}'::uuid[]\", returns: \"integer\", 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: \"relation_words_with_icons_many\", args: \"p_organization_id uuid, p_field_id uuid, p_record_ids uuid[]\", returns: \"TABLE(record_id uuid, words text, archived boolean, icon text, table_icon text)\", security: \"definer\" },\n  { name: \"relative_window_for_reader\", args: \"p_window jsonb, p_organization_id uuid, p_instants boolean DEFAULT false\", returns: \"jsonb\", security: \"invoker\" },\n  { name: \"relative_window_resolve\", args: \"p_window jsonb\", returns: \"jsonb\", security: \"invoker\" },\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: \"reverse_links_many_fields\", args: \"p_organization_id uuid, p_table_id uuid, p_field_ids uuid[], p_record_ids uuid[], p_limit integer DEFAULT 10, p_offset integer DEFAULT 0\", returns: \"TABLE(field_id uuid, record_id uuid, total integer, links jsonb)\", security: \"invoker\" },\n  { name: \"revoke_view_share_link\", args: \"p_link_id uuid\", returns: \"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_bodies\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(template_id uuid, body jsonb)\", security: \"definer\" },\n  { name: \"row_template_declare\", args: \"p_organization_id uuid, p_table_id uuid, p_spec jsonb\", returns: \"uuid\", security: \"definer\" },\n  { name: \"row_template_default\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(template_id uuid, name text, \\\"values\\\" jsonb, body jsonb)\", 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_filter_skip_withheld\", args: \"p_organization_id uuid, p_table_id uuid, p_node jsonb, p_visible text[]\", returns: \"jsonb\", security: \"invoker\" },\n  { name: \"rule_is_me\", args: \"p_op text, p_a jsonb\", returns: \"jsonb\", security: \"invoker\" },\n  { name: \"rule_is_me\", args: \"p_op text, p_a jsonb, p_organization_id uuid\", returns: \"jsonb\", 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\", args: \"p_table_id uuid, p_readers jsonb, p_reason text\", returns: \"jsonb\", security: \"definer\" },\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: \"set_table_organization\", args: \"p_table_id uuid, p_reason text\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"set_view_share_link_copy\", args: \"p_link_id uuid, p_restrict boolean\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"set_view_share_link_protection\", args: \"p_link_id uuid, p_password text DEFAULT NULL::text, p_change_expiry boolean DEFAULT false, p_expires_at timestamp with time zone DEFAULT NULL::timestamp with time zone\", 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_lists_row\", args: \"p_id uuid\", returns: \"boolean\", security: \"invoker\" },\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: \"shared_view_read\", args: \"p_token text, p_password text DEFAULT NULL::text, p_unlock text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\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_sentence\", args: \"p_data jsonb\", returns: \"text\", security: \"invoker\" },\n  { name: \"sign_request_state\", args: \"p_data jsonb\", returns: \"text\", security: \"invoker\" },\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: \"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: \"space_templates\", args: \"p_filter jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"definer\" },\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_field_part\", args: \"p_field_data jsonb\", returns: \"text\", 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: \"store_part_notice\", args: \"p_field custom.record, p_action text DEFAULT 'read'::text\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"store_part_who\", args: \"p_cells jsonb, p_action text DEFAULT 'read'::text\", returns: \"text\", security: \"definer\" },\n  { name: \"store_row_visible\", args: \"p_person uuid, p_table uuid, p_row custom.record, p_visible text[]\", returns: \"text[]\", security: \"definer\" },\n  { name: \"store_row_visible_with\", args: \"p_reveals jsonb, p_person uuid, p_row custom.record, p_visible text[]\", returns: \"text[]\", security: \"definer\" },\n  { name: \"store_seat_fallback\", args: \"p_org uuid\", returns: \"SETOF uuid\", security: \"definer\" },\n  { name: \"store_seat_has\", args: \"p_person uuid, p_record uuid, p_seat jsonb\", returns: \"boolean\", security: \"definer\" },\n  { name: \"store_seat_holders\", args: \"p_record uuid, p_seat jsonb\", returns: \"TABLE(user_id uuid, source text)\", security: \"definer\" },\n  { name: \"store_seat_invalid\", args: \"p_seat jsonb\", returns: \"text\", security: \"invoker\" },\n  { name: \"store_seat_records\", args: \"p_person uuid, p_table uuid, p_seat jsonb\", returns: \"SETOF uuid\", security: \"definer\" },\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: \"synced_source_archive_log\", args: \"p_id uuid, p_job text DEFAULT NULL::text\", returns: \"jsonb\", security: \"invoker\" },\n  { name: \"synced_source_archive_log_add\", args: \"p_id uuid, p_job text, p_entry jsonb, p_now timestamp with time zone DEFAULT now()\", returns: \"jsonb\", security: \"invoker\" },\n  { name: \"synced_source_by_ref\", args: \"p_organization_id uuid, p_source_kinds text[], p_source_ref text\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"synced_source_finish\", args: \"p_id uuid, p_cursor jsonb, p_synced_at timestamp with time zone, p_report jsonb, p_mapping jsonb, p_run_id uuid\", returns: \"void\", security: \"definer\" },\n  { name: \"synced_source_read\", args: \"p_organization_id uuid, p_source_kind text, p_target uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"synced_source_save\", args: \"p_organization_id uuid, p_source_kind text, p_source_ref text, p_title text, p_target uuid, p_owner uuid, p_connector jsonb, p_actor uuid\", returns: \"uuid\", security: \"definer\" },\n  { name: \"synced_sources_for\", args: \"p_source_ref text\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"table_access_setup\", args: \"p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"table_access_setup_preview\", args: \"p_table_id uuid, p_setup jsonb, p_moves jsonb DEFAULT '{}'::jsonb\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"table_access_setup_revert\", args: \"p_table_id uuid, p_audit_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"table_access_setup_set\", args: \"p_table_id uuid, p_setup jsonb, p_moves jsonb DEFAULT '{}'::jsonb, p_reason text DEFAULT NULL::text\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"table_add_rung\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"permission_level\", security: \"invoker\" },\n  { name: \"table_agent_writable_set\", args: \"p_organization_id uuid, p_table_id uuid, p_agent_writable boolean\", returns: \"jsonb\", security: \"definer\" },\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_copy_sync\", args: \"p_organization_id uuid, p_spec jsonb\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"table_create\", args: \"p_organization_id uuid, p_spec jsonb, p_fields jsonb\", returns: \"jsonb\", security: \"invoker\" },\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, platform_owned 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_find_many\", args: \"p_organization_ids uuid[], p_slug 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_homes_named\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"TABLE(home_id uuid, name text, declared boolean)\", 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_level_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_platform_tables boolean\", returns: \"jsonb\", security: \"invoker\" },\n  { name: \"table_map_fields\", args: \"p_organization_id uuid, p_table_ids uuid[]\", returns: \"TABLE(table_id uuid, field_key text, field_label text, field_type text, relation_target uuid, inverse_key text, field_sort numeric, is_link boolean)\", security: \"definer\" },\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_page_bundle\", args: \"p_organization_id uuid, p_table_id uuid, p_view_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"invoker\" },\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_row_label\", args: \"p_organization_id uuid, p_table_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"table_row_label_set\", args: \"p_organization_id uuid, p_table_id uuid, p_formula text\", 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_sync_cell\", args: \"p_organization_id uuid, p_record_id uuid, p_key text, p_land jsonb\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"table_sync_due_tick\", args: \"\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"table_sync_settings_set\", args: \"p_organization_id uuid, p_table_id uuid, p_settings jsonb\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"table_template_declare\", args: \"p_org_id uuid, p_name text, p_description text, p_fields jsonb\", returns: \"uuid\", security: \"invoker\" },\n  { name: \"table_templates\", args: \"p_org_id uuid\", 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_fresh\", args: \"p_organization_id uuid, p_template_id uuid, p_title text DEFAULT NULL::text, p_install_id uuid DEFAULT NULL::uuid, p_budget_ms integer DEFAULT 4000\", 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_instance_of_page\", args: \"p_organization_id uuid, p_page_id uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"template_instances\", args: \"p_organization_id uuid, p_catalogue_id 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: \"template_upgrade\", args: \"p_organization_id uuid, p_install_id uuid, p_template_id uuid\", 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: \"timeline_dependency_shift\", args: \"p_organization_id uuid\", returns: \"boolean\", security: \"definer\" },\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: \"unmatched_people_resolve\", args: \"p_organization_id uuid, p_user_id uuid\", returns: \"integer\", security: \"definer\" },\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: \"view_share_links\", args: \"p_view_id uuid\", returns: \"TABLE(id uuid, token text, permission_level text, label text, expires_at timestamp with time zone, use_count integer, last_used_at timestamp with time zone, created_at timestamp with time zone, created_by uuid, created_by_name text, made_by_me boolean, has_password boolean, restrict_copy boolean)\", 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: \"who_could_see_on\", args: \"p_record_id uuid, p_at timestamp with time zone\", returns: \"jsonb\", 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_retired\", args: \"p_doc jsonb, p_retired jsonb, p_visible text[], p_declared text[]\", returns: \"jsonb\", 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_host_run\", args: \"p_organization_id uuid, p_fingerprint text, p_conversation_id uuid DEFAULT NULL::uuid, p_approval_id uuid DEFAULT NULL::uuid\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"work_approval_host_run_done\", args: \"p_organization_id uuid, p_approval_id uuid, p_ok boolean, p_outcome text, p_report jsonb DEFAULT NULL::jsonb\", returns: \"jsonb\", security: \"definer\" },\n  { name: \"work_approval_is_approver\", args: \"p_organization_id uuid, p_subject_id uuid, p_approver_id uuid, p_user_id uuid\", returns: \"boolean\", security: \"invoker\" },\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  { name: \"world_reader_may_know_row\", args: \"p_organization_id uuid, p_record_id uuid\", returns: \"boolean\", security: \"definer\" },\n  { name: \"world_reader_only\", args: \"p_organization_id uuid\", returns: \"boolean\", security: \"definer\" },\n  { name: \"world_reader_reads_public_definition\", args: \"p_organization_id uuid, p_table_id uuid, p_record_ids uuid[]\", returns: \"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_value_cap_bytes\", value: \"0\", type: \"integer\" },\n  { key: \"agent_schema_changes\", value: \"\\\"never_ask\\\"\", type: \"string\" },\n  { key: \"ai_column_decision_engine\", value: \"false\", type: \"boolean\" },\n  { key: \"ai_fill_default_rows\", value: \"3\", type: \"integer\" },\n  { key: \"ai_fill_rows_max\", value: \"50\", type: \"integer\" },\n  { key: \"ai_fill_try_max\", value: \"10\", type: \"integer\" },\n  { key: \"archive_confirm_over\", value: \"1000\", type: \"integer\" },\n  { key: \"automation_catch_up_hours\", value: \"48\", type: \"integer\" },\n  { key: \"back_links\", value: \"true\", type: \"boolean\" },\n  { key: \"base_snapshot_keep\", value: \"30\", type: \"integer\" },\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: \"copy_stall_passes\", value: \"20\", type: \"integer\" },\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_estimate_output_tokens\", value: \"200\", type: \"integer\" },\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\\\": \\\"edit_content\\\", \\\"internal\\\": \\\"edit_content\\\", \\\"restricted\\\": \\\"admin\\\", \\\"confidential\\\": \\\"admin\\\"}, \\\"read\\\": {\\\"public\\\": \\\"viewer\\\", \\\"internal\\\": \\\"viewer\\\", \\\"restricted\\\": \\\"admin\\\", \\\"confidential\\\": \\\"admin\\\"}}\", 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: \"host_run_approval_days\", value: \"7\", type: \"integer\" },\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: \"\\\"editor\\\"\", 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: \"retype_preview_bytes_max\", value: \"2000000\", type: \"integer\" },\n  { key: \"retype_preview_values_max\", value: \"100\", type: \"integer\" },\n  { key: \"row_action_steps_max\", value: \"60\", type: \"integer\" },\n  { key: \"row_actions_max\", value: \"24\", 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: \"sheets_write_through\", 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: \"true\", 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,_org_admin_table_gate,_portal_config_judge,_portal_invite_payload,_read_record_with,_record_restore_one,_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_delete,doc_render_document,doc_render_read,doc_render_restore,doc_sign,doc_signature_intact,doc_signature_read,doc_template_delete,doc_template_read,doc_template_restore,doc_template_save,enrich_pin,entity_back_links,entity_custom_value_apply,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_duplicate,field_restore,field_retype_preview,field_update_rehoming_choices,form_archive,form_response_update,form_restore,form_set_password,io_restore,migrate_delete,migrate_extract_parent,migrate_merge,migrate_reclass,migrate_rename,migrate_reparent,migrate_retype,migrate_split,migrate_undo,organization_clear,pick_list_update,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_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,table_agent_writable_set,table_archive,table_archive_deliberately,table_restore,table_row_defaults,table_row_defaults_apply,table_row_defaults_set,table_row_label,table_row_label_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_host_run,work_approval_host_run_done,work_approval_read,work_approval_request,work_assign,work_record_states,work_set_state\" },\n  { code: \"0A000\", raised_by: \"checklist_step_complete,entity_custom_value_apply,entity_row_write,external_rows,external_source_declare,external_write_through,promote_field,promoted_index_expr,promoted_query_sql,promoted_read,read_records_keyset,rule_eval,rule_filter_node_sql,template_restore,work_assign\" },\n  { code: \"22003\", raised_by: \"context_resolve\" },\n  { code: \"22004\", raised_by: \"_entity_change_file,_entity_custom_fields_guard,_io_outbox_claim,_org_admin_table_gate,_portal_config_judge,_record_restore_one,_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,base_copy_finish,base_move,booking_declare,capture_submit,checklist_declare,context_resolve,context_template_define,context_type_write,copy_table_extras,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,entity_row_write,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_response_update,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,subscription_declare,table_agent_writable_set,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_host_run,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,_automation_advance,_automation_cond_norm,_automation_step,_booking_availability,_ctx_reference_value_holds,_ctx_store_scope,_ctx_table_template_field_holds,_ctx_tree_part,_decorations_check,_entity_change_file,_entity_custom_fields_guard,_form_flow_judge,_form_look_judge,_fx_date,_fx_datetime_parse,_fx_dl,_fx_ext,_fx_listop,_fx_num,_fx_recprop,_fx_regex,_fx_unit,_fx_unit_norm,_fxp_level,_fxp_resolve,_fxp_tokens,_nfx_arglist,_nfx_bin,_nfx_call,_nfx_expr,_nfx_primary,_nfx_tokens,_nfx_unary,_portal_config_judge,_rule_eval_seated,_schedules_stand_down,_stamp_check,_table_dimensions_check,_take_op_id,_template_bind,_template_install_core,_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,archive_guard_decide,archive_hold_answer,automation_test,base_activity,base_move,booking_busy_set,booking_declare,booking_sms_consent,button_press,containment_parent,context_scope_archive,context_scope_write,context_scopes,context_template_define,context_type_archive,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_data_source,enrich_declare,enrich_land,enrich_normalize,enrich_pin,entity_back_links,entity_custom_value_apply,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_access_set,field_declare_many,field_duplicate,field_history,field_notify_on_assign,field_update,filter_list_op,find_duplicates,form_declare,form_draft_save,form_response_update,form_set_password,form_visit,formula_eval,formula_history,formula_parse,formula_preview,formula_translate_notion,grid_layout_check,hub_changed_by,hub_changed_by_many,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,my_levels_across,organization_clear,page_size,pick_list_create,pick_list_update,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_keyset,read_records_page,record_aggregate_as_of,record_change_many,record_drill,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,relation_reverse_field,relation_reverse_set,relative_window_for_reader,relative_window_resolve,reverse_links_many_fields,row_template_declare,rule_eval,rule_filter_node_sql,rule_members,rule_members_visible,rule_sql_op,scope_table_provision,set_table_confidential,set_table_organization,share_grant,share_lane_set,subscription_declare,table_access_setup_set,table_archive_deliberately,table_copy_sync,table_create,table_ensure,table_find,table_find_many,table_from_example,table_move,table_row_defaults_set,table_row_label_set,table_rules,table_share_outside_grant,table_sync,table_sync_cell,table_sync_settings_set,table_template_declare,table_transfer_owner,table_webhook_declare,template_declare,template_from_tables,template_install_claim,template_install_note,template_upgrade,templates,view_declare,view_designate,view_keys_check,view_look_set,view_record_order_set,visibility_as_of,where_lists_live,where_tables_live,work_approval_host_run,work_approval_request,work_decide_many,work_inbox,work_list,work_slot_hold\" },\n  { code: \"23502\", raised_by: \"synced_source_save\" },\n  { code: \"23503\", raised_by: \"_action_check,_automation_advance,_automation_flip,_automation_step,_automation_time_item,_automation_view_rule,_booking_availability,_checklist_instantiate,_containment_guard,_ctx_store_value,_decorations_check,_display_spec_for,_field_document_for,_field_type_parity_guard,_form_flow_judge,_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,automation_declare,automation_revision_restore,automation_revisions,automation_runs,automation_test,automations,autonumber_backfill,booking_busy_set,booking_cancel,booking_confirm,booking_declare,booking_hold,booking_reschedule,booking_sms_consent,button_press,capture_publish,checklist_declare,checklist_steps_table,comment_write,dashboard_declare,delete_rule,doc_sign,doc_template_save,enrich_declare,enrich_due,enrich_land,field_make_automatic,field_notify_on_assign,field_update,form_declare,form_draft_save,form_response_update,form_results,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,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: \"_booking_seat_take,_ctx_store_item,_ctx_store_scope,_ctx_store_type,_portal_config_judge,_restore_guard_one,_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,table_share_outside_resend,work_approval_decide,work_slot_hold\" },\n  { code: \"23514\", raised_by: \"_checklist_instantiate,_checklist_step_guard,_containment_guard,_ctx_scope_parent_holds,_ctx_store_item,_ctx_table_template_field_holds,_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_restore_one,_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_make_automatic,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_reparent,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,status_groups_keyed,status_groups_of,table_access_setup_set,table_from_example,table_restore,template_upgrade,validate_value_envelope,validate_values,whole_value_complete,work_set_state,work_slots_declare,work_take_assignment,work_template_instantiate\" },\n  { code: \"42501\", raised_by: \"_agent_change_gate,_computed_door_org,_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,_not_a_member_refusal,_org_admin_table_gate,_portal_config_judge,_portal_principal_here,_read_record_with,_rule_definition_write,_share_write_person,_stamp_token,_store_door,_table_dimensions_infer,_table_duplicate_step,_table_shape_guard,_template_bind,_template_call,_template_install_core,_value_envelope,_withdraw_approvals_for_batch,_workdoors_approval_guard,admin_all_tables,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_may_know_table,assert_organization_admin,assert_scope_door,assert_store_door,automation_app_watch,automation_claim_pending,automation_note,automation_resume,automation_step_mark,automation_webhook_receive,base_copy_finish,base_move,base_move_access_kept,base_move_remove_access,booking_confirm,booking_declare,booking_hold,capture_submit,checklist_run,comment_write,computed_refresh,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,copy_table_extras,count_records_archived,dashboard_target_field_assert,doc_sign,enrich_declare,enrich_due,enrich_land,enrich_normalize,entity_custom_value_apply,entity_field_declare,entity_field_retire,entity_field_update,entity_row_propose,entity_row_write,entity_value_write,external_write_through,field_access_set,field_restore,field_update,form_declare,form_draft_save,form_public_asks,form_response_update,form_set_password,form_submit,formula_history,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,my_levels_across,organization_clear,organization_contents,pick_list_get,pick_list_update,portal_declare,portal_form,portal_form_submit,portal_invitation,portal_invite,portal_invite_accept,portal_principal_bind,portal_self_signup,promote_table,protected_matches,query_visibility_parity,read_record,read_records,read_records_archived,read_records_by_ids,read_records_keyset,read_records_matching,read_records_page,record_delete,record_follow_set,record_row_controls,record_table,record_write_graph,relation_halves_disagreements,relation_halves_repair,resolve_context,reverse_links_many,scope_table_provision,share_grant,share_lane_set,space_templates,subscription_mute,subscription_preview,table_access_setup_set,table_agent_writable_set,table_archive_deliberately,table_copies_in_progress,table_copy_sync,table_duplicate,table_duplicate_continue,table_kind_facts,table_level_facts,table_move,table_row_defaults_apply,table_row_defaults_set,table_row_label_set,table_share_outside_accept,table_share_outside_grant,table_share_outside_invite,table_share_outside_resend,table_sync,table_sync_cell,table_templates,table_transfer_owner,table_webhook_declare,template_declare,template_from_tables,template_instances,template_restore,template_upgrade,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_host_run,work_approval_host_run_done,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,comment_counts,data_home_changed_by,form_draft_save,hub_changed_by,hub_changed_by_many,pipeline_move_many,read_records_page,record_change_many,record_headers,relation_names_match,reverse_links_many,table_copy_sync,table_decorate,table_from_example,table_map_fields,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,_template_install_core,base_move,entity_field_protect_arman_explicitly_approved,inbox_clear,inbox_snooze,io_outbox_release,io_outbox_subscribe,table_duplicate,table_ensure,table_move,template_restore,template_upgrade,work_approval_decide,work_approval_host_run_done,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: \"MXPV1\", raised_by: \"field_retype_preview\" },\n  { code: \"P0001\", raised_by: \"_guest_record_ceiling,action_run,context_scope_write\" },\n  { code: \"P0002\", raised_by: \"_template_install_core,inbox_clear,inbox_snooze,publish_bind,template_archive,template_install_claim,template_install_note,template_keep,template_restore,template_uninstall,template_upgrade,whole_value_complete\" },\n  { code: \"P0R01\", raised_by: \"template_upgrade\" },\n  { code: \"PT409\", raised_by: \"entity_row_write,has_visibility_at,record_change_many,record_update,record_upsert,record_write_graph_superseding,table_move,whole_value_complete\" },\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  \"access_shadow_log\",\n  \"access_version\",\n  \"access_version_event\",\n  \"account_addon\",\n  \"account_closure\",\n  \"account_facts\",\n  \"acquisition_block\",\n  \"activity\",\n  \"admin_audit_log\",\n  \"admin_email_log\",\n  \"admin_markdown_sample\",\n  \"admin_user\",\n  \"admin_user_owned_resources_cache\",\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_block\",\n  \"agent_prompt_block_variant\",\n  \"agent_prompt_remediation\",\n  \"agent_required_flag_change\",\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_test_result\",\n  \"agent_test_run\",\n  \"agent_usage\",\n  \"agent_user_kv\",\n  \"ai_api\",\n  \"ai_calls\",\n  \"ai_device_model_file\",\n  \"ai_device_model_root\",\n  \"ai_endpoint\",\n  \"ai_media_generation_cache\",\n  \"ai_model\",\n  \"ai_model_alias\",\n  \"ai_model_artifact\",\n  \"ai_model_candidate\",\n  \"ai_model_presentation\",\n  \"ai_model_upstream\",\n  \"ai_model_variant\",\n  \"ai_model_verification_run\",\n  \"ai_model_want\",\n  \"ai_offering\",\n  \"ai_person_model_want\",\n  \"ai_provider\",\n  \"ai_request_latency\",\n  \"ai_runtime\",\n  \"ai_runtime_build\",\n  \"ai_runtime_compat\",\n  \"ai_setting\",\n  \"ai_setting_profile\",\n  \"ai_translation_cell\",\n  \"ai_usage_execution_facts\",\n  \"ai_usage_executions\",\n  \"ai_usage_hourly\",\n  \"ai_usage_hourly_watermark\",\n  \"analysis_result\",\n  \"anon_form\",\n  \"anon_form_password\",\n  \"anon_form_visit\",\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_hourly\",\n  \"app_log_hourly_watermark\",\n  \"app_log_lines\",\n  \"app_log_muted_pattern\",\n  \"app_log_norm_exception\",\n  \"app_log_requests_hourly\",\n  \"app_rate_limit\",\n  \"app_setting\",\n  \"app_sync_status\",\n  \"applet_visitor_binding\",\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  \"attention_audience_rule\",\n  \"attention_audit\",\n  \"attention_item_state\",\n  \"attention_showing\",\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  \"automation_delivery\",\n  \"automation_fired\",\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_ci_package_build\",\n  \"billing_connect_account\",\n  \"billing_coupon\",\n  \"billing_coupon_redemption\",\n  \"billing_customer\",\n  \"billing_external_call_vendor\",\n  \"billing_free_network_counter\",\n  \"billing_free_period_grant\",\n  \"billing_free_use_counter\",\n  \"billing_hard_cost_reconciliation\",\n  \"billing_held_run\",\n  \"billing_org_payment_account\",\n  \"billing_payment\",\n  \"billing_payment_ask\",\n  \"billing_plan\",\n  \"billing_plan_limit\",\n  \"billing_price\",\n  \"billing_product\",\n  \"billing_provider_balance_snapshot\",\n  \"billing_spend_alarm\",\n  \"billing_spend_alarm_occurrence\",\n  \"billing_spend_approval\",\n  \"billing_spend_guardrail\",\n  \"billing_spend_hold\",\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_item\",\n  \"change_job\",\n  \"change_job_row\",\n  \"change_plan\",\n  \"change_type_default\",\n  \"change_work\",\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  \"collab_checkpoint\",\n  \"collab_op\",\n  \"collab_room\",\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  \"computed_org_mark\",\n  \"computed_reader_cols\",\n  \"computed_reader_judgement\",\n  \"config_manifest\",\n  \"config_read_bucket\",\n  \"contact_medium\",\n  \"contact_submission\",\n  \"content_certification\",\n  \"content_ir_converter_definition\",\n  \"content_ir_converter_run\",\n  \"content_ir_kind\",\n  \"content_ir_kind_component\",\n  \"content_ir_kind_component_incident\",\n  \"content_ir_kind_component_layer\",\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_ir_render_inspection\",\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_origin\",\n  \"custom_agent_table_trust\",\n  \"custom_agg_digest_checked\",\n  \"custom_anon_form_draft\",\n  \"custom_base\",\n  \"custom_base_snapshot\",\n  \"custom_entity_definition\",\n  \"custom_field_definition\",\n  \"custom_field_target\",\n  \"custom_inbox_item_state\",\n  \"custom_io_outbox_consumer\",\n  \"custom_io_outbox_consumption\",\n  \"custom_portal\",\n  \"custom_portal_principal\",\n  \"custom_portal_table\",\n  \"custom_record\",\n  \"custom_share_tails_mine_repair\",\n  \"custom_synced_source\",\n  \"custom_template\",\n  \"custom_template_install\",\n  \"custom_whole_value_parked\",\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_request_values\",\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  \"desktop_app_account\",\n  \"desktop_app_instance\",\n  \"desktop_app_profile\",\n  \"dev_login_audit\",\n  \"device_handoff\",\n  \"dict_entry\",\n  \"dict_provider_publication\",\n  \"dict_setting\",\n  \"dm_conversation\",\n  \"dm_message\",\n  \"dm_participant\",\n  \"dm_session_member\",\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_draft\",\n  \"esign_envelope_event\",\n  \"esign_envelope_external_ref\",\n  \"esign_envelope_signer\",\n  \"esign_provider\",\n  \"esign_provider_binding\",\n  \"esign_saved_signature\",\n  \"esign_signing_key\",\n  \"esign_template\",\n  \"execution_event_cursor\",\n  \"extension_auth_code\",\n  \"external_api_reservation\",\n  \"external_conversation\",\n  \"external_delivery_event\",\n  \"external_inbox\",\n  \"external_link\",\n  \"external_message\",\n  \"external_provider_receipt\",\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_template\",\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_goal\",\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_review\",\n  \"hr_review_cycle\",\n  \"hr_review_peer_nomination\",\n  \"hr_review_response\",\n  \"hr_review_template\",\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_access_setup\",\n  \"iam_api_key\",\n  \"iam_emergency_door_request\",\n  \"iam_oauth_app\",\n  \"iam_org_availability_key\",\n  \"iam_org_domain\",\n  \"iam_org_domain_route\",\n  \"iam_publish_binding\",\n  \"iam_publisher_verification\",\n  \"iam_read_lane_v2_rollout\",\n  \"iam_record_seat_change\",\n  \"iam_sign_in_event\",\n  \"iam_world_namespace\",\n  \"iam_world_publish_admission\",\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_proposal\",\n  \"mandate_readiness_verdict\",\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_connection\",\n  \"meet_invitee\",\n  \"meet_meeting\",\n  \"meet_note\",\n  \"meet_occurrence_override\",\n  \"meet_participant\",\n  \"meet_recording\",\n  \"meet_session\",\n  \"meet_transcript_segment\",\n  \"membership\",\n  \"membership_grant\",\n  \"memory_trial\",\n  \"memory_trial_step\",\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_auth_lock_watchdog_log\",\n  \"ops_check_item\",\n  \"ops_check_run\",\n  \"ops_db_host_sample\",\n  \"ops_issue_class\",\n  \"ops_issue_event\",\n  \"ops_perf_client_event\",\n  \"ops_perf_sample\",\n  \"ops_perf_statement_snapshot\",\n  \"ops_proof_check\",\n  \"ops_proof_run\",\n  \"ops_proof_scenario\",\n  \"ops_source_read_cache\",\n  \"ops_test_replay_cache\",\n  \"org_admin_audit\",\n  \"org_change_policy\",\n  \"org_chart_publication\",\n  \"org_context_ledger\",\n  \"org_industries\",\n  \"org_member_control\",\n  \"org_module_config\",\n  \"org_move_txn\",\n  \"org_plan\",\n  \"org_sweep_list\",\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  \"page_vitals\",\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  \"personal_data_column\",\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_class_approval_by_org_admin\",\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_hidden_item\",\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  \"presentation\",\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_snapshot\",\n  \"provision_spec\",\n  \"provision_spec_grandfather\",\n  \"provision_vocabulary\",\n  \"provlock_recall_visits_all8u5\",\n  \"public_compat_wrapper\",\n  \"public_placement_baseline\",\n  \"public_placement_census\",\n  \"public_placement_domain\",\n  \"public_restore_permit\",\n  \"purpose\",\n  \"quiz_session\",\n  \"rag_ingest_run\",\n  \"rag_library_audit_log\",\n  \"rate_limit_buckets\",\n  \"reachability_pending\",\n  \"read_mask_kept\",\n  \"recompute_queue\",\n  \"record\",\n  \"record_alias\",\n  \"record_computed\",\n  \"record_follow\",\n  \"redaction_mapping\",\n  \"relationship_rule\",\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  \"run_approval\",\n  \"run_approval_event\",\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  \"scheduler_automation_run_subject\",\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  \"scraper_comparison_run\",\n  \"scraper_data_fetch_job\",\n  \"scraper_data_fetch_job_row\",\n  \"scraper_data_source\",\n  \"search_item\",\n  \"seo_ai_capability\",\n  \"seo_ai_visibility_brand_check\",\n  \"seo_ai_visibility_citation\",\n  \"seo_ai_visibility_claim\",\n  \"seo_ai_visibility_design_artifact\",\n  \"seo_ai_visibility_panel\",\n  \"seo_ai_visibility_panel_version\",\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  \"share_link_password\",\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  \"social_account_insight_daily\",\n  \"social_ad\",\n  \"social_captured_post\",\n  \"social_kpi_goal\",\n  \"social_own_post_metric\",\n  \"social_post\",\n  \"social_post_analysis\",\n  \"social_post_comment\",\n  \"social_post_metric_snapshot\",\n  \"social_post_stat\",\n  \"social_post_transcript\",\n  \"social_profile\",\n  \"social_profile_snapshot\",\n  \"social_remix_output\",\n  \"social_swipe_collection\",\n  \"social_tracked_account\",\n  \"social_video_composition_version\",\n  \"social_video_project\",\n  \"social_video_variant\",\n  \"social_watchlist_hit\",\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  \"support_session\",\n  \"support_session_event\",\n  \"surface\",\n  \"system_announcement\",\n  \"system_context_item\",\n  \"system_context_item_org_value\",\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_battle\",\n  \"tool_battle_cell\",\n  \"tool_binding\",\n  \"tool_bundle\",\n  \"tool_call\",\n  \"tool_call_facts\",\n  \"tool_canary_run\",\n  \"tool_catalog_cache\",\n  \"tool_catalog_call\",\n  \"tool_catalog_call_attempt\",\n  \"tool_catalog_call_detail\",\n  \"tool_catalog_endpoint\",\n  \"tool_catalog_entry\",\n  \"tool_catalog_provider\",\n  \"tool_definition_version\",\n  \"tool_executor\",\n  \"tool_feature_scorecard\",\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_decision_pick\",\n  \"ui_surface_action\",\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_acquisition_facts\",\n  \"user_acquisition_facts_stored\",\n  \"user_acquisition_facts_stored_watermark\",\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  \"users_calendar_feed\",\n  \"users_notion_sync_source\",\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_choice\",\n  \"web_brand_exclusion\",\n  \"web_brand_offering\",\n  \"web_brand_persona\",\n  \"web_brand_relation_kind\",\n  \"web_brand_review\",\n  \"web_brand_testimony\",\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_domain_category\",\n  \"web_domain_category_observation\",\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_temp_brand_firmographic\",\n  \"web_temp_brand_presence\",\n  \"web_temp_brand_recognition\",\n  \"web_voice_fingerprint\",\n  \"web_youtube_video\",\n  \"webhook_deliveries\",\n  \"webhook_dispatch_state\",\n  \"webhook_test_receipt\",\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_checkpoint_value\",\n  \"workflow_comparison\",\n  \"workflow_definition_overview\",\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_review_issue\",\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/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 { mapPgError } from \"../core/pgError\";\nimport { TRANSIENT_CODES, backoffDelay, isStoreAwayError, isTransientStoreError } from \"../core/transient\";\nimport {\n  automationSpecs,\n  bookingArgs,\n  bookingColumnsProblem,\n  checklistSpec,\n  dashboardBlocks,\n  deferredRelations,\n  derivedFieldSpec,\n  buttonFieldSpec,\n  fieldDisplayFormat,\n  formulaFieldSpec,\n  formulaLooksOf,\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 TemplateField, type TemplateFootprint, type TemplateRowAction, type TemplateSpec, type TemplateTable } from \"./types\";\nimport { allTables } from \"./validate\";\nimport { derivedLookOf } from \"../formulaLook\";\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/**\n * The back-link key a relation declares on its target (relationships[].inverseKey), unless the target table\n * already has a column of that key (a hand-listed mirror from before two-way links were declarable).\n */\nexport function backLinkKeyOf(spec: Pick<TemplateSpec, \"relationships\" | \"tables\" | \"sharedBlocks\">, table: string, field: string): string | undefined {\n  const rel = (spec.relationships ?? []).find((r) => r.fromTable === table && r.fromField === field);\n  const key = rel?.inverseKey?.trim();\n  if (!key) return undefined;\n  const target = allTables(spec as TemplateSpec).find((t) => t.token === rel!.toTable);\n  return target && target.fields.some((f) => f.key === key) ? undefined : key;\n}\n\ntype Look = { id: string; options?: Record<string, unknown> };\n\n/**\n * THE NUMBER FORMAT EVERY INFERRED COLUMN OF A TEMPLATE IS INSTALLED WITH (FORMULA-FORMAT + ROLLUP-FORMAT), keyed\n * \"<table token>.<field key>\": formulas (`formulaLooksOf`) and rollups / lookups (`derivedLookOf`, the one inference in\n * formulaLook.ts) worked out together until nothing changes, so lookup -> formula -> rollup chains settle. A look the\n * template declares on a column wins and is never listed.\n */\nexport function templateLooksOf(spec: Pick<TemplateSpec, \"relationships\" | \"tables\" | \"sharedBlocks\">): Map<string, Look> {\n  const tables = allTables(spec);\n  const looks = new Map<string, Look>();\n  const stored = (t: TemplateTable, f: TemplateField): Record<string, unknown> => {\n    const df = fieldDisplayFormat(f) ?? looks.get(`${t.token}.${f.key}`);\n    return {\n      key: f.key,\n      label: f.label,\n      parity_type: f.parityType,\n      ...(f.unit ? { unit: f.unit } : {}),\n      config: { via: f.via, of: f.pick, pick: f.pick, agg: f.agg },\n      ...(df ? { display_format: df } : {}),\n    };\n  };\n  for (let pass = 0; pass < 4; pass++) {\n    let changed = false;\n    for (const t of tables) {\n      const own = new Map([...looks].filter(([k]) => k.startsWith(`${t.token}.`)).map(([k, v]) => [k.slice(t.token.length + 1), v]));\n      for (const [key, look] of formulaLooksOf(t, own)) {\n        if (looks.has(`${t.token}.${key}`)) continue;\n        looks.set(`${t.token}.${key}`, look);\n        changed = true;\n      }\n      for (const f of t.fields.filter((x) => DERIVED.has(x.parityType) && !fieldDisplayFormat(x) && !looks.has(`${t.token}.${x.key}`))) {\n        const look = derivedLookOf(stored(t, f), (via) => {\n          const link = t.fields.find((x) => x.key === via && x.parityType === \"relation\" && x.relationTarget);\n          const fars = link\n            ? tables.filter((u) => u.token === link.relationTarget)\n            : tables.filter((u) =>\n                u.fields.some(\n                  (x) =>\n                    x.parityType === \"relation\" &&\n                    x.relationTarget === t.token &&\n                    (x.key === via || (spec.relationships ?? []).some((r) => r.fromTable === u.token && r.fromField === x.key && r.inverseKey?.trim() === via)),\n                ),\n              );\n          return fars.map((u) => u.fields.map((x) => stored(u, x)));\n        });\n        if (!look) continue;\n        looks.set(`${t.token}.${f.key}`, look as Look);\n        changed = true;\n      }\n    }\n    if (!changed) break;\n  }\n  return looks;\n}\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  \"anon_publish\",\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  \"automation_declare\",\n  \"row_template_declare\",\n  \"automation_set_enabled\",\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  /** The mandate this template presents instead of an agent copy; recorded on the install (custom.template_install.mandate_key). */\n  mandateKey?: string;\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 unless the caller found it empty (`seedRows`).\n  // A new table's value that points at one of its sample rows lands when the row is seeded or mapped to an\n  // existing row (`rowIds`); otherwise that one value is left empty - the row itself is always kept, and a\n  // field that loses a value stops being required so the row is not refused.\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 resolves = (target: string, v: unknown): boolean => {\n    const b = bound.get(target);\n    return !b || !!b.seedRows || (typeof v === \"string\" && !!b.rowIds?.[v]);\n  };\n  const tables = allTables(spec).map((t) => {\n    if (bound.has(t.token)) return bound.get(t.token)!.seedRows ? t : { ...t, rows: [] };\n    const toBound = t.fields.filter((f) => f.parityType === \"relation\" && f.relationTarget && bound.has(f.relationTarget));\n    if (!toBound.length) return t;\n    const lost = new Set<string>();\n    const rows = t.rows.map((r) => {\n      const values: Record<string, unknown> = { ...(r.values ?? {}) };\n      for (const f of toBound) {\n        const v = values[f.key];\n        if (v === null || v === undefined) continue;\n        const keep = Array.isArray(v) ? v.filter((x) => resolves(f.relationTarget!, x)) : resolves(f.relationTarget!, v) ? v : null;\n        if (Array.isArray(keep) ? keep.length < (v as unknown[]).length : keep === null) lost.add(f.key);\n        if (keep === null || (Array.isArray(keep) && !keep.length)) delete values[f.key];\n        else values[f.key] = keep;\n      }\n      return { ...r, values };\n    });\n    return { ...t, rows, fields: t.fields.map((f) => (lost.has(f.key) && f.required ? { ...f, required: false } : f)) };\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!), backLinkKeyOf(spec, t.token, f.key)) },\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  // A bound table that did not seed answers a link with the existing row it was mapped to.\n  for (const [token, b] of bound) if (!b.seedRows) for (const [key, id] of Object.entries(b.rowIds ?? {})) rowIds.set(`${token}.${key}`, id);\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, each declared with the number format of the column it reads (ROLLUP-FORMAT).\n  const allLooks = templateLooksOf(spec);\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, allLooks.get(`${t.token}.${f.key}`)) },\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, allLooks.get(`${t.token}.${f.key}`)) },\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    // A date reminder names its date Field by id.\n    ...spec.extras.filter((e) => e.kind === \"automation\" && e.when.field).map((e) => (e as { when: { table: string } }).when.table),\n    // A button's link fills {{field}} from the row by field id.\n    ...tables.filter((t) => t.fields.some((f) => f.parityType === \"button\" && f.button?.do === \"open_url\" && /\\{\\{/.test(f.button.url))).map((t) => t.token),\n    ...spec.views.filter((v) => (v.anyOf && Object.keys(v.anyOf).length) || (v.within && Object.keys(v.within).length) || v.me?.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  // 5b — row templates (TEMPLATE-GAPS a): preset values and the page body a new row starts from.\n  for (const t of tables) {\n    (t.rowTemplates ?? []).forEach((rt, i) => {\n      steps.push({\n        label: `row_templates.${t.token}.${i + 1}`,\n        door: \"row_template_declare\",\n        args: {\n          p_organization_id: \"${org}\",\n          p_table_id: tableRef(t.token),\n          p_spec: { name: rt.name, values: rt.values ?? {}, ...(rt.body ? { body: rt.body } : {}), ...(rt.default ? { default: true } : {}) },\n        },\n        save: { [`row_templates.${t.token}.${i + 1}`]: [] },\n        made: [{ kind: \"view\", ref: `row_templates.${t.token}.${i + 1}`, title: rt.name, table: `tables.${t.token}` }],\n      });\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    // A FORM THE BOX BUILDS WORKS THE MOMENT IT IS BUILT (lane DESCRIBE-INSTALL, 2026-10-08). form_declare\n    // makes a DRAFT whose link does not answer, so a form a template installs is opened in the same\n    // install unless the template says `publishForms: false`. The installer is admin on the table she\n    // just made, which is the rung custom.anon_publish asks.\n    if (spec.publishForms !== false) {\n      steps.push({\n        label: `forms.${f.token}.publish`,\n        door: \"anon_publish\",\n        args: { p_organization_id: \"${org}\", p_form_id: ref(`forms.${f.token}`), p_published: true },\n      });\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        // Lives on its table (custom.record data.automations): uninstall archives the table, and it goes with it.\n        // AT-TPLAUTO: one spec, except `assigned` (two, as custom.field_notify_on_assign declares them): the first keeps the\n        // token's label, the second is `<token>.new`.\n        automationSpecs(e, fieldRefs(e.when.table)).forEach((spec, i) => {\n          const label = i === 0 ? `automations.${e.token}` : `automations.${e.token}.new`;\n          steps.push({\n            label,\n            door: \"automation_declare\",\n            args: { p_organization_id: \"${org}\", p_table_id: tableRef(e.when.table), p_spec: spec, p_automation_id: null },\n            save: { [label]: [\"automation_id\"] },\n          });\n          // AT-AIBASE: a SUGGESTED automation (describe/starter.ts, `startsOff`) is saved switched off — no blind\n          // automations; the person switches on the ones they want. One the template wrote itself installs as written.\n          if ((e as { startsOff?: unknown }).startsOff === true) {\n            steps.push({\n              label: `${label}.off`,\n              door: \"automation_set_enabled\",\n              args: { p_organization_id: \"${org}\", p_automation_id: ref(label), p_enabled: false },\n            });\n          }\n        });\n        break;\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      // TEMPLATE-GAPS (e): each action's id by its token, for a button that runs it.\n      saveEach: { array: [], key: [\"name\"], value: [\"id\"], prefix: `actions_by_name.${token}.` },\n    });\n  }\n\n  // TEMPLATE-GAPS (e): button columns, last — they point at row actions and automations made above.\n  for (const t of tables) {\n    for (const f of t.fields.filter((x) => x.parityType === \"button\" && !has(t.token, x.key))) {\n      const b = f.button;\n      let spec = buttonFieldSpec(t.token, f);\n      if (b?.do === \"add_row\" && b.template) {\n        // The row template's saved id, by its index on the target table (step 5b saves row_templates.<table>.<n>).\n        const target = b.table ?? t.token;\n        const n = (tables.find((x) => x.token === target)?.rowTemplates ?? []).findIndex((rt) => rt.name === b.template) + 1;\n        spec = JSON.parse(JSON.stringify(spec).replace(`\\${ref:row_template_by_name.${target}.${b.template}}`, `\\${ref:row_templates.${target}.${n}}`));\n      }\n      if (b?.do === \"run_action\") {\n        const action = (actionsByTable.get(t.token) ?? []).find((a) => a.token === b.action);\n        spec = JSON.parse(JSON.stringify(spec).replace(`\\${ref:actions.${t.token}.${b.action}}`, `\\${ref:actions_by_name.${t.token}.${action?.name ?? b.action}}`));\n      }\n      steps.push({\n        label: `buttons.${t.token}.${f.key}`,\n        door: \"field_declare\",\n        args: { p_organization_id: \"${org}\", p_table_id: tableRef(t.token), p_spec: spec },\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  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    ...(spec.mandateKey ? { mandateKey: spec.mandateKey } : {}),\n    // A template that presents a mandate copies no agent.\n    ...(agent?.platformAgent && !spec.mandateKey\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_install_fresh\" | \"template_uninstall\" | \"template_restore\";\n\n/**\n * TEMPLATE-FRESH (2026-10-18): what a fresh copy of a template says about itself. A fresh copy\n * (custom.template_install_fresh) is a NEW independent install every time it is used: its own tables, named\n * \"<Table> · <title>\", and everything wired to them only. The default install (custom.template_install) has none.\n */\nexport interface TemplateInstance {\n  /** 2, 3, …; the default install is 1. Never reused. */\n  no: number;\n  title: string;\n  mode: \"fresh\";\n  /** What the copy appends to every table name: \" · <title>\". */\n  suffix: string;\n}\n\n/** The name a fresh copy gives a template table: \"<Table> · <title>\" (the store's custom._template_instance_args). */\nexport function instanceTableName(name: string, title: string | null | undefined): string {\n  return title ? `${name} · ${title}` : name;\n}\n\n/** One row of custom.template_instances: every install of one template in one organization. */\nexport interface TemplateInstanceRow {\n  install_id: string;\n  instance_no: number;\n  mode: \"default\" | \"fresh\";\n  title: string | null;\n  state: NonNullable<TemplateDoorAnswer[\"state\"]>;\n  version: number;\n  template_id: string;\n  started_at: string;\n  finished_at: string | null;\n  /** The first page the install recorded (template_install_note kind 'page'); null for a copy that recorded none. */\n  root_page_id: string | null;\n  /** Every page the install recorded, oldest first; [] for a copy that recorded none. */\n  pages: Array<{ id: string; title: string | null }>;\n  tables: Array<{ ref: string; id: string | null; title: string | null }>;\n  newer_version: number | null;\n  /** Hand to `upgradeTemplateInstall(source, org, upgrade.install_id, upgrade.template_id)`; one copy at a time. */\n  upgrade: TemplateUpgradeHint | null;\n}\n\n/** Every install (default + fresh copies) of one catalogue id in one organization, oldest first. */\nexport async function listTemplateInstances(\n  source: RecordsDataSource,\n  organizationId: string,\n  catalogueId: string,\n): Promise<{ ok: boolean; instances: TemplateInstanceRow[]; error?: { code: string | null; message: string } }> {\n  const { data, error } = await source.rpc(\n    \"template_instances\",\n    { p_organization_id: organizationId, p_catalogue_id: catalogueId },\n    { schema: \"custom\" },\n  );\n  if (error) return { ok: false, instances: [], error: { code: error.code ?? null, message: error.message } };\n  return { ok: true, instances: (Array.isArray(data) ? data : []) as TemplateInstanceRow[] };\n}\n\n/** The install that made a page (custom.template_instance_of_page): the row of the install whose recorded pages include it. */\nexport interface TemplateInstanceOfPage {\n  id: string;\n  catalogue_id: string;\n  status: NonNullable<TemplateDoorAnswer[\"state\"]>;\n  /** The first page the install recorded: the page a \"made from a template\" banner points back to. */\n  root_page_id: string | null;\n  template_version: number;\n}\n\n/**\n * Which template install made this page, or null: the page is not one an install recorded, the caller may not read it, or it is\n * not in that organization (all three answer the same, so nothing leaks). The door checks read access on the page itself.\n */\nexport async function templateInstanceOfPage(\n  source: RecordsDataSource,\n  organizationId: string,\n  pageId: string,\n): Promise<{ ok: boolean; instance: TemplateInstanceOfPage | null; error?: { code: string | null; message: string } }> {\n  const { data, error } = await source.rpc(\n    \"template_instance_of_page\",\n    { p_organization_id: organizationId, p_page_id: pageId },\n    { schema: \"custom\" },\n  );\n  if (error) return { ok: false, instance: null, error: { code: error.code ?? null, message: error.message } };\n  return { ok: true, instance: data && typeof data === \"object\" && !Array.isArray(data) ? (data as TemplateInstanceOfPage) : null };\n}\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  /** The mandate the template presents (spec.mandateKey), recorded on the install; null for a template with an agent copy. */\n  mandate_key?: string | 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  /** template_install's `already` answer, when the template is newer than the install. */\n  newer_version?: number | null;\n  /** TEMPLATE-FRESH: present only on a fresh copy (custom.template_install_fresh). */\n  instance?: TemplateInstance | null;\n  /** What `upgradeTemplateInstall` needs to bring the install up to `newer_version` (null when current). */\n  upgrade?: TemplateUpgradeHint | null;\n  [key: string]: unknown;\n}\n\n/** template_install's hint: call custom.template_upgrade with these ids. */\nexport interface TemplateUpgradeHint {\n  door: \"template_upgrade\";\n  install_id: string;\n  template_id: string;\n  from_version: number;\n  to_version: number;\n}\n\n/** What custom.template_upgrade answers: the install answer plus what this upgrade did. */\nexport interface TemplateUpgradeAnswer extends TemplateDoorAnswer {\n  /** True when this call changed the install; false on `already` (current) or a refusal. */\n  upgraded?: boolean;\n  /** The install's version now. */\n  version?: number;\n  from_version?: number;\n  to_version?: number;\n  /**\n   * Per kind: `tables`, `fields`, `views`, `dashboards`… made; `rows` seeded on new tables;\n   * `fields_converted` (choice → link), `links`, `targets_created`, `fields_retired`; `kept` steps.\n   */\n  counts?: Record<string, number>;\n  /** Anything the upgrade left as it was, with the reason. */\n  skipped?: Array<{ kind: string; ref: string; reason: string }>;\n}\n\nexport interface TemplateUpgradeRun {\n  ok: boolean;\n  answer: TemplateUpgradeAnswer | null;\n  error?: { code: string | null; message: string; hint: string | null };\n  calls: number;\n}\n\n/** The upgrade hint an install answer carries, or null when the install is current. */\nexport function templateUpgradeHint(answer: TemplateDoorAnswer | null | undefined): TemplateUpgradeHint | null {\n  const u = answer?.upgrade;\n  return u && typeof u === \"object\" && typeof u.install_id === \"string\" && typeof u.template_id === \"string\" ? u : null;\n}\n\n/**\n * Apply a newer version of a template to an existing install (custom.template_upgrade): new tables,\n * fields, views and seed rows of new tables are made; a choice column that became a link is converted\n * by title; a column the new version drops is retired, never dropped. One transaction per call, so a\n * lock wait or a timeout is retried. Never throws: a refusal is `ok: false` with `answer.refusal`.\n * A host that copies agents runs its host steps on `answer` after, exactly as after an install.\n */\nexport async function upgradeTemplateInstall(\n  source: RecordsDataSource,\n  organizationId: string,\n  installId: string,\n  templateId: string,\n  options: BusyRetryOptions & { maxCalls?: number } = {},\n): Promise<TemplateUpgradeRun> {\n  const max = options.maxCalls ?? 3;\n  const busy = busyRetry(options);\n  let error: TemplateUpgradeRun[\"error\"];\n  let answer: TemplateUpgradeAnswer | null = null;\n  let calls = 0;\n  while (calls < max + busy.retries) {\n    calls++;\n    let data: unknown;\n    let e: { code?: string | null; message: string; hint?: string | null } | null = null;\n    try {\n      ({ data, error: e } = await source.rpc(\n        \"template_upgrade\",\n        { p_organization_id: organizationId, p_install_id: installId, p_template_id: templateId },\n        { schema: \"custom\" },\n      ));\n    } catch (thrown) {\n      e = { code: null, message: thrown instanceof Error ? thrown.message : String(thrown), hint: null };\n    }\n    if (e) {\n      error = { code: e.code ?? null, message: e.message, hint: e.hint ?? null };\n      if (isTransientStoreError(e) && (await busy.wait())) continue;\n      if (isTransientStoreError(e)) return busyRefusal(answer, calls, error);\n      return { ok: false, answer: null, error, calls };\n    }\n    answer = (data ?? null) as TemplateUpgradeAnswer | null;\n    if (!answer) return { ok: false, answer, calls };\n    // A busy refusal (the store's lock wait or deadlock) changed nothing: wait, then the same upgrade again.\n    if (answer.ok === false && isBusy(answer)) {\n      if (await busy.wait()) continue;\n      return busyRefusal(answer, calls);\n    }\n    return { ok: answer.ok !== false, answer, calls };\n  }\n  return answer && isBusy(answer) ? busyRefusal(answer, calls, error) : { ok: false, answer, ...(error ? { error } : {}), calls };\n}\n\n/** TEMPLATE-FRESH-2: the one sentence a person sees when the tables stayed busy through every retry. */\nexport const TEMPLATE_BUSY_MESSAGE = \"The tables were busy; try again in a minute.\";\n\nexport interface BusyRetryOptions {\n  /** Retries after a transient answer (lock wait 55P03, deadlock 40P01, timeout 57014, serialization 40001, PGRST001/PGRST002, 502/503/504, a reset connection). Default 6. */\n  busyRetries?: number;\n  /** Waits between them: 0.5, 1, 2, then 4 s, each with +/-25 % jitter. Tests pass a fake. */\n  sleep?: (ms: number) => Promise<void>;\n  /** The jitter's source (0..1); tests pass a fixed one so the waits are exact. */\n  random?: () => number;\n}\n\nfunction busyRetry(options: BusyRetryOptions) {\n  const retries = Math.max(0, options.busyRetries ?? 6);\n  const sleep = options.sleep ?? ((ms: number) => new Promise<void>((r) => setTimeout(r, ms)));\n  let used = 0;\n  return {\n    retries,\n    /** True after waiting when a retry is left; false when every retry is spent. */\n    async wait(): Promise<boolean> {\n      if (used >= retries) return false;\n      used++;\n      await sleep(backoffDelay(used - 1, options.random));\n      return true;\n    },\n  };\n}\n\nfunction isBusy(answer: TemplateDoorAnswer | null | undefined): boolean {\n  const r = answer?.refusal;\n  if (!r) return false;\n  return r[\"busy\"] === true || (typeof r[\"code\"] === \"string\" && TRANSIENT.has(r[\"code\"] as string));\n}\n\n/** Out of retries on busy tables: a refusal in plain words, never the store's raw lock text. */\nfunction busyRefusal<A extends TemplateDoorAnswer>(\n  answer: A | null,\n  calls: number,\n  error?: { code: string | null; message: string; hint: string | null },\n): { ok: false; answer: A | null; error: { code: string | null; message: string; hint: string | null }; calls: number } {\n  const code = (typeof answer?.refusal?.[\"code\"] === \"string\" ? (answer.refusal[\"code\"] as string) : null) ?? error?.code ?? null;\n  // TEMPLATE-INSTALL-3: when the API itself was away (PGRST002, a 503, a reset connection) the sentence is the shared mapper's, never the raw text.\n  const message = error && isStoreAwayError(error) ? mapPgError({ code: error.code, message: error.message, hint: error.hint }, \"the template\").message : TEMPLATE_BUSY_MESSAGE;\n  const out = answer ? ({ ...answer, ok: false, refusal: { ...(answer.refusal ?? {}), busy: true, code, message } } as A) : null;\n  return { ok: false, answer: out, error: { code, message, hint: null }, calls };\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\n// The retry classification is the records client's one (core/transient.ts): PGRST001/PGRST002, 502/503/504 and a reset connection count with the lock and timeout codes.\nconst TRANSIENT = TRANSIENT_CODES;\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 *\n * TEMPLATE-FRESH: `template_install_fresh` (id = the template id) makes a NEW copy on its first call and\n * continues THAT copy (p_install_id from the first answer) on every later call, so one run is one copy.\n * `options.title` names it (else the store numbers it \"<template name> 2\", \"3\", …).\n */\nexport async function runTemplateDoor(\n  source: RecordsDataSource,\n  door: TemplateFamilyDoor,\n  organizationId: string,\n  id: string,\n  options: BusyRetryOptions & {\n    maxCalls?: number;\n    onCall?: (answer: TemplateDoorAnswer) => void;\n    title?: string | null;\n    installId?: string | null;\n    /** A fresh copy's id when this run minted it (heard BEFORE the first call, so a host can keep it for a refresh). */\n    onInstallId?: (installId: string) => void;\n  } = {},\n): Promise<TemplateDoorRun> {\n  const max = options.maxCalls ?? 40;\n  const busy = busyRetry(options);\n  const key = door === \"template_install\" || door === \"template_install_fresh\" ? \"p_template_id\" : \"p_install_id\";\n  let answer: TemplateDoorAnswer | null = null;\n  let error: TemplateDoorRun[\"error\"];\n  let calls = 0;\n  // TEMPLATE-INSTALL-2: a fresh copy has its id BEFORE the first call (the caller's, else minted here and announced), and every call\n  // sends it, so a retry after a timeout, a refresh or a second press is the same install in the store, never a second copy.\n  let chosen = options.installId ?? null;\n  if (door === \"template_install_fresh\" && !chosen) {\n    chosen = newTemplateInstallId();\n    options.onInstallId?.(chosen);\n  }\n  while (calls < max + busy.retries) {\n    calls++;\n    const args: Record<string, unknown> = { p_organization_id: organizationId, [key]: id };\n    if (door === \"template_install_fresh\") {\n      args[\"p_title\"] = options.title ?? null;\n      args[\"p_install_id\"] = answer?.install_id ?? chosen;\n    }\n    const { data, error: e } = await source.rpc(door, args, { schema: \"custom\" });\n    if (e) {\n      error = { code: e.code ?? null, message: e.message, hint: e.hint ?? null };\n      // A lock wait, deadlock or timeout changed nothing: wait a moment, then the same call resumes from next_step.\n      if (isTransientStoreError(e) && (await busy.wait())) continue;\n      if (isTransientStoreError(e)) return busyRefusal(answer, calls, error);\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    // TEMPLATE-FRESH-2: the store answers busy tables as `installing` + refusal.busy (older bodies: `refused` + 55P03).\n    if (isBusy(answer) && (answer.state === \"installing\" || answer.state === \"refused\")) {\n      if (await busy.wait()) continue;\n      return busyRefusal(answer, calls);\n    }\n    if (answer.state === \"refused\") return { ok: false, answer, calls };\n    // TEMPLATE-INSTALL-2: an uninstall or restore that names a refusal (a table pass that moved nothing) ends here with it, never re-asked.\n    if ((door === \"template_uninstall\" || door === \"template_restore\") && answer.refusal && !isBusy(answer)) return { ok: false, answer, calls };\n  }\n  if (answer && isBusy(answer)) return busyRefusal(answer, calls, error);\n  return { ok: false, answer, ...(error ? { error } : {}), calls };\n}\n\n/**\n * TEMPLATE-INSTALL-2: a new id for one copy of a template. The page mints it BEFORE the first call and sends it on every call, a retry\n * or a refresh included, so `template_install_fresh` answers the same install however many times it is asked (never a second copy).\n */\nexport function newTemplateInstallId(): string {\n  const c = (globalThis as { crypto?: { randomUUID?: () => string; getRandomValues?: (a: Uint8Array) => Uint8Array } }).crypto;\n  if (c && typeof c.randomUUID === \"function\") return c.randomUUID();\n  const b = new Uint8Array(16);\n  if (c && typeof c.getRandomValues === \"function\") c.getRandomValues(b);\n  else for (let i = 0; i < 16; i++) b[i] = Math.floor(Math.random() * 256);\n  b[6] = (b[6]! & 0x0f) | 0x40;\n  b[8] = (b[8]! & 0x3f) | 0x80;\n  const h = Array.from(b, (x) => x.toString(16).padStart(2, \"0\")).join(\"\");\n  return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20)}`;\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 normalizes 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 recognize 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, instanceTableName, type TemplateInstallPlan } from \"../templates/plan\";\nimport { resolveDateToken } from \"../templates/validate\";\nimport type { TemplateSpec } from \"../templates/types\";\nimport { choiceSlug } from \"../choice\";\nimport { derivedLookOf, formulaLookOf } from \"../formulaLook\";\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  /** True once an anon_publish step opened it (a declared form is a draft until then). */\n  published?: boolean;\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  /** TEMPLATE-GAPS R3b: row templates (custom.row_template_declare), values as written (relative dates kept). */\n  rowTemplates?: Array<{ template_id: string; table_id: string; name: string; values: Json; body: Json | null; default: boolean }>;\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   * TEMPLATE-FRESH: preview a fresh copy (custom.template_install_fresh): every table is named \"<Table> · <title>\"\n   * and every id is the copy's own, so two copies of one template never share a table, row or column.\n   */\n  instance?: { title: string; no?: number };\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 \"status\": {\n      // A Status column is stored as a choice list wearing the `status` format, its groups keyed by choice\n      // key (newerKinds.ts) — so a board groups by it like any choice column, never \"an unusual column\".\n      base[\"type\"] = \"list\";\n      base[\"format\"] = \"status\";\n      config[\"options_table_id\"] = idOf(`options.${tableToken}.${key}`);\n      const groups = spec[\"statusGroups\"] ?? spec[\"status_groups\"];\n      if (groups && typeof groups === \"object\" && !Array.isArray(groups)) {\n        config[\"status_groups\"] = Object.fromEntries(Object.entries(groups as Json).map(([label, g]) => [choiceSlug(label), g]));\n      }\n      break;\n    }\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      if (spec[\"inverse_key\"] ?? spec[\"inverseKey\"]) base[\"inverse_key\"] = spec[\"inverse_key\"] ?? spec[\"inverseKey\"];\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|installer|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\"}${options.instance ? `:copy:${options.instance.no ?? options.instance.title}` : \"\"}`;\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 viewer = stableId(`${seed}:viewer`);\n  const resolveString = (s: string): unknown => {\n    const whole = /^\\$\\{(org|installer|ref:[^}]+|new:[^}]+|date:[^}]+)\\}$/.exec(s);\n    const one = (tok: string): string => {\n      if (tok === \"org\") return org;\n      // TEMPLATE-GAPS R3 (3): \"@installer\" seeds are the preview's own viewer, so a \"me\" view shows them.\n      if (tok === \"installer\") return viewer;\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: 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  // BUTTON-STAMPS: a rollup (sum / min / max / avg) or lookup with no look of its own reads in the number format of\n  // the column it picks, on the table its link reaches (forward: this table's own link; back: another table's link\n  // to this one, by field key or inverse key).\n  const inheritNumberLook = (table: MemoryTable, field: MemoryField) => {\n    const d = field.data;\n    const parity = String(d[\"parity_type\"] ?? \"\");\n    const cfg = (d[\"config\"] ?? {}) as Json;\n    if (d[\"display_format\"]) return;\n    if (parity === \"formula\") {\n      const look = formulaLookOf(String(cfg[\"formula_text\"] ?? \"\"), d, table.fields.map((f) => f.data));\n      if (look) d[\"display_format\"] = look;\n      return;\n    }\n    if (parity !== \"rollup\" && parity !== \"lookup\") return;\n    const look = derivedLookOf(d, (via) => {\n      const own = table.fields.find((f) => f.data[\"key\"] === via && f.data[\"type\"] === \"relation\");\n      const fars = own\n        ? [world.tableById.get(String(own.data[\"relation_target\"]))]\n        : world.tables.filter((t) => t.fields.some((f) => f.data[\"type\"] === \"relation\" && f.data[\"relation_target\"] === table.id && (f.data[\"key\"] === via || f.data[\"inverse_key\"] === via)));\n      return fars.flatMap((far) => (far ? [far.fields.map((f) => f.data)] : []));\n    });\n    if (look) d[\"display_format\"] = look;\n  };\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    inheritNumberLook(table, 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 normalizes 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: instanceTableName(String(t[\"name\"]), options.instance?.title),\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 \"anon_publish\": {\n        const id = String(args[\"p_form_id\"] ?? \"\");\n        const form = world.forms.find((f) => f.form_id === id);\n        if (form) form.published = args[\"p_published\"] !== false;\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 \"row_template_declare\": {\n        if (!tableId) break;\n        const s = args[\"p_spec\"] as Json;\n        world.rowTemplates ??= [];\n        if (s[\"default\"] === true) for (const t of world.rowTemplates) if (t.table_id === tableId) t.default = false;\n        world.rowTemplates.push({\n          template_id: idOf(step.save ? Object.keys(step.save)[0]! : step.label),\n          table_id: tableId,\n          name: String(s[\"name\"] ?? \"\"),\n          values: (s[\"values\"] as Json) ?? {},\n          body: (s[\"body\"] as Json) ?? null,\n          default: s[\"default\"] === true,\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 { fieldAppliesToEveryType, fieldAppliesToType } from \"../recordType\";\nimport { memoryEntityDoors as entityDoors } from \"./entity\";\nimport type { RecordsDataSource, RecordsFilter, RecordsResponse } from \"../ports\";\nimport type { PgError } from \"../results\";\nimport { cellMatchesWords, filterWordsOf, type AggregateGroupValue } from \"../aggregate\";\nimport { MEMORY_KERNEL, type MemoryTable, type MemoryWorld } from \"./world\";\nimport { resolveDateToken } from \"../templates/validate\";\nimport { evaluateFormula, parseFormula } from \"@ai-matrx/kit/formula\";\n\n/** What a member chip names the preview's own viewer (the live store answers the installer's own name). */\nexport const PREVIEW_VIEWER_NAME = \"You\";\n\n/** ISO date / moment strings in time order (anything else is left out), for a date min / max. */\nexport function byMoment(values: unknown[]): string[] {\n  const ISO = /^\\d{4}-\\d{2}-\\d{2}([T ]\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}(:?\\d{2})?)?)?$/;\n  return values\n    .filter((v): v is string => typeof v === \"string\" && ISO.test(v.trim()) && Number.isFinite(Date.parse(v.trim())))\n    .sort((a, b) => Date.parse(a.trim()) - Date.parse(b.trim()));\n}\n\n/**\n * A row template's values with its \"@\" words filled on `today` in `tz` for `userId` (TEMPLATE-GAPS R3b + BUTTON-STAMPS;\n * the store's custom._stamp_token twin): \"@today+3d\" is a day, \"@now\" the preview's fixed 09:00 of today, \"@me\" the\n * preview's viewer. Any other value is handed back unchanged.\n */\nexport function rowTemplateValuesNow(values: Record<string, unknown>, today: string, tz: string, userId?: string): Record<string, unknown> {\n  return Object.fromEntries(Object.entries(values ?? {}).map(([k, v]) => [k, typeof v === \"string\" && v.startsWith(\"@\") ? stampWordNow(v, today, tz, userId) : v]));\n}\n\n/** One \"@\" word as the store's custom._stamp_token would fill it; the word itself when it is not one. */\nexport function stampWordNow(word: string, today: string, tz: string, userId?: string): string {\n  if (word === \"@me\") return userId ?? word;\n  if (word === \"@now\") return resolveDateToken(\"@today 09:00\", today, tz) ?? word;\n  return resolveDateToken(word, today, tz) ?? word;\n}\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  // CHAIR-RETIRED-VALUES: `_retired` (the values a tightened rule set aside, each {key, value, reason, ...}) rides in\n  // the stored row and so on every read door, as on the live ones. The preview reader sees every column, so the\n  // live masking (a masked column's entry is dropped) keeps every entry here.\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  // CHAIR-SHEET-STORE (a): each derived cell is resolved on demand. Related rows are never\n  // expanded into whole documents just to read one picked/filtered/aggregated cell.\n  const errors: Record<string, string> = {};\n  const resolver = new CellResolver(world);\n  for (const f of table.fields) {\n    if (f.data[\"type\"] !== \"formula\" || (f.data[\"parity_type\"] !== \"lookup\" && f.data[\"parity_type\"] !== \"rollup\")) continue;\n    const key = String(f.data[\"key\"]);\n    const cell = resolver.read(table, id, key);\n    doc[key] = cell.value;\n    if (cell.error) errors[key] = cell.error;\n  }\n  // PREVIEW-DATA-FIX: a formula column is worked out on read, as the store's custom.formula_eval fills it, reading\n  // the row's other columns by label (or key) — rollups, lookups and other formulas included. A formula that reads\n  // itself in a circle, or a column that is not there, is empty and says why in `_errors`.\n  const formulas = table.fields.filter((f) => f.data[\"type\"] === \"formula\" && f.data[\"parity_type\"] === \"formula\");\n  for (const f of formulas) {\n    const key = String(f.data[\"key\"]);\n    const cell = resolver.read(table, id, key);\n    doc[key] = cell.value;\n    if (cell.error) errors[key] = cell.error;\n  }\n  if (Object.keys(errors).length) doc[\"_errors\"] = errors;\n  return doc;\n}\n\ninterface ResolvedCell {\n  value: unknown;\n  error?: string;\n  cycle?: boolean;\n}\n\n/** One top-level row read's cache; never retained across reads or mutations. */\nclass CellResolver {\n  private readonly memo = new Map<string, ResolvedCell>();\n  private readonly active = new Set<string>();\n\n  private readonly world: MemoryWorld;\n\n  constructor(world: MemoryWorld) {\n    this.world = world;\n  }\n\n  read(table: MemoryTable, id: string, key: string): ResolvedCell {\n    const cacheKey = `${table.id}:${id}:${key}`;\n    const cached = this.memo.get(cacheKey);\n    if (cached) return cached;\n    if (this.active.has(cacheKey)) throw new RangeError(\"circle\");\n    const stored = table.rows.get(id) ?? {};\n    const field = table.fields.find((candidate) => candidate.data[\"key\"] === key);\n    if (!field) return { value: stored[key] ?? null };\n    if (\n      field.data[\"type\"] === \"formula\" &&\n      field.data[\"parity_type\"] !== \"lookup\" &&\n      field.data[\"parity_type\"] !== \"rollup\" &&\n      field.data[\"parity_type\"] !== \"formula\"\n    ) return { value: stored[key] ?? null };\n    this.active.add(cacheKey);\n    try {\n      let value: unknown;\n      if (field.data[\"type\"] !== \"formula\") {\n        value = this.readStored(table, stored, key);\n      } else {\n        const config = (field.data[\"config\"] ?? {}) as Json;\n        const parity = field.data[\"parity_type\"];\n        if (parity === \"lookup\") value = this.lookup(stored, config);\n        else if (parity === \"rollup\") value = this.rollup(table, id, config);\n        else if (parity === \"formula\") value = this.formula(table, id, config);\n        else value = null;\n      }\n      const result: ResolvedCell = { value: value ?? null };\n      this.memo.set(cacheKey, result);\n      return result;\n    } catch (thrown) {\n      const what = field.data[\"parity_type\"] === \"lookup\" ? \"lookup\" : field.data[\"parity_type\"] === \"rollup\" ? \"roll-up\" : \"formula\";\n      const result: ResolvedCell = { value: null, error: workedOutSentence(what, thrown), cycle: thrown instanceof RangeError };\n      this.memo.set(cacheKey, result);\n      return result;\n    } finally {\n      this.active.delete(cacheKey);\n    }\n  }\n\n  private readStored(table: MemoryTable, stored: Json, key: string): unknown {\n    const value = stored[key];\n    const options = table.options.get(key) ?? [];\n    const option = (v: unknown) => options.find((candidate) => candidate.key === v);\n    if (Array.isArray(value)) return value.map(option).filter(Boolean).map((candidate) => candidate!.label);\n    return option(value)?.label ?? value ?? null;\n  }\n\n  private formula(table: MemoryTable, id: string, config: Json): unknown {\n    const byName = new Map<string, (typeof table.fields)[number]>();\n    for (const candidate of table.fields) byName.set(String(candidate.data[\"key\"]).toLowerCase(), candidate);\n    for (const candidate of table.fields) byName.set(String(candidate.data[\"label\"] ?? candidate.data[\"key\"]).toLowerCase(), candidate);\n    const text = String(config[\"formula_text\"] ?? \"\");\n    const parsed = parseFormula(text);\n    if (!parsed.ok) throw new Error(parsed.error);\n    let circled = false;\n    let dependencyError: string | undefined;\n    const answered = evaluateFormula(parsed.ast, (name) => {\n      const hit = byName.get(name.trim().toLowerCase());\n      if (!hit) return undefined;\n      try {\n        const cell = this.read(table, id, String(hit.data[\"key\"]));\n        if (cell.cycle) circled = true;\n        else if (cell.error && hit.data[\"parity_type\"] === \"formula\") dependencyError ??= cell.error;\n        return cell.value;\n      } catch (thrown) {\n        if (thrown instanceof RangeError) {\n          circled = true;\n          return null;\n        }\n        throw thrown;\n      }\n    }, { recordId: id });\n    if (circled) throw new RangeError(\"circle\");\n    if (dependencyError) throw new Error(dependencyError);\n    if (!answered.ok) throw new Error(answered.error);\n    return answered.value;\n  }\n\n  private lookup(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 = this.world.recordTable.get(first);\n    return far ? this.read(far, first, pick).value ?? null : null;\n  }\n\n  private rollup(table: MemoryTable, id: string, config: Json): unknown {\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    const own = maybeTable ? undefined : table.fields.find((f) => f.data[\"key\"] === maybeField && f.data[\"type\"] === \"relation\");\n    const far = own ? this.world.tableById.get(String(own.data[\"relation_target\"] ?? \"\")) : undefined;\n    if (own) {\n      const link = (table.rows.get(id) ?? {})[String(own.data[\"key\"])];\n      for (const rid of Array.isArray(link) ? link : typeof link === \"string\" ? [link] : []) {\n        if (typeof rid !== \"string\") continue;\n        const target = far ?? this.world.recordTable.get(rid);\n        if (!target || !target.rows.has(rid)) continue;\n        if (filter && !admits(this.world, target, rid, filter, this)) continue;\n        count += 1;\n        if (of && agg !== \"count\") values.push(this.read(target, rid, of).value);\n      }\n    } else {\n      for (const other of this.world.tables) {\n        if (maybeTable && other.token !== maybeTable) continue;\n        const rel = other.fields.find((f) => (f.data[\"key\"] === maybeField || f.data[\"inverse_key\"] === maybeField) && f.data[\"type\"] === \"relation\" && f.data[\"relation_target\"] === table.id);\n        if (!rel) continue;\n        const linkKey = String(rel.data[\"key\"]);\n        for (const rid of other.order) {\n          const row = other.rows.get(rid)!;\n          const link = row[linkKey];\n          const linked = Array.isArray(link) ? link.includes(id) : link === id;\n          if (!linked) continue;\n          if (filter && !admits(this.world, other, rid, filter, this)) continue;\n          count += 1;\n          if (of && agg !== \"count\") values.push(this.read(other, rid, of).value);\n        }\n      }\n    }\n    const nums = values.filter((v): v is number => typeof v === \"number\");\n    switch (agg) {\n      case \"count\": return count;\n      case \"sum\": return exact(nums.reduce((a, b) => a + b, 0));\n      case \"avg\": return nums.length ? exact(nums.reduce((a, b) => a + b, 0) / nums.length) : null;\n      case \"min\": return nums.length ? Math.min(...nums) : (byMoment(values)[0] ?? null);\n      case \"max\": return nums.length ? Math.max(...nums) : (byMoment(values).at(-1) ?? null);\n      default: return count;\n    }\n  }\n}\n\n/** The store's sentence for a worked-out column it could not work out (custom._derived_attempt). */\nfunction workedOutSentence(what: string, thrown: unknown): string {\n  if (thrown instanceof RangeError) return `This ${what} reads itself in a circle.`;\n  const said = thrown instanceof Error ? thrown.message : String(thrown);\n  return /^[A-Z`\"].*[.!?]$/.test(said) ? said : `This ${what} could not be worked out: ${said.replace(/\\.$/, \"\")}.`;\n}\n\nconst exact = (n: number): number => (Number.isFinite(n) ? Number.parseFloat(n.toPrecision(12)) : 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, resolver = new CellResolver(world)): boolean {\n  if (!filter || typeof filter !== \"object\") return true;\n  const stored = table.rows.get(id) ?? {};\n  const f = filter as Json;\n  const keys = new Set<string>();\n  const collectRuleFields = (node: unknown) => {\n    if (!node || typeof node !== \"object\" || Array.isArray(node)) return;\n    const ruleNode = node as Json;\n    if (typeof ruleNode[\"field\"] === \"string\") {\n      const field = table.fields.find((candidate) => candidate.id === ruleNode[\"field\"] || candidate.data[\"key\"] === ruleNode[\"field\"]);\n      if (field) keys.add(String(field.data[\"key\"]));\n    }\n    if (Array.isArray(ruleNode[\"args\"])) for (const child of ruleNode[\"args\"] as unknown[]) collectRuleFields(child);\n  };\n  if (typeof f[\"op\"] === \"string\") collectRuleFields(f);\n  else for (const key of Object.keys(f)) keys.add(key);\n  const doc: Json = Object.fromEntries([...keys].map((key) => [key, resolver.read(table, id, key).value]));\n  if (typeof f[\"op\"] === \"string\") { const r = rule(world, table, doc, stored, f); return r !== false && r !== null; }\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 (filterWordsOf(want)) {\n      // ROLLUP-FILTER: any-of list / {not: [...]} — key or label, any case, as the store reads it.\n      const opts = table.options.get(key) ?? [];\n      const aliases = (word: string) => opts.filter((o) => o.key.toLowerCase() === word.toLowerCase() || o.label.toLowerCase() === word.toLowerCase()).flatMap((o) => [o.key, o.label]);\n      const cell = Array.isArray(raw) ? raw : raw !== undefined && raw !== null ? [raw] : Array.isArray(got) ? got : got === undefined ? [] : [got];\n      if (!cellMatchesWords(cell, filterWordsOf(want)!, aliases)) 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\n/** A filter step this preview cannot work out: refused by name, never read as \"every row matches\". */\nclass UnknownFilterStep extends Error {}\n\nconst WEEKDAYS = [\"monday\", \"tuesday\", \"wednesday\", \"thursday\", \"friday\", \"saturday\", \"sunday\"];\n\nfunction addDays(day: string, n: number): string {\n  const d = new Date(`${day}T00:00:00Z`);\n  d.setUTCDate(d.getUTCDate() + n);\n  return d.toISOString().slice(0, 10);\n}\n\nfunction addMonths(day: string, n: number): string {\n  const d = new Date(`${day.slice(0, 7)}-01T00:00:00Z`);\n  d.setUTCMonth(d.getUTCMonth() + n);\n  return d.toISOString().slice(0, 10);\n}\n\n/**\n * A relative day window as `custom.relative_window_for_reader` works it out, on the preview's own\n * day (`world.today`) with the week starting Monday: `{from, to}` days, `to` exclusive.\n */\nfunction relativeWindow(world: MemoryWorld, w: Json): { from?: string; to?: string } {\n  if (typeof w[\"relative\"] !== \"string\") return w as { from?: string; to?: string };\n  const t = world.today;\n  const ws = addDays(t, -((new Date(`${t}T00:00:00Z`).getUTCDay() + 6) % 7) + WEEKDAYS.indexOf(\"monday\"));\n  const ms = `${t.slice(0, 7)}-01`;\n  const n = typeof w[\"n\"] === \"number\" ? Math.min(Math.max(Math.trunc(w[\"n\"] as number), 0), 3660) : null;\n  switch (w[\"relative\"]) {\n    case \"today\": return { from: t, to: addDays(t, 1) };\n    case \"tomorrow\": return { from: addDays(t, 1), to: addDays(t, 2) };\n    case \"yesterday\": return { from: addDays(t, -1), to: t };\n    case \"this_week\": return { from: ws, to: addDays(ws, 7) };\n    case \"next_week\": return { from: addDays(ws, 7), to: addDays(ws, 14) };\n    case \"last_week\": return { from: addDays(ws, -7), to: ws };\n    case \"this_month\": return { from: ms, to: addMonths(ms, 1) };\n    case \"next_month\": return { from: addMonths(ms, 1), to: addMonths(ms, 2) };\n    case \"last_month\": return { from: addMonths(ms, -1), to: ms };\n    case \"before_today\": return { to: t };\n    case \"next_days\": if (n !== null) return { from: t, to: addDays(t, n) }; break;\n    case \"past_days\": if (n !== null) return { from: addDays(t, -n), to: t }; break;\n  }\n  throw new UnknownFilterStep(`\"${String(w[\"relative\"])}\" is not a day range this filter knows.`);\n}\n\nfunction isBlank(v: unknown): boolean {\n  return v === null || v === undefined || v === \"\" || (Array.isArray(v) && v.length === 0);\n}\n\nfunction asList(v: unknown): unknown[] {\n  return Array.isArray(v) ? v : isBlank(v) ? [] : [v];\n}\n\nfunction compare(a: unknown, b: unknown): number | null {\n  if (isBlank(a) || isBlank(b)) return null;\n  if (typeof a === \"number\" && typeof b === \"number\") return a - b;\n  return String(a).localeCompare(String(b));\n}\n\n/** The store's Rule expression (`custom.rule_eval`), worked out on one preview row. */\nfunction rule(world: MemoryWorld, table: MemoryTable, doc: Json, stored: Json, node: Json): unknown {\n  if (\"const\" in node) {\n    const c = node[\"const\"];\n    if (c && typeof c === \"object\" && !Array.isArray(c) && (c as Json)[\"me\"] === true) return world.user_id;\n    return c;\n  }\n  if (typeof node[\"field\"] === \"string\") {\n    const field = table.fields.find((f) => f.id === node[\"field\"] || f.data[\"key\"] === node[\"field\"]);\n    if (!field) return null;\n    const key = String(field.data[\"key\"]);\n    const raw = stored[key];\n    // A choice compares by its key (what the store keeps) and by its words.\n    return raw !== undefined && raw !== null ? raw : doc[key] ?? null;\n  }\n  const args = ((node[\"args\"] as Json[]) ?? []).map((a) => rule(world, table, doc, stored, a));\n  const label = (v: unknown, raw: Json | undefined): unknown[] => {\n    // eq on a choice column also matches the option's words, any case.\n    const out = [v];\n    if (raw && typeof raw[\"field\"] === \"string\") {\n      const f = table.fields.find((x) => x.id === raw[\"field\"] || x.data[\"key\"] === raw[\"field\"]);\n      const opts = f ? table.options.get(String(f.data[\"key\"])) ?? [] : [];\n      for (const o of opts) if (o.key === v) out.push(o.label);\n    }\n    return out;\n  };\n  const same = (a: unknown, b: unknown, at: Json | undefined): boolean => {\n    const left = asList(a);\n    const hits = left.flatMap((x) => label(x, at));\n    return hits.some((x) => x === b || (typeof x === \"string\" && typeof b === \"string\" && x.toLowerCase() === b.toLowerCase()));\n  };\n  const raw0 = ((node[\"args\"] as Json[]) ?? [])[0];\n  switch (node[\"op\"]) {\n    case \"and\":\n    case \"all\":\n      return args.every((a) => a !== false && a !== null);\n    case \"or\":\n    case \"any\":\n      return args.some((a) => a !== false && a !== null);\n    case \"not\":\n      return args[0] === false || args[0] === null;\n    case \"eq\":\n    case \"is_exactly\":\n      return isBlank(args[1]) ? isBlank(args[0]) : same(args[0], args[1], raw0);\n    case \"ne\":\n    case \"neq\":\n      return isBlank(args[1]) ? !isBlank(args[0]) : !same(args[0], args[1], raw0);\n    case \"lt\": { const c = compare(args[0], args[1]); return c === null ? null : c < 0; }\n    case \"lte\": { const c = compare(args[0], args[1]); return c === null ? null : c <= 0; }\n    case \"gt\": { const c = compare(args[0], args[1]); return c === null ? null : c > 0; }\n    case \"gte\": { const c = compare(args[0], args[1]); return c === null ? null : c >= 0; }\n    case \"is_empty\":\n      return isBlank(args[0]);\n    case \"not_empty\":\n    case \"is_not_empty\":\n    case \"present\":\n      return !isBlank(args[0]);\n    case \"contains\":\n      return asList(args[0]).some((x) => String(x ?? \"\").toLowerCase().includes(String(args[1] ?? \"\").toLowerCase()));\n    case \"not_contains\":\n      return !asList(args[0]).some((x) => String(x ?? \"\").toLowerCase().includes(String(args[1] ?? \"\").toLowerCase()));\n    case \"matches\": {\n      const pattern = String(args[1] ?? \"\");\n      const ci = pattern.startsWith(\"(?i)\");\n      return new RegExp(ci ? pattern.slice(4) : pattern, ci ? \"i\" : \"\").test(String(args[0] ?? \"\"));\n    }\n    case \"has_any\":\n      return asList(args[1]).some((w) => asList(args[0]).some((x) => same(x, w, raw0)));\n    case \"has_all\":\n      return asList(args[1]).every((w) => asList(args[0]).some((x) => same(x, w, raw0)));\n    case \"has_none\":\n      return !asList(args[1]).some((w) => asList(args[0]).some((x) => same(x, w, raw0)));\n    case \"within\": {\n      const v = args[0];\n      if (typeof v !== \"string\" && typeof v !== \"number\") return false;\n      const w = relativeWindow(world, (args[1] ?? {}) as Json);\n      const g = String(v);\n      const at = new Date(g.length === 10 ? `${g}T00:00:00Z` : g).getTime();\n      if (Number.isNaN(at)) return false;\n      if (w.to && at >= new Date(w.to.length === 10 ? `${w.to}T00:00:00Z` : w.to).getTime()) return false;\n      if (w.from && at < new Date(w.from.length === 10 ? `${w.from}T00:00:00Z` : w.from).getTime()) return false;\n      return true;\n    }\n    case \"length\":\n      return Array.isArray(args[0]) ? args[0].length : String(args[0] ?? \"\").length;\n    case \"add\": return Number(args[0]) + Number(args[1]);\n    case \"sub\": return Number(args[0]) - Number(args[1]);\n    case \"mul\": return Number(args[0]) * Number(args[1]);\n    case \"div\": return Number(args[1]) === 0 ? null : Number(args[0]) / Number(args[1]);\n    case \"concat\": return args.map((a) => (a === null || a === undefined ? \"\" : String(a))).join(\"\");\n    default:\n      throw new UnknownFilterStep(`A template preview cannot work out the filter step \"${String(node[\"op\"])}\".`);\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<AggregateGroupValue> {\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  // CHAIR-SHEET-STORE (b): a number stays a number and yes/no stays true/false, as the store answers.\n  const out = list.map((v) =>\n    v === undefined || v === null || v === \"\" ? null : typeof v === \"number\" || typeof v === \"boolean\" ? v : String(v),\n  );\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, AggregateGroupValue>; 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, AggregateGroupValue>> = [{}];\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, AggregateGroupValue>; 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    // A member column seeded \"@installer\" holds the preview's viewer, who is no record of the template.\n    if (id === world.user_id) return PREVIEW_VIEWER_NAME;\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      // As the store answers (CD-CORE-15): no type → the columns every record has; '*' → every column; a type →\n      // the columns that apply to it.\n      const asked = typeof args[\"p_record_type\"] === \"string\" ? (args[\"p_record_type\"] as string) : null;\n      return ok(\n        t.fields.filter((f) => (asked === null ? fieldAppliesToEveryType(f.data as never) : fieldAppliesToType(f.data as never, asked))).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\", \"orange\", \"yellow\", \"pink\", \"brown\", \"gray\"], columns: {}, version: 1, rule_ops: [] }),\n    row_actions: () => ok({ stale: [], actions: [] }),\n    // A preview holds no published tables and no placement facts: the honest answer is an empty list, never a door this store cannot serve.\n    table_facts: () => ok([]),\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    // The door every relation chip asks first (CHAIR-EMBEDDED-FIDELITY 14): the words door's rows plus icons. A\n    // template's records carry no icon of their own; the table's is its document's.\n    relation_words_with_icons_many: (args) =>\n      ok(((args[\"p_record_ids\"] as string[]) ?? []).map((id) => {\n        const t = world.recordTable.get(id);\n        const tableIcon = t && typeof t.document[\"icon\"] === \"string\" ? (t.document[\"icon\"] as string) : null;\n        return { record_id: id, words: nameOf(id), archived: false, icon: null, table_icon: tableIcon };\n      })),\n    reverse_columns: (args) => {\n      const target = String(args[\"p_table_id\"] ?? \"\");\n      const out: Json[] = [];\n      // NOTION-PROPS: a two-way link's reverse Field on the target names the column it pairs with.\n      const pairOf = (fid: string) => world.tableById.get(target)?.fields.find((r) => (r.data[\"config\"] as Json | undefined)?.[\"reverse_of\"] === fid);\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          if ((f.data[\"config\"] as Json | undefined)?.[\"reverse_of\"]) continue;\n          const pair = pairOf(f.id);\n          out.push({\n            key: pair ? String(pair.data[\"key\"]) : `${t.token}__${String(f.data[\"key\"])}`,\n            label: pair ? String(pair.data[\"label\"] ?? pair.data[\"key\"]) : 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: !pair,\n          });\n        }\n      }\n      return ok(out);\n    },\n    relation_reverse_field: (args) => {\n      const hit = fieldById(args[\"p_field_id\"]);\n      if (!hit || hit.f.data[\"type\"] !== \"relation\") return refuse(\"This column is not a link, so it has no other side.\", \"22023\");\n      const target = world.tableById.get(String(hit.f.data[\"relation_target\"] ?? \"\"));\n      if (!target) return refuse(\"Only a link to one of your tables can show on the other table.\", \"22023\");\n      const have = target.fields.find((r) => (r.data[\"config\"] as Json | undefined)?.[\"reverse_of\"] === hit.f.id);\n      if (have) return ok(have.id);\n      const id = `${hit.f.id}-reverse`;\n      target.fields.push({\n        id,\n        table_id: target.id,\n        data: {\n          key: `${hit.t.token}__${String(hit.f.data[\"key\"])}`,\n          label: String(args[\"p_label\"] ?? hit.t.document[\"name\"] ?? hit.t.token),\n          type: \"relation\",\n          multi: true,\n          relation_target: hit.t.id,\n          entity_definition_id: target.id,\n          config: { reverse_of: hit.f.id },\n        },\n      });\n      return ok(id);\n    },\n    relation_reverse_set: (args) => {\n      const rev = fieldById(args[\"p_field_id\"]);\n      const fwd = rev ? fieldById((rev.f.data[\"config\"] as Json | undefined)?.[\"reverse_of\"]) : null;\n      if (!rev || !fwd) return refuse(\"This column is not the other side of a link.\", \"22023\");\n      const me = String(args[\"p_record_id\"] ?? \"\");\n      const key = String(fwd.f.data[\"key\"]);\n      const many = fwd.f.data[\"multi\"] === true;\n      let n = 0;\n      for (const other of (args[\"p_add\"] as string[] | undefined) ?? []) {\n        const doc = fwd.t.rows.get(other);\n        if (!doc) continue;\n        const have = Array.isArray(doc[key]) ? (doc[key] as string[]) : typeof doc[key] === \"string\" ? [doc[key] as string] : [];\n        doc[key] = many ? (have.includes(me) ? have : [...have, me]) : me;\n        n += 1;\n      }\n      for (const other of (args[\"p_remove\"] as string[] | undefined) ?? []) {\n        const doc = fwd.t.rows.get(other);\n        if (!doc) continue;\n        const have = Array.isArray(doc[key]) ? (doc[key] as string[]) : typeof doc[key] === \"string\" ? [doc[key] as string] : [];\n        if (!have.includes(me)) continue;\n        const left = have.filter((x) => x !== me);\n        doc[key] = many ? left : (left[0] ?? null);\n        n += 1;\n      }\n      return ok(n);\n    },\n    // The one-call door for every reverse column of a page (custom.reverse_links_many_fields): one row per field × record.\n    reverse_links_many_fields: (args) => {\n      const limit = Math.max(1, Math.min(50, Number(args[\"p_limit\"] ?? 10)));\n      const offset = Math.max(0, Number(args[\"p_offset\"] ?? 0));\n      const out: Json[] = [];\n      for (const fid of (args[\"p_field_ids\"] as string[]) ?? []) {\n        const hit = fieldById(fid);\n        for (const rid of (args[\"p_record_ids\"] as string[]) ?? []) {\n          if (!hit) {\n            out.push({ field_id: fid, record_id: rid, total: 0, links: [] });\n            continue;\n          }\n          const key = String(hit.f.data[\"key\"]);\n          const all = hit.t.order.filter((id) => {\n            const v = hit.t.rows.get(id)![key];\n            return Array.isArray(v) ? v.includes(rid) : v === rid;\n          });\n          out.push({ field_id: fid, record_id: rid, total: all.length, links: all.slice(offset, offset + limit).map((id) => ({ id, words: nameOf(id) ?? \"\" })) });\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    // TEMPLATE-GAPS R3b: row templates, their relative dates filled on the world's day (the store's\n    // custom._row_template_values_now twin).\n    row_templates: (args) =>\n      ok((world.rowTemplates ?? []).filter((t) => t.table_id === String(args[\"p_table_id\"])).sort((a, b) => a.name.localeCompare(b.name))\n        .map((t) => ({ template_id: t.template_id, name: t.name, table_id: t.table_id, values: rowTemplateValuesNow(t.values, world.today, world.timezone, world.user_id), created_at: `${world.today}T09:00:00Z`, updated_at: `${world.today}T09:00:00Z` }))),\n    row_template_default: (args) =>\n      ok((world.rowTemplates ?? []).filter((t) => t.table_id === String(args[\"p_table_id\"]) && t.default)\n        .map((t) => ({ template_id: t.template_id, name: t.name, values: rowTemplateValuesNow(t.values, world.today, world.timezone, world.user_id), body: t.body }))),\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(world, 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    // TYPEFORM-DUP. The memory world answers showIf as form_preview_asks does and takes no jumps;\n    // the store's own walk (custom._form_route) is proven against the live database, never here.\n    form_preview_route: (args) => {\n      const t = tableOf(args);\n      const values = (args[\"p_values\"] as Json | null) ?? {};\n      const endings = ((args[\"p_endings\"] as Json[]) ?? []).filter((e) => !(\"when\" in e || \"score_min\" in e || \"score_max\" in e));\n      return ok({\n        asks: ((args[\"p_questions\"] as Json[]) ?? []).map((q) => {\n          const when = q[\"show_if\"] ?? q[\"showIf\"] ?? null;\n          const asked = !when || !t ? true : rule(world, t, values, values, when as Json) !== false;\n          return { field_key: String(q[\"field\"] ?? q[\"key\"] ?? \"\"), asked, decided: true, said: null };\n        }),\n        ending: endings[0] ? String(endings[0][\"id\"]) : null,\n        score: null,\n      });\n    },\n    form_results: (args) =>\n      ok({ form_id: args[\"p_form_id\"], views: 0, starts: 0, completions: 0, completion_rate: null, questions: [], endings: [], hidden: [], score: null }),\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) {\n        try {\n          return Promise.resolve(door(args ?? {}));\n        } catch (thrown) {\n          if (thrown instanceof UnknownFilterStep) return Promise.resolve(refuse(thrown.message, \"22023\"));\n          throw thrown;\n        }\n      }\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","ref","KIT_FORMULA_FUNCTIONS","spec","import_uuid","COMPUTED","look","import_formula","ok","refuse","WEEKDAYS","zoneOffset","m","t"]}