@aglyn/plugins-ai 1.0.0-beta.152 → 1.0.0-beta.153

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/ai-doctrine-validators.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { sanitizeAuthorHtml } from '@aglyn/aglyn/app-utils/author-html'\nimport {\n formatBytes,\n measureNodeMap,\n nodeMapBytes,\n} from '@aglyn/aglyn/app-utils/measure-node-map'\nimport {\n MEDIA_CDN_VARIANT_WIDTHS,\n parseMediaRef,\n} from '@aglyn/aglyn/app-utils/media-ref'\nimport {\n ESTIMATED_PAGE_TRANSFER_BYTES,\n FREE_AI_TASTE_CREDITS_PER_MONTH,\n} from '@aglyn/aglyn/app-utils/plan-entitlements'\nimport {\n REUSABLE_INSTANCE_COMPONENT_ID,\n REUSABLE_INSTANCE_PROP_VALUES_KEY,\n} from '@aglyn/aglyn/app-utils/reusable-component-keys'\nimport { parseBreakpointSpan } from '@aglyn/shared-data-enums/breakpoint-span'\nimport { renderEmailHtml } from '@aglyn/shared-util-email/email-render'\nimport {\n aiPlanCreateFor,\n aiPlanUndeclaredRefs,\n isAiPlanNewRef,\n type AiBuildPlan,\n type AiBuildPlanCreateKind,\n type AiBuildPlanSection,\n type AiPlanUndeclaredRef,\n} from '../model/ai-build-plan'\nimport {\n aiCreationNoun,\n aiPlanUncreatable,\n aiPlanUncreatableKind,\n type AiPlanCapabilities,\n} from '../model/ai-plan-capabilities'\nimport type { AiSiteInventory } from '../model/ai-site-inventory'\nimport {\n AI_INSTANCE_REF_PROP,\n validateAiNodeTree,\n type AiNodeTreeContext,\n type AiNodeTreeResult,\n} from './ai-node-tree'\nimport { AI_PAGE_SCROLL_TO_PROP, aiPageLinkTarget, aiStoredScrollTargets } from './ai-page-links'\nimport {\n AI_EMAIL_CLIP_BYTES,\n AI_OUTPUT_BUDGETS,\n AI_OUTPUT_SURFACE,\n isHeadlineVariant,\n type AiBudgetMetric,\n type AiLoadEstimate,\n type AiOutputKind,\n} from './ai-palette'\nimport { AI_PALETTE, AI_SX_TOKENS } from './ai-palette.generated'\n\n/**\n * The building doctrine's validators (AGL-2935): the rules a generated\n * document is held to, each checked by code rather than asked of a prompt.\n *\n * A generator's system prompt carries the doctrine (`ai-doctrine.ts`), and a\n * model mostly follows it. \"Mostly\" is what these are for. Every tree and\n * every plan passes through them inside `runValidatedGeneration`; a finding\n * is a VIOLATION that names its rule and says, in a sentence a customer can\n * read, what was refused and what to do instead. The runtime re-asks the\n * model once with the findings, and stops for a person when the second\n * answer still breaks one.\n *\n * Trees are checked AFTER `validateAiNodeTree` (AGL-2905) has admitted them,\n * never instead of it: the palette validator decides what may be stored at\n * all, and these decide whether it was built the way a careful author would\n * build it. Plans are checked against the site inventory, which is where\n * \"reuse before create\" becomes checkable.\n *\n * Rule 17 is a MEASUREMENT, in the platform's existing units: the stored\n * node map in the bytes the save counts (`nodeMapBytes`), images at the size\n * the media library recorded, an email's HTML as the send path renders it,\n * and a page's load on top of the page weight the platform already measured.\n * Nothing here invents a second measure of a page.\n */\n\nexport type AiDoctrineRuleNumber =\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | 10\n | 11\n | 12\n | 13\n | 14\n | 15\n | 16\n | 17\n\n/** Each rule's title, in the words the proposal and the docs page use. */\nexport const AI_DOCTRINE_RULES: Readonly<Record<AiDoctrineRuleNumber, string>> = {\n 1: 'Repeats become one reusable component',\n 2: 'Site-wide regions live in the layout',\n 3: 'Forms are built on the Forms page, then placed',\n 4: 'Similar pages share one template',\n 5: 'Colors, spacing and type come from the theme',\n 6: 'Emails use the brand',\n 7: 'Reuse before creating',\n 8: 'Data is bound, not typed',\n 9: 'Images come from the media library, with alt text',\n 10: 'Navigation and SEO travel with a page',\n 11: 'One main landmark and an ordered outline',\n 12: \"Responsive by the theme's breakpoints\",\n 13: 'Drafts only',\n 14: 'Your voice, with no filler copy',\n 15: 'Start from a duplicate of the nearest thing',\n 16: 'The smallest document that does the job',\n 17: 'A measured budget for every output',\n}\n\nexport const AI_DOCTRINE_RULE_NUMBERS = Object.keys(AI_DOCTRINE_RULES).map(\n Number,\n) as AiDoctrineRuleNumber[]\n\nexport interface AiDoctrineViolation {\n /**\n * The rule broken; `null` when the answer could not be read as the output\n * at all, or asks for what its job does not build rather than breaking a\n * building rule.\n */\n rule: AiDoctrineRuleNumber | null\n /** Stable per finding, for specs and logs. */\n code: string\n /** One customer-safe sentence: what was refused and what to do instead. */\n message: string\n /** What the model is told beyond `message`, when the validator's own words say more. */\n detail?: string\n /** Offending nodes, by the ids of the tree that was checked. */\n nodeIds?: string[]\n /** Offending plan entries or answer fields, as `screens[1].sections[2]`. */\n paths?: string[]\n /** Rule 17: the measured figure against its budget. */\n figure?: { metric: AiBudgetMetric; value: number; budget: number }\n}\n\n/** A violation as one line: the rule's number and title, then its sentence. */\nexport function aiDoctrineViolationText(violation: AiDoctrineViolation): string {\n return violation.rule === null\n ? violation.message\n : `Rule ${violation.rule} (${AI_DOCTRINE_RULES[violation.rule]}): ${violation.message}`\n}\n\n/** Who the copy is framed for; agency and enterprise copy holds to the judgment-word rule. */\nexport type AiCopyFraming = 'agency' | 'enterprise' | null\n\n// ── Trees ────────────────────────────────────────────────────────────────\n\nexport interface AiDoctrineNode {\n componentId: string\n props?: Record<string, unknown>\n sx?: Record<string, unknown>\n nodes?: string[]\n}\n\n/** A validated flat node map, as `validateAiNodeTree` returns it. */\nexport interface AiDoctrineTree {\n rootId: string\n nodes: Record<string, AiDoctrineNode>\n}\n\n/** What a library asset records about itself, for the image weight. */\nexport interface AiAssetFacts {\n sizeBytes?: number\n width?: number\n height?: number\n}\n\nexport interface AiDoctrineTreeContext extends AiNodeTreeContext {\n /** The brand an email is held to: palette path → color, and the families. */\n brand?: { colors: Record<string, string>; fonts: string[] } | null\n /** Placed library assets by media id. */\n assets?: Record<string, AiAssetFacts>\n /** The plan named a third-party embed the brief asked for, and its cost. */\n allowEmbeds?: boolean\n framing?: AiCopyFraming\n /**\n * Whether the workspace keeps reusable components and saved forms\n * (AGL-3030). `false` builds inline, the one way such a workspace can: a\n * form is a Form holding its fields, and a repeated block is drawn where it\n * repeats. Absent is `true`, the doctrine whole.\n */\n reusableComponents?: boolean\n /**\n * The site's home screens, by id (AGL-3056): the screen a link falls back\n * to when the site has none for what it promises. Absent: none is known.\n */\n homeScreenIds?: readonly string[]\n /**\n * The node as the model wrote it, by the id the checked tree gives it\n * (AGL-3078), for a tree that was stored before it is checked: a page\n * section is checked as part of the page, whose props the palette validator\n * has already read, and a value it could not read is absent there. Absent,\n * the tree the check is given is what the model wrote.\n */\n writtenNode?: (id: string) => unknown\n /**\n * The page's sections by their names in its plan, in order, where the tree\n * is a page a plan lays out (AGL-3097). A Button or a Screen Link may then go\n * to one of them, by `scrollTo` naming it or an `href` fragment its name's\n * words make up, which the page step writes as the platform's Scroll to\n * element interaction. Absent: a link goes only where its `screenId` or\n * `href` says.\n */\n pageSections?: readonly string[]\n /**\n * The section roots of the page, by id, where the tree checked is the page as\n * the page step stores it (AGL-3097): a link there that carries a Scroll to\n * element interaction to one of them, built or still to come, goes there.\n * Only a stored page is given them. The palette validator drops every\n * interaction a model writes before anything is stored, and an answer's own\n * are never read.\n */\n scrollTargetIds?: readonly string[]\n}\n\n/** One node of a walk: its id, its depth, and its ancestors' ids from the root down. */\nexport interface Visit {\n id: string\n node: AiDoctrineNode\n depth: number\n ancestors: string[]\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Every reachable node in document order, each once. Exported for a door's\n * own checks (`extend`), which read a tree the way these detectors do.\n */\nexport function walkTree(tree: AiDoctrineTree): Visit[] {\n const visits: Visit[] = []\n const seen = new Set<string>()\n const stack: Array<{ id: string; depth: number; ancestors: string[] }> = [\n { id: tree.rootId, depth: 0, ancestors: [] },\n ]\n while (stack.length) {\n const { id, depth, ancestors } = stack.pop() as (typeof stack)[number]\n const node = tree.nodes[id]\n if (!node || seen.has(id)) continue\n seen.add(id)\n visits.push({ id, node, depth, ancestors })\n const children = node.nodes ?? []\n for (let index = children.length - 1; index >= 0; index -= 1) {\n stack.push({ id: children[index], depth: depth + 1, ancestors: [...ancestors, id] })\n }\n }\n return visits\n}\n\nfunction displayName(componentId: string): string {\n return AI_PALETTE[componentId]?.displayName ?? componentId\n}\n\n/** The HTML element a node was told to render as. */\nfunction elementOf(node: AiDoctrineNode | undefined): string {\n const value = node?.props?.['component'] ?? node?.props?.['element']\n return typeof value === 'string' ? value : ''\n}\n\nfunction hasAncestor(\n tree: AiDoctrineTree,\n visit: Visit,\n test: (node: AiDoctrineNode) => boolean,\n): boolean {\n return visit.ancestors.some((id) => {\n const node = tree.nodes[id]\n return node ? test(node) : false\n })\n}\n\nfunction unique<T>(values: T[]): T[] {\n return [...new Set(values)]\n}\n\nfunction listNames(ids: string[], tree: AiDoctrineTree): string {\n const names = unique(ids.map((id) => displayName(tree.nodes[id]?.componentId ?? '')))\n return names.length <= 1\n ? names.join('')\n : `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`\n}\n\n// Rule 1 and rule 8 read the same index: which subtrees share a shape.\n\n/** Below this, a repeat is a row of buttons, not a block worth a component. */\nexport const AI_REPEAT_MIN_NODES = 3\n/** Rule 1: a block on one page this many times is a component. */\nexport const AI_REPEAT_MIN_COUNT = 3\n/** Rule 1 across pages: a block this large on two pages is a component. */\nexport const AI_REPEAT_ACROSS_PAGES_MIN_NODES = 5\n/** Rule 8: a hand-typed list this long is data. */\nexport const AI_TYPED_LIST_MIN_ITEMS = 8\n\ninterface ShapeIndex {\n visits: Visit[]\n shapeOf: Map<string, string>\n sizeOf: Map<string, number>\n}\n\n/**\n * A subtree's shape: element ids, the prop NAMES it sets, and the values of\n * the props that change structure (enums, switches, numbers) — but never the\n * values of copy, links or media, which is what differs between the twelve\n * cards that should have been one component.\n */\nfunction indexShapes(tree: AiDoctrineTree): ShapeIndex {\n const shapeOf = new Map<string, string>()\n const sizeOf = new Map<string, number>()\n const visits = walkTree(tree)\n for (let index = visits.length - 1; index >= 0; index -= 1) {\n const { id, node } = visits[index]\n const schema = AI_PALETTE[node.componentId]?.propsSchema.properties ?? {}\n const props = Object.keys(node.props ?? {})\n .sort()\n .map((key) => {\n const declared = schema[key]\n const structural =\n Boolean(declared?.enum) ||\n declared?.type === 'boolean' ||\n declared?.type === 'number' ||\n declared?.type === 'integer'\n return structural ? `${key}=${String(node.props?.[key])}` : key\n })\n .join(',')\n const children = (node.nodes ?? []).filter((child) => shapeOf.has(child))\n shapeOf.set(\n id,\n `${node.componentId}(${props})[${children.map((child) => shapeOf.get(child)).join('|')}]`,\n )\n sizeOf.set(id, 1 + children.reduce((sum, child) => sum + (sizeOf.get(child) ?? 0), 0))\n }\n return { visits, shapeOf, sizeOf }\n}\n\n/** Whether a node sits inside a collection repeater, whose child is authored once and repeated by data. */\nfunction repeatedByData(tree: AiDoctrineTree, visit: Visit): boolean {\n return hasAncestor(tree, visit, (node) => node.componentId === 'collectionEntries')\n}\n\n/**\n * Shapes that repeat at least `minCount` times, reported only where they are\n * the outermost repeat: the header inside each of twelve cards repeats\n * because the card does, and the fix is the card. `groupOf` counts each\n * group's repeats apart; absent, the whole tree is one group.\n */\nfunction repeatedShapes(\n tree: AiDoctrineTree,\n index: ShapeIndex,\n minNodes: number,\n minCount: number,\n groupOf: (visit: Visit) => string = () => tree.rootId,\n): Array<{ shape: string; ids: string[] }> {\n const byShape = new Map<string, string[]>()\n for (const visit of index.visits) {\n if (visit.id === tree.rootId) continue\n if ((index.sizeOf.get(visit.id) ?? 0) < minNodes) continue\n if (repeatedByData(tree, visit)) continue\n const shape = JSON.stringify([groupOf(visit), index.shapeOf.get(visit.id)])\n byShape.set(shape, [...(byShape.get(shape) ?? []), visit.id])\n }\n const repeated = [...byShape.entries()].filter(([, ids]) => ids.length >= minCount)\n const repeatedIds = new Set(repeated.flatMap(([, ids]) => ids))\n const ancestorsOf = new Map(index.visits.map((visit) => [visit.id, visit.ancestors]))\n return repeated\n .filter(\n ([, ids]) =>\n !ids.every((id) => (ancestorsOf.get(id) ?? []).some((ancestor) => repeatedIds.has(ancestor))),\n )\n .map(([shape, ids]) => ({ shape, ids }))\n}\n\n/**\n * Rule 1. A block repeated on one page, or a block this page shares with\n * another page generated beside it, is one component placed as instances.\n *\n * A workspace that keeps no reusable components can place no instance, so\n * there a repeated block is drawn where it repeats, and nothing is refused.\n */\nexport function detectRepeatedSubtrees(\n tree: AiDoctrineTree,\n otherPages: readonly AiDoctrineTree[] = [],\n context: Pick<AiDoctrineTreeContext, 'reusableComponents'> = {},\n): AiDoctrineViolation[] {\n if (context.reusableComponents === false) return []\n const index = indexShapes(tree)\n const violations: AiDoctrineViolation[] = repeatedShapes(\n tree,\n index,\n AI_REPEAT_MIN_NODES,\n AI_REPEAT_MIN_COUNT,\n ).map(({ ids }) => {\n const name = displayName(tree.nodes[ids[0]].componentId)\n return {\n rule: 1,\n code: 'repeated-subtree',\n message: `The same ${name} block appears ${ids.length} times. Make it one reusable component with props for what changes, and place it ${ids.length} times.`,\n nodeIds: ids,\n }\n })\n if (otherPages.length) {\n const elsewhere = new Set<string>()\n for (const other of otherPages) {\n const otherIndex = indexShapes(other)\n for (const visit of otherIndex.visits) {\n if (visit.id === other.rootId) continue\n if ((otherIndex.sizeOf.get(visit.id) ?? 0) >= AI_REPEAT_ACROSS_PAGES_MIN_NODES) {\n elsewhere.add(otherIndex.shapeOf.get(visit.id) as string)\n }\n }\n }\n const shared = index.visits.filter(\n (visit) =>\n visit.id !== tree.rootId &&\n (index.sizeOf.get(visit.id) ?? 0) >= AI_REPEAT_ACROSS_PAGES_MIN_NODES &&\n elsewhere.has(index.shapeOf.get(visit.id) as string),\n )\n const sharedIds = new Set(shared.map((visit) => visit.id))\n const outermost = shared.filter((visit) => !visit.ancestors.some((id) => sharedIds.has(id)))\n for (const visit of outermost) {\n violations.push({\n rule: 1,\n code: 'repeated-across-pages',\n message: `This page and another share the same ${displayName(visit.node.componentId)} block. Make it one reusable component and place it on both.`,\n nodeIds: [visit.id],\n })\n }\n }\n return violations\n}\n\n/**\n * How many copies of one repeated thing a document shows, read as\n * generously as the tree allows (AGL-3024): the largest group of nodes the\n * shape index calls the same shape — the index rule 1 counts repeats with —\n * or, where a node's children outnumber that, its fan-out.\n *\n * GENEROUS ON PURPOSE. The one caller compares this against a count a plan\n * promised and speaks only when the count is SHORT, so every reading that\n * finds more items makes the check quieter, never louder: three cards whose\n * headings a hero's subtitle happens to match read as four and are let\n * through, and four cards laid out as two rows of two read as four either by\n * their shared shape or by the rows' fan-out. What it cannot do is find four\n * items in a document that holds three of everything.\n */\nexport function aiRepeatedItemCount(tree: AiDoctrineTree): number {\n const index = indexShapes(tree)\n const byShape = new Map<string, number>()\n let most = 0\n for (const visit of index.visits) {\n if (visit.id !== tree.rootId) {\n const shape = index.shapeOf.get(visit.id)\n if (shape) {\n const count = (byShape.get(shape) ?? 0) + 1\n byShape.set(shape, count)\n if (count > most) most = count\n }\n }\n const children = (visit.node.nodes ?? []).filter((id) => tree.nodes[id]).length\n if (children > most) most = children\n }\n return most\n}\n\n/** Whether a document draws its repeated items from a collection, which fills them at render. */\nexport function aiBindsRepeatedItems(tree: AiDoctrineTree): boolean {\n return walkTree(tree).some(({ node }) => node.componentId === 'collectionEntries')\n}\n\nconst REGION_ELEMENTS = new Set(['header', 'footer', 'nav'])\nconst REGION_WORDS: Record<string, string> = {\n header: 'header',\n footer: 'footer',\n nav: 'navigation',\n}\n\n/**\n * The regions a layout is built out of, and how each one is found in a tree\n * (AGL-3024): the landmark elements it may be written as, and the palette\n * elements that ARE one wherever they appear.\n *\n * A CLOSED vocabulary, because it is what a plan's promise of a region is\n * checked against: a planner naming a region outside it has promised\n * something no check can find, which the plan rules refuse rather than let\n * pass as built.\n */\nexport const AI_LAYOUT_REGIONS = {\n header: { elements: ['header'], componentIds: ['muiAppBar'] },\n nav: { elements: ['nav'], componentIds: [] },\n sidebar: { elements: ['aside'], componentIds: [] },\n main: { elements: ['main'], componentIds: ['layoutSlot'] },\n footer: { elements: ['footer'], componentIds: [] },\n} as const satisfies Record<string, { elements: readonly string[]; componentIds: readonly string[] }>\n\nexport type AiLayoutRegion = keyof typeof AI_LAYOUT_REGIONS\n\nexport const AI_LAYOUT_REGION_NAMES = Object.keys(AI_LAYOUT_REGIONS) as AiLayoutRegion[]\n\n/** The words a plan may name each region by, beyond the region's own name. */\nconst LAYOUT_REGION_ALIASES: Readonly<Record<string, AiLayoutRegion>> = {\n 'app bar': 'header',\n masthead: 'header',\n 'top bar': 'header',\n navigation: 'nav',\n 'nav bar': 'nav',\n menu: 'nav',\n aside: 'sidebar',\n 'side bar': 'sidebar',\n 'side nav': 'sidebar',\n drawer: 'sidebar',\n rail: 'sidebar',\n slot: 'main',\n 'layout slot': 'main',\n content: 'main',\n}\n\n/**\n * The region a plan's word names, or `null` for a word the vocabulary does\n * not hold.\n *\n * Read the way a recorded plan writes one. A planner names a region as\n * `header`, as `layoutSlot:slot` or as `footer:region (firm name, address)`,\n * so the name is what stands before the first colon, capitals are word\n * breaks, and a trailing \"region\" or \"area\" is filler once the whole name has\n * been tried: \"Sidebar region\", \"side-bar\" and `sidebar:links` are one thing.\n */\nexport function aiLayoutRegionOf(word: string): AiLayoutRegion | null {\n const cleaned = word\n .split(':')[0]\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, ' ')\n .trim()\n const read = (value: string): AiLayoutRegion | null =>\n (AI_LAYOUT_REGION_NAMES as string[]).includes(value)\n ? (value as AiLayoutRegion)\n : (LAYOUT_REGION_ALIASES[value] ?? null)\n if (!cleaned) return null\n return read(cleaned) ?? read(cleaned.replace(/\\s+(?:region|area)$/, ''))\n}\n\n/** Every region a built tree carries, by the elements and palette elements it holds. */\nexport function aiTreeLayoutRegions(tree: AiDoctrineTree): Set<AiLayoutRegion> {\n const found = new Set<AiLayoutRegion>()\n for (const { node } of walkTree(tree)) {\n const element = elementOf(node)\n for (const region of AI_LAYOUT_REGION_NAMES) {\n const where = AI_LAYOUT_REGIONS[region]\n if (\n (element && (where.elements as readonly string[]).includes(element)) ||\n (where.componentIds as readonly string[]).includes(node.componentId)\n ) {\n found.add(region)\n }\n }\n }\n return found\n}\n\n/**\n * Rule 2. A page carries no copy of what every page carries: an app bar, or\n * a header, navigation or footer element near the top of the document. The\n * header of an article inside the page is the article's, not the site's.\n */\nexport function detectLayoutRegions(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n if (outputKind !== 'page' && outputKind !== 'template') return []\n const found: Array<{ id: string; region: string }> = []\n for (const visit of walkTree(tree)) {\n if (visit.id === tree.rootId) continue\n if (visit.node.componentId === 'muiAppBar') {\n found.push({ id: visit.id, region: 'header' })\n continue\n }\n const element = elementOf(visit.node)\n if (\n REGION_ELEMENTS.has(element) &&\n visit.depth <= 3 &&\n !hasAncestor(tree, visit, (node) => elementOf(node) === 'article')\n ) {\n found.push({ id: visit.id, region: REGION_WORDS[element] })\n }\n }\n if (!found.length) return []\n const regions = unique(found.map((entry) => entry.region)).join(' and ')\n return [\n {\n rule: 2,\n code: 'layout-region-in-screen',\n message: `This page carries its own site ${regions}. Headers, navigation and footers live in the site's layout; put the page in the layout instead of copying them onto it.`,\n nodeIds: found.map((entry) => entry.id),\n },\n ]\n}\n\n/**\n * Rule 3. A form on a page is a Form bound by id to a form built on the\n * Forms page — fields, validation, consent and routing kept in one place.\n * Loose fields, an unbound Form, and fields drawn inside a bound Form (which\n * the page never renders: the placed form's own design replaces them) are\n * refused. A form's own design is the one place fields are drawn.\n *\n * A workspace that keeps no saved forms (AGL-3030) has no Forms page to build\n * one on, so there the form IS the page's: an unbound Form holding its Form\n * Fields, which the site's submit route collects like any other. Loose fields\n * are still refused, and so is an unbound Form with no field to send.\n */\nexport function detectInlineForms(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: Pick<AiDoctrineTreeContext, 'reusableComponents'> = {},\n): AiDoctrineViolation[] {\n if (outputKind === 'form' || outputKind === 'email') return []\n const inline = context.reusableComponents === false\n const loose: string[] = []\n const unbound: string[] = []\n const shadowed: string[] = []\n const empty: string[] = []\n const visits = walkTree(tree)\n for (const visit of visits) {\n if (\n visit.node.componentId === 'formField' &&\n !hasAncestor(tree, visit, (node) => node.componentId === 'form')\n ) {\n loose.push(visit.id)\n }\n if (visit.node.componentId === 'form') {\n const bound = visit.node.props?.['formId']\n if (typeof bound === 'string' && bound) {\n if ((visit.node.nodes ?? []).length) shadowed.push(visit.id)\n } else if (!inline) {\n unbound.push(visit.id)\n } else if (\n !visits.some(\n (inner) => inner.node.componentId === 'formField' && inner.ancestors.includes(visit.id),\n )\n ) {\n empty.push(visit.id)\n }\n }\n }\n const violations: AiDoctrineViolation[] = []\n if (inline && loose.length) {\n violations.push({\n rule: 3,\n code: 'loose-form-field',\n message:\n 'This draws form fields outside a form, where nothing sends them. Put every Form Field inside the Form it belongs to.',\n nodeIds: loose,\n })\n }\n if (empty.length) {\n violations.push({\n rule: 3,\n code: 'form-without-fields',\n message: 'This form has no field to send. Give it the Form Fields it collects.',\n nodeIds: empty,\n })\n }\n if (!inline && (loose.length || unbound.length)) {\n violations.push({\n rule: 3,\n code: 'inline-form',\n message:\n 'This draws a form inline. Build the form on the Forms page, with its fields, validation, consent and routing, then place it here by its id.',\n nodeIds: [...unbound, ...loose],\n })\n }\n if (shadowed.length) {\n violations.push({\n rule: 3,\n code: 'fields-inside-bound-form',\n message:\n 'This form is placed by its id, so its fields come from the Forms page. Remove the copies of the fields drawn inside it.',\n nodeIds: shadowed,\n })\n }\n return violations\n}\n\nconst COLOR_SX_KEYS = new Set(['color', 'bgcolor', 'backgroundColor', 'borderColor'])\nconst COLOR_IN_VALUE_SX_KEYS = new Set([\n 'border',\n 'borderTop',\n 'borderRight',\n 'borderBottom',\n 'borderLeft',\n 'boxShadow',\n])\nconst SPACING_SX_KEYS = new Set([\n 'm',\n 'mt',\n 'mr',\n 'mb',\n 'ml',\n 'mx',\n 'my',\n 'margin',\n 'marginTop',\n 'marginRight',\n 'marginBottom',\n 'marginLeft',\n 'p',\n 'pt',\n 'pr',\n 'pb',\n 'pl',\n 'px',\n 'py',\n 'padding',\n 'paddingTop',\n 'paddingRight',\n 'paddingBottom',\n 'paddingLeft',\n 'gap',\n 'rowGap',\n 'columnGap',\n])\nconst TYPE_SX_KEYS = new Set(['fontSize', 'lineHeight', 'letterSpacing'])\nconst COLOR_KEYWORDS = new Set([\n 'inherit',\n 'transparent',\n 'currentcolor',\n 'initial',\n 'unset',\n 'none',\n])\nconst LITERAL_COLOR =\n /#[0-9a-f]{3,8}\\b|\\b(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color)\\s*\\(|\\b(?:black|white|red|green|blue|yellow|orange|purple|pink|gray|grey|brown|cyan|magenta|navy|teal|maroon|olive|lime|aqua|silver|gold|indigo|violet|beige|coral|crimson|salmon|tomato|turquoise|khaki|lavender|ivory|azure)\\b/i\nconst LENGTH_WITH_UNIT = /-?\\d*\\.?\\d+\\s*(?:px|rem|em|pt|vh|vw|ch)\\b/i\nconst paletteTokens = new Set<string>(AI_SX_TOKENS.palette)\n\n/** Whether a value names a color by value rather than by theme token. */\nfunction hasLiteralColor(value: unknown): boolean {\n if (typeof value !== 'string') return false\n const parts = value\n .trim()\n .split(/\\s+/)\n .filter((part) => !paletteTokens.has(part) && !COLOR_KEYWORDS.has(part.toLowerCase()))\n return LITERAL_COLOR.test(parts.join(' '))\n}\n\n/** An `sx` value and each of its responsive values. */\nfunction sxValues(value: unknown): unknown[] {\n return isRecord(value) ? Object.values(value) : [value]\n}\n\n/**\n * Rule 5. Every color, spacing, radius and type size is a theme token. A\n * color the theme lacks is a theme change for the theme door to draft, not a\n * value written onto one element.\n */\nexport function detectLiteralStyles(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n if (outputKind === 'email') return []\n const colors: string[] = []\n const lengths: string[] = []\n for (const { id, node } of walkTree(tree)) {\n for (const [key, raw] of Object.entries(node.sx ?? {})) {\n for (const value of sxValues(raw)) {\n if ((COLOR_SX_KEYS.has(key) || COLOR_IN_VALUE_SX_KEYS.has(key)) && hasLiteralColor(value)) {\n colors.push(id)\n } else if (\n (SPACING_SX_KEYS.has(key) || key === 'borderRadius' || TYPE_SX_KEYS.has(key)) &&\n typeof value === 'string' &&\n LENGTH_WITH_UNIT.test(value)\n ) {\n lengths.push(id)\n } else if (key === 'fontSize' && typeof value === 'number' && value > 0) {\n lengths.push(id)\n }\n }\n }\n const schema = AI_PALETTE[node.componentId]?.propsSchema.properties ?? {}\n for (const [name, value] of Object.entries(node.props ?? {})) {\n if (\n /(?:^|[a-z])(?:color|Color|bgcolor)$/.test(name) &&\n !schema[name]?.enum &&\n hasLiteralColor(value)\n ) {\n colors.push(id)\n }\n }\n }\n const violations: AiDoctrineViolation[] = []\n if (colors.length) {\n violations.push({\n rule: 5,\n code: 'literal-color',\n message:\n \"This sets colors by value. Use the theme's color tokens, and propose a theme change for a color the theme does not have.\",\n nodeIds: unique(colors),\n })\n }\n if (lengths.length) {\n violations.push({\n rule: 5,\n code: 'literal-length',\n message:\n \"This sets spacing, corners or type sizes in fixed units. Use the theme's spacing scale, shape and typography styles.\",\n nodeIds: unique(lengths),\n })\n }\n return violations\n}\n\nfunction normalizeHex(value: string): string {\n const hex = value.trim().toLowerCase()\n return /^#[0-9a-f]{3}$/.test(hex)\n ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}`\n : hex\n}\n\n/**\n * Rule 6. An email is painted with the brand: its colors are the site's\n * brand colors and its fonts the brand's. A mail client cannot resolve a\n * theme token, so the brand's own values are what an email may name — and\n * with no brand recorded, the blocks' own defaults.\n */\nexport function detectOffBrandEmail(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n brand: AiDoctrineTreeContext['brand'],\n): AiDoctrineViolation[] {\n if (outputKind !== 'email') return []\n const allowed = new Set(Object.values(brand?.colors ?? {}).map(normalizeHex))\n const fonts = new Set((brand?.fonts ?? []).map((font) => font.toLowerCase()))\n const offBrand: string[] = []\n const values: string[] = []\n for (const { id, node } of walkTree(tree)) {\n const candidates: unknown[] = []\n for (const name of ['color', 'backgroundColor']) candidates.push(node.props?.[name])\n for (const [key, raw] of Object.entries(node.sx ?? {})) {\n if (COLOR_SX_KEYS.has(key)) candidates.push(...sxValues(raw))\n if (key === 'fontFamily') {\n for (const family of sxValues(raw)) {\n if (typeof family === 'string' && !fonts.has(family.trim().toLowerCase())) {\n offBrand.push(id)\n values.push(family.trim())\n }\n }\n }\n }\n for (const candidate of candidates) {\n if (typeof candidate !== 'string' || !candidate.trim()) continue\n if (!allowed.has(normalizeHex(candidate))) {\n offBrand.push(id)\n values.push(candidate.trim())\n }\n }\n }\n if (!offBrand.length) return []\n return [\n {\n rule: 6,\n code: 'off-brand-email',\n message: `This email uses ${unique(values).slice(0, 3).join(', ')}, outside the brand. Use the brand's colors and fonts so every email reads as the same sender.`,\n nodeIds: unique(offBrand),\n },\n ]\n}\n\n/**\n * Rule 8 (tree). A long list typed out item by item is data: bound to a\n * dataset or a content collection it stays current; typed, it is a copy that\n * goes stale. Instances of one component filled in side by side are the same\n * list in a component's clothes, and are counted the same way.\n *\n * A list is counted within the Section it sits in, the unit a plan counts a\n * section's items in (AGL-3061): a page's four practice areas and its four\n * steps are two short lists that happen to share a card, not one long one,\n * and a plan that kept them must not build a page this refuses. The same\n * list split across a section's columns is still one list. A tree with no\n * Section is one group.\n */\nexport function detectTypedData(tree: AiDoctrineTree): AiDoctrineViolation[] {\n const index = indexShapes(tree)\n const sectionOf = (visit: Visit): string =>\n [...visit.ancestors].reverse().find((id) => tree.nodes[id]?.componentId === 'section') ?? tree.rootId\n const violations: AiDoctrineViolation[] = repeatedShapes(\n tree,\n index,\n AI_REPEAT_MIN_NODES - 1,\n AI_TYPED_LIST_MIN_ITEMS,\n sectionOf,\n ).map(({ ids }) => ({\n rule: 8,\n code: 'typed-list',\n message: `${ids.length} ${displayName(tree.nodes[ids[0]].componentId)} items are typed out by hand. Bind the list to a dataset or content collection, or propose a dataset for data the site does not have yet.`,\n nodeIds: ids,\n }))\n for (const visit of index.visits) {\n if (repeatedByData(tree, visit) || visit.node.componentId === 'collectionEntries') continue\n const byComponent = new Map<string, string[]>()\n for (const childId of visit.node.nodes ?? []) {\n const child = tree.nodes[childId]\n const ref = child?.props?.[AI_INSTANCE_REF_PROP]\n if (child?.componentId !== REUSABLE_INSTANCE_COMPONENT_ID || typeof ref !== 'string') continue\n byComponent.set(ref, [...(byComponent.get(ref) ?? []), childId])\n }\n for (const ids of byComponent.values()) {\n if (ids.length < AI_TYPED_LIST_MIN_ITEMS) continue\n violations.push({\n rule: 8,\n code: 'typed-instances',\n message: `${ids.length} copies of one component are filled in by hand. Bind them to a dataset or content collection, or propose a dataset for data the site does not have yet.`,\n nodeIds: ids,\n })\n }\n }\n return violations\n}\n\n/** The media-role props of a node, with the declared image props of an instance. */\nfunction mediaValues(\n node: AiDoctrineNode,\n context: AiNodeTreeContext,\n): Array<{ name: string; value: string }> {\n const out: Array<{ name: string; value: string }> = []\n const roles = AI_PALETTE[node.componentId]?.propRoles ?? {}\n for (const [name, value] of Object.entries(node.props ?? {})) {\n if (roles[name] === 'media' && typeof value === 'string' && value.trim()) {\n out.push({ name, value: value.trim() })\n }\n }\n const refId = node.props?.[AI_INSTANCE_REF_PROP]\n const values = node.props?.[REUSABLE_INSTANCE_PROP_VALUES_KEY]\n if (typeof refId === 'string' && isRecord(values)) {\n const declared = context.componentProps?.[refId] ?? {}\n for (const [name, value] of Object.entries(values)) {\n if (declared[name] === 'image' && typeof value === 'string' && value.trim()) {\n out.push({ name: `${REUSABLE_INSTANCE_PROP_VALUES_KEY}.${name}`, value: value.trim() })\n }\n }\n }\n return out\n}\n\n/**\n * Rule 9. Images are placed from the media library — an asset, or an empty\n * slot for the author to fill — never hot-linked from another site, and\n * every picture carries alt text (or says it is decorative).\n */\nexport function detectImageSources(\n tree: AiDoctrineTree,\n context: AiNodeTreeContext = {},\n): AiDoctrineViolation[] {\n const hotlinked: string[] = []\n const missingAlt: string[] = []\n for (const { id, node } of walkTree(tree)) {\n if (mediaValues(node, context).some(({ value }) => /^https?:\\/\\//i.test(value))) {\n hotlinked.push(id)\n }\n if (node.componentId === 'image' || node.componentId === 'emailImage') {\n const alt = node.props?.['alt']\n const decorative = node.props?.['decorative'] === true\n if (!decorative && (typeof alt !== 'string' || !alt.trim())) missingAlt.push(id)\n }\n }\n const violations: AiDoctrineViolation[] = []\n if (hotlinked.length) {\n violations.push({\n rule: 9,\n code: 'hotlinked-image',\n message:\n 'This loads images from another website. Place images from the media library, or leave the slot empty for an upload.',\n nodeIds: hotlinked,\n })\n }\n if (missingAlt.length) {\n violations.push({\n rule: 9,\n code: 'missing-alt',\n message:\n 'An image has no alt text. Describe what each picture shows, or mark a purely decorative one as decorative.',\n nodeIds: missingAlt,\n })\n }\n return violations\n}\n\n/**\n * A heading's level: the element it renders as, else the variant's own.\n * Exported for a door's own checks, which read an outline the way rule 11\n * reads a page's.\n */\nexport function aiHeadingLevel(node: AiDoctrineNode): number | null {\n if (node.componentId !== 'muiTypography') return null\n const element =\n typeof node.props?.['component'] === 'string' ? String(node.props['component']) : ''\n const match = /^h([1-6])$/.exec(element || String(node.props?.['variant'] ?? ''))\n return match ? Number(match[1]) : null\n}\n\n/**\n * Rule 11. One `main` landmark per document, and a heading outline that\n * starts at one `h1` and never skips a level. The platform places the one\n * landmark on the layout's slot, or on a page's root when it has no layout\n * (`stampDocumentLandmark`); a tree that declares two leaves it to pick the\n * wrong one. A component, a form or an email is placed inside pages, so it\n * carries no landmark of its own, and a layout carries no `h1`: every page\n * placed in it brings its own.\n */\nexport function detectDocumentStructure(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n const visits = walkTree(tree)\n const mains = visits.filter((visit) => elementOf(visit.node) === 'main').map((visit) => visit.id)\n const violations: AiDoctrineViolation[] = []\n if (outputKind === 'component' || outputKind === 'email' || outputKind === 'form') {\n if (mains.length) {\n violations.push({\n rule: 11,\n code: 'landmark-in-fragment',\n message: `A ${outputKind} is placed inside pages, so it cannot carry the main landmark. Leave the element unset.`,\n nodeIds: mains,\n })\n }\n } else if (mains.length > 1) {\n violations.push({\n rule: 11,\n code: 'multiple-main',\n message: 'This declares more than one main landmark. A page has exactly one.',\n nodeIds: mains,\n })\n }\n if (outputKind === 'layout') {\n const slots = visits.filter((visit) => visit.node.componentId === 'layoutSlot')\n const rootElement = elementOf(tree.nodes[tree.rootId])\n const slotElement = slots[0] ? elementOf(slots[0].node) : ''\n // The landmark goes on the slot, else on the root — unless an author\n // chose another element for each.\n const chosenAway =\n rootElement !== '' &&\n rootElement !== 'main' &&\n (!slots.length || (slotElement !== '' && slotElement !== 'main'))\n if (slots.length !== 1 || chosenAway) {\n violations.push({\n rule: 11,\n code: 'layout-slot',\n message:\n 'A layout has exactly one Layout Slot, where each page renders, and the slot is the main landmark.',\n nodeIds: slots.map((slot) => slot.id),\n })\n }\n }\n if (outputKind === 'email' || outputKind === 'form') return violations\n\n const headings = visits\n .map((visit) => ({ id: visit.id, level: aiHeadingLevel(visit.node) }))\n .filter((entry): entry is { id: string; level: number } => entry.level !== null)\n const h1s = headings.filter((heading) => heading.level === 1).map((heading) => heading.id)\n const page = outputKind === 'page' || outputKind === 'template'\n if (page && h1s.length !== 1) {\n violations.push({\n rule: 11,\n code: h1s.length ? 'multiple-h1' : 'missing-h1',\n message: h1s.length\n ? `This page has ${h1s.length} top-level headings. A page has one h1; make the others h2.`\n : \"This page has no top-level heading. Give the page's title one h1.\",\n nodeIds: h1s,\n })\n } else if (!page && h1s.length > (outputKind === 'layout' ? 0 : 1)) {\n violations.push({\n rule: 11,\n code: 'multiple-h1',\n message:\n outputKind === 'layout'\n ? 'A layout wraps pages that bring their own h1, so it carries none.'\n : 'A component carries at most one h1.',\n nodeIds: h1s,\n })\n }\n const skipped: string[] = []\n let previous = page ? 0 : (headings[0]?.level ?? 1) - 1\n for (const heading of headings) {\n if (heading.level > previous + 1) skipped.push(heading.id)\n previous = heading.level\n }\n if (skipped.length) {\n violations.push({\n rule: 11,\n code: 'skipped-heading',\n message:\n 'The heading outline skips a level. Step down one level at a time — an h2 before any h3.',\n nodeIds: skipped,\n })\n }\n return violations\n}\n\nconst WIDTH_SX_KEYS = new Set(['width', 'minWidth', 'maxWidth'])\n\n/**\n * Rule 12. Widths follow the theme's breakpoints and the palette's\n * responsive props — a Container's max width, a Grid's span — never a fixed\n * pixel or viewport width that holds at one screen size. An email's column\n * is fixed by the medium, and is exempt.\n */\nexport function detectAdHocWidths(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n if (outputKind === 'email') return []\n const fixed: string[] = []\n for (const { id, node } of walkTree(tree)) {\n for (const [key, raw] of Object.entries(node.sx ?? {})) {\n if (!WIDTH_SX_KEYS.has(key)) continue\n for (const value of sxValues(raw)) {\n // MUI reads a number up to 1 as a fraction of the parent.\n if (\n (typeof value === 'number' && value > 1) ||\n (typeof value === 'string' && LENGTH_WITH_UNIT.test(value))\n ) {\n fixed.push(id)\n }\n }\n }\n }\n return fixed.length\n ? [\n {\n rule: 12,\n code: 'fixed-width',\n message:\n \"This sets fixed widths. Size elements with the theme's breakpoints — a Container's max width, a Grid span, or a percentage.\",\n nodeIds: unique(fixed),\n },\n ]\n : []\n}\n\nconst GRID = 'muiGrid'\n/** A Grid's props that only a container reads; on an item they do nothing. */\nconst GRID_CONTAINER_PROPS = ['direction', 'wrap', 'spacing', 'rowSpacing', 'columnSpacing', 'columns']\n/** A container's props that set what it holds side by side, which a group that only stacks never needs. */\nconst GRID_ROW_PROPS = ['wrap', 'columns', 'columnSpacing']\n/** The directions the palette keeps for a Grid, which lays out rows. */\nconst GRID_ROW_DIRECTIONS = ['row', 'row-reverse']\n/** A direction a Stack has and a Grid does not; the palette validator drops it from a Grid. */\nconst GRID_COLUMN_DIRECTION = /^column(?:-reverse)?$/i\n/** The elements an answer wraps a container's items in, where they belong in the container itself. */\nconst GRID_ITEM_WRAPPERS = new Set(['muiBox', 'muiStack'])\n/** `sx` keys that space a container's columns outside the widths its items are sized by. */\nconst GRID_GAP_SX_KEYS = ['gap', 'columnGap']\n/** The columns a container divides a row into when it names none. */\nconst GRID_DEFAULT_COLUMNS = 12\n/** The most characters of a written value a re-ask quotes back. */\nconst GRID_QUOTED_MAX_CHARS = 24\n\n/** A value as the model wrote it, as a re-ask quotes it: text in quotes, anything else as JSON, cut short. */\nfunction writtenValueText(value: unknown): string {\n const text = typeof value === 'string' ? value : (JSON.stringify(value) ?? String(value))\n const cut = text.length > GRID_QUOTED_MAX_CHARS ? `${text.slice(0, GRID_QUOTED_MAX_CHARS)}…` : text\n return typeof value === 'string' ? `the text \"${cut}\"` : cut\n}\n\n/** A Grid's columns: its own `columns` when it names a count, else the renderer's twelve. */\nfunction gridColumns(node: AiDoctrineNode): number {\n const columns = Number(node.props?.['columns'])\n return Number.isInteger(columns) && columns > 0 ? columns : GRID_DEFAULT_COLUMNS\n}\n\n/**\n * Whether a Grid item's size is one the renderer reads, full width on a phone,\n * and whether it steps down to a column at a larger width. The size is the\n * stored string the besigner's breakpoint row writes and the Grid renderer\n * parses (`parseBreakpointSpan`): a bare span at every width, or pairs such as\n * `xs:12 md:4`.\n */\nfunction gridItemSpan(size: unknown, columns: number): { phoneFull: boolean; steps: boolean } {\n if (typeof size !== 'string' && typeof size !== 'number') return { phoneFull: false, steps: false }\n const span = parseBreakpointSpan(size)\n if (span.raw !== undefined) return { phoneFull: false, steps: false }\n if (span.base !== undefined) return { phoneFull: span.base === columns, steps: false }\n const values = span.values ?? {}\n return {\n phoneFull: values.xs === columns,\n steps: Object.entries(values).some(([breakpoint, value]) => breakpoint !== 'xs' && value !== columns),\n }\n}\n\n/** The size a container's column is asked for: full width on a phone, a row of up to four from md. */\nfunction gridItemSizeFor(items: number, columns: number): string {\n const across = Math.min(Math.max(items, 2), 4)\n const md = Math.max(1, Math.floor(columns / (items > 4 ? 3 : across)))\n const sm = Math.floor(columns / 2)\n return items >= 4 && sm !== md ? `xs:${columns} sm:${sm} md:${md}` : `xs:${columns} md:${md}`\n}\n\n/**\n * Rule 12, for a Grid (AGL-3055). The palette's Grid is one element in both\n * roles: a CONTAINER lays its direct Grid children out in columns, and an ITEM\n * takes a size. The sizes are fractions of the container's columns, so an\n * item under a Grid that is not a container is sized against nothing, and a\n * row of them stacks one under another at every width; a size that holds at\n * every width keeps a phone's columns as narrow as a desktop's; and an `sx`\n * gap on a container spaces the columns outside the widths the items were\n * sized by, so the last column wraps onto a row of its own. A live About\n * page's practice areas were the first: a Grid with no container holding three\n * items sized \"4\", one column at every width.\n *\n * A Grid that is not a container is told what to do by what it was written as\n * (AGL-3078), because one sentence does not mend every shape: a live About\n * page's section was refused twice for rule 12, with a re-ask that only ever\n * said to make the Grid a container of sized columns.\n *\n * - `grid-not-container`: a row that is not a container. A Grid that holds\n * sized Grid items, sets a prop only a row reads, or holds two or more\n * elements of one shape side by side. The rule's intent: a row of cards is a\n * container of sized items.\n * - `grid-as-stack`: any other Grid that is not a container and sets a prop\n * only a container reads, or holds two or more elements without being an\n * item: a group that only stacks, such as a heading over its text, or one\n * written with a column direction, which a Grid does not have. The re-ask\n * offers a Stack or a Box for the group, or a container of sized items.\n * - `grid-item-outside-container`: a sized Grid item that sits in another\n * element, such as a Box inside its container. A container sizes only the\n * items directly in it, so the re-ask asks to move the item there. A Box or a\n * Stack in a container that holds nothing but sized items is refused through\n * its items, not as a child of the container that is no item.\n * - `grid-container-text`: a Grid whose `container` was written as a value the\n * palette validator cannot read as true or false, such as the text \"True\". The\n * re-ask names the value as the fault.\n * - `grid-item-size`: a container's child that is not a Grid item sized full\n * width on a phone, or a container of several whose items never step down\n * to columns at a larger width.\n * - `grid-gap`: a container spaced by an `sx` gap rather than its spacing.\n *\n * Each re-ask names the Grid or its items by the model's own ids and says what\n * to write, in the size format the renderer reads. `written` is the node as\n * the model wrote it, by an id of `tree`, where that is known: the palette\n * validator reads a `container` it cannot parse, and a column direction, as\n * absent, and only what was written can name them.\n */\nexport function detectUnresponsiveGrids(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n written: (id: string) => unknown = () => undefined,\n): AiDoctrineViolation[] {\n if (outputKind === 'email' || outputKind === 'form') return []\n // Shapes are indexed only once a Grid needs its children compared.\n let shapes: ShapeIndex | null = null\n const shapeOf = (id: string): string | undefined => (shapes ??= indexShapes(tree)).shapeOf.get(id)\n const childrenOf = (id: string): string[] => (tree.nodes[id]?.nodes ?? []).filter((child) => tree.nodes[child])\n const isGrid = (id: string | undefined): boolean => id !== undefined && tree.nodes[id]?.componentId === GRID\n const isContainer = (id: string | undefined): boolean =>\n isGrid(id) && tree.nodes[id as string].props?.['container'] === true\n const isSized = (id: string): boolean => isGrid(id) && tree.nodes[id].props?.['size'] !== undefined\n const writtenProp = (id: string, name: string): unknown => {\n const node = written(id)\n return isRecord(node) && isRecord(node['props']) ? node['props'][name] : undefined\n }\n /** A `container` the model wrote that the palette validator could not read as true or false. */\n const unreadContainer = (id: string): unknown => {\n const value = writtenProp(id, 'container')\n return tree.nodes[id].props?.['container'] === undefined && value !== null ? value : undefined\n }\n /** A Box or a Stack holding nothing but sized Grid items, which belong directly in a container. */\n const wrapsItems = (id: string): boolean => {\n const children = childrenOf(id)\n return GRID_ITEM_WRAPPERS.has(tree.nodes[id].componentId) && children.length > 0 && children.every(isSized)\n }\n /** A direction the model wrote as a column, which the palette validator drops from a Grid. */\n const writtenColumn = (id: string): boolean => {\n const direction = writtenProp(id, 'direction')\n return typeof direction === 'string' && GRID_COLUMN_DIRECTION.test(direction.trim())\n }\n /** A Grid set out as a row: a row direction, a prop only a row reads, or elements of one shape. */\n const setsOutRow = (id: string, children: readonly string[]): boolean =>\n GRID_ROW_DIRECTIONS.includes(String(tree.nodes[id].props?.['direction'])) ||\n GRID_ROW_PROPS.some((name) => tree.nodes[id].props?.[name] !== undefined) ||\n (children.length >= 2 && new Set(children.map(shapeOf)).size === 1)\n\n const refused = new Set<string>()\n const rows: string[] = []\n const stacks: Array<{ id: string; column: boolean }> = []\n const outside: Array<{ id: string; within: string }> = []\n const texts: Array<{ id: string; value: unknown }> = []\n const unsized: string[] = []\n const suggested: string[] = []\n const gapped: Array<{ id: string; spacing: unknown }> = []\n for (const visit of walkTree(tree)) {\n const { id, node } = visit\n if (node.componentId !== GRID) continue\n const children = childrenOf(id)\n const [parentId, grandparentId] = [...visit.ancestors].reverse()\n const parent = parentId === undefined ? undefined : tree.nodes[parentId]\n const sized = node.props?.['size'] !== undefined\n // An item whose container sits one element above it: a Box or a Stack holding only items.\n const wrappedItem = sized && parentId !== undefined && wrapsItems(parentId) && isContainer(grandparentId)\n if (node.props?.['container'] !== true) {\n const holdsSized = children.some(isSized)\n // An item of a container, or of a Grid refused here for not being the container it is written as.\n const isItem =\n parentId !== undefined &&\n isGrid(parentId) &&\n (isContainer(parentId) ||\n childrenOf(parentId).some(isSized) ||\n (refused.has(parentId) && unreadContainer(parentId) !== undefined))\n const setsContainerProps = GRID_CONTAINER_PROPS.some((name) => node.props?.[name] !== undefined)\n if (!holdsSized && !setsContainerProps && (isItem || children.length < 2) && !wrappedItem) continue\n refused.add(id)\n const text = unreadContainer(id)\n if (text !== undefined) texts.push({ id, value: text })\n else if (holdsSized) rows.push(id)\n else if (sized && parent && parent.componentId !== GRID) outside.push({ id, within: parent.componentId })\n else if (writtenColumn(id)) stacks.push({ id, column: true })\n else if (setsOutRow(id, children)) rows.push(id)\n else stacks.push({ id, column: false })\n continue\n }\n if (wrappedItem && parent) outside.push({ id, within: parent.componentId })\n const columns = gridColumns(node)\n // The items a Box or a Stack holds for it are sized against it, and refused where they sit.\n const items = children.flatMap((child) => (wrapsItems(child) ? childrenOf(child) : [child]))\n let steps = false\n const offending: string[] = []\n for (const child of items) {\n const item = tree.nodes[child]\n const span = item.componentId === GRID ? gridItemSpan(item.props?.['size'], columns) : null\n if (!span?.phoneFull) offending.push(child)\n if (span?.steps) steps = true\n }\n if (offending.length) {\n unsized.push(...offending)\n } else if (items.length >= 2 && !steps) {\n unsized.push(...items)\n }\n if (offending.length || (items.length >= 2 && !steps)) {\n suggested.push(gridItemSizeFor(items.length, columns))\n }\n const sx = node.sx ?? {}\n const gap = GRID_GAP_SX_KEYS.find((key) => sx[key] !== undefined)\n if (gap) gapped.push({ id, spacing: sx[gap] })\n }\n const violations: AiDoctrineViolation[] = []\n if (rows.length) {\n violations.push({\n rule: 12,\n code: 'grid-not-container',\n message:\n 'A Grid lays out columns only as a container: this one is not, so what it holds stacks at every width. Set \"container\": true on it, and put each column in a Grid item sized like \"xs:12 md:4\".',\n nodeIds: unique(rows),\n })\n }\n if (stacks.length) {\n violations.push({\n rule: 12,\n code: 'grid-as-stack',\n message: `${\n stacks[0].column\n ? 'A Grid lays out rows and has no \"column\" direction, so this one only stacks what it holds.'\n : 'A Grid that is not a container lays nothing out, so this one only stacks what it holds.'\n } Use a Stack (or a Box) for a group that only stacks, such as a heading over its text, or make it a container of sized items: set \"container\": true on it, and put each column in a Grid item sized like \"xs:12 md:4\".`,\n nodeIds: unique(stacks.map((entry) => entry.id)),\n })\n }\n if (outside.length) {\n const within = displayName(outside[0].within)\n violations.push({\n rule: 12,\n code: 'grid-item-outside-container',\n message: `A Grid item is sized only by the Grid container it sits directly in, and this one sits in a ${within}, so its size does nothing and it stacks at every width. Move it directly under its Grid container, or, where it has none, put it and the items beside it in one (\"container\": true).`,\n nodeIds: unique(outside.map((entry) => entry.id)),\n })\n }\n if (texts.length) {\n const [first] = texts\n violations.push({\n rule: 12,\n code: 'grid-container-text',\n message: `This Grid's \"container\" is ${writtenValueText(first.value)}, not true, so it is not a container and what it holds stacks at every width. Write \"container\": true${\n typeof first.value === 'string' ? ', with no quotes around true' : ''\n }.`,\n nodeIds: unique(texts.map((entry) => entry.id)),\n })\n }\n if (unsized.length) {\n violations.push({\n rule: 12,\n code: 'grid-item-size',\n message: `Every child of a Grid container is a Grid item whose size is full width on a phone and steps up to columns at a larger width, written as one string. Size these like \"${suggested[0]}\", and wrap any other element in such an item.`,\n nodeIds: unique(unsized),\n })\n }\n if (gapped.length) {\n const [first] = gapped\n const spacing = typeof first.spacing === 'number' ? first.spacing : 2\n violations.push({\n rule: 12,\n code: 'grid-gap',\n message: `A Grid container's items are sized by its \"spacing\", so an sx gap pushes its last column onto a row of its own. Remove the sx gap and set \"spacing\": ${spacing}.`,\n nodeIds: gapped.map((entry) => entry.id),\n })\n }\n return violations\n}\n\n/** The palette colors a link or a button can take, and a band can be painted in. */\nconst LINK_COLOR_FAMILIES = new Set(['primary', 'secondary', 'success', 'error', 'info', 'warning'])\n/** The elements a page links with; each draws its words in its `color` unless told otherwise. */\nconst LINK_COMPONENTS = new Set(['muiButton', 'muiScreenLink'])\n\n/** Whether an element is one rule 10 holds to a destination: a Button or a Screen Link. */\nexport function isAiLinkElement(componentId: unknown): boolean {\n return typeof componentId === 'string' && LINK_COMPONENTS.has(componentId)\n}\n\n/** Surfaces that paint their own background, whatever band they sit on. */\nconst PAPER_COMPONENTS = new Set(['muiCard', 'muiPaper', 'muiAccordion', 'muiDrawer'])\n/** A palette color token of a link family: `primary.main`, `secondary.dark`. */\nconst FAMILY_TOKEN = /^([a-z]+)\\.(?:main|dark|light)$/\n\n/** The link family a color value names, if it names one. */\nfunction familyOf(value: unknown): string | null {\n const family = typeof value === 'string' ? FAMILY_TOKEN.exec(value.trim())?.[1] : undefined\n return family && LINK_COLOR_FAMILIES.has(family) ? family : null\n}\n\n/**\n * The band a node sits on: the nearest ancestor that paints a background. An\n * `sx` background in a link family's color is a band of that family, and an\n * App Bar is one in its `color`, which is primary when it names none. Any\n * other background, and every paper surface, is not.\n */\nfunction bandOf(tree: AiDoctrineTree, visit: Visit): { family: string; token: string } | null {\n for (const id of [...visit.ancestors].reverse()) {\n const node = tree.nodes[id]\n if (!node) continue\n const background = node.sx?.['bgcolor'] ?? node.sx?.['backgroundColor']\n if (background !== undefined) {\n const token = sxValues(background).find((value) => familyOf(value) !== null)\n return typeof token === 'string' ? { family: familyOf(token) as string, token: token.trim() } : null\n }\n if (node.componentId === 'muiAppBar') {\n const color = typeof node.props?.['color'] === 'string' ? node.props['color'] : 'primary'\n return LINK_COLOR_FAMILIES.has(color) ? { family: color, token: `${color}.main` } : null\n }\n if (PAPER_COMPONENTS.has(node.componentId)) return null\n }\n return null\n}\n\n/**\n * The palette family a link or a button draws its words in: its own `sx`\n * color when it sets one, else its `color` (primary when it names none). A\n * link told to inherit takes the band's own, and a contained button draws its\n * label in the family's contrast text on a fill of its own.\n */\nfunction linkWordsFamily(node: AiDoctrineNode): string | null {\n const own = node.sx?.['color']\n if (own !== undefined) {\n return sxValues(own).map(familyOf).find((family) => family !== null) ?? null\n }\n const color = typeof node.props?.['color'] === 'string' ? node.props['color'] : 'primary'\n if (!LINK_COLOR_FAMILIES.has(color)) return null\n const styledAsButton = node.componentId === 'muiButton' || node.props?.['renderAs'] !== 'link'\n return styledAsButton && node.props?.['variant'] === 'contained' ? null : color\n}\n\n/**\n * Rule 5, for a link on a colored band (AGL-3056). The doctrine asks for\n * palette tokens, and a band in `primary.main` holding a Screen Link that\n * sets no color is two valid tokens: but the link keeps the theme's primary\n * color, so its words are navy on navy. A live About page's footer was the\n * first, a \"Request a Consultation\" link on a primary band. A link or a button\n * whose words are drawn in the family of the band it sits on is refused, with\n * a re-ask to inherit the band's contrast text or to set it.\n */\nexport function detectInvisibleLinks(tree: AiDoctrineTree, outputKind: AiOutputKind): AiDoctrineViolation[] {\n if (outputKind === 'email' || outputKind === 'form') return []\n const hidden: Array<{ id: string; family: string; token: string }> = []\n for (const visit of walkTree(tree)) {\n if (!LINK_COMPONENTS.has(visit.node.componentId)) continue\n const family = linkWordsFamily(visit.node)\n const band = family ? bandOf(tree, visit) : null\n if (band && band.family === family) hidden.push({ id: visit.id, ...band })\n }\n if (!hidden.length) return []\n const [first] = hidden\n return [\n {\n rule: 5,\n code: 'link-color-on-band',\n message: `A link or button on a ${first.token} band draws its words in the theme's ${first.family} color, the band's own, so they cannot be read. Give it \"color\": \"inherit\" under a band whose sx color is ${first.family}.contrastText, or set its own sx color to ${first.family}.contrastText.`,\n nodeIds: unique(hidden.map((entry) => entry.id)),\n },\n ]\n}\n\n/** A link's words that say it goes home. */\nconst HOME_WORDS = /\\bhome(?:\\s?page)?\\b/i\n\n/**\n * Rule 10, for a link sent where the site has nothing for it (AGL-3056). A\n * link whose purpose the site has no screen for is left out; it never goes to\n * a screen that does something else. The site inventory cannot say what each\n * screen is for, but it can name the one a model falls back to: a live About\n * page's footer sent \"Request a Consultation\" to the home screen, because the\n * site had no consultation screen. So a Screen Link or a Button, outside the\n * header and the navigation, that links the home screen with words that do\n * not say home is refused, with a re-ask to link the screen that does what it\n * says, or to leave the link out.\n */\nexport function detectUnrelatedScreenLinks(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: Pick<AiDoctrineTreeContext, 'homeScreenIds'> = {},\n): AiDoctrineViolation[] {\n if (outputKind === 'email' || outputKind === 'form') return []\n const home = new Set(context.homeScreenIds ?? [])\n const sent: Array<{ id: string; label: string }> = []\n for (const visit of walkTree(tree)) {\n const { node } = visit\n if (!LINK_COMPONENTS.has(node.componentId)) continue\n const screenId = node.props?.['screenId']\n const linksHome = (typeof screenId === 'string' && home.has(screenId)) || node.props?.['href'] === '/'\n const label = typeof node.props?.['children'] === 'string' ? node.props['children'].trim() : ''\n if (!linksHome || !label || HOME_WORDS.test(label)) continue\n // The header and the navigation link home by name and by the site's own brand.\n const inNavigation = hasAncestor(\n tree,\n visit,\n (ancestor) => ancestor.componentId === 'muiAppBar' || ['header', 'nav'].includes(elementOf(ancestor)),\n )\n if (!inNavigation) sent.push({ id: visit.id, label })\n }\n if (!sent.length) return []\n return [\n {\n rule: 10,\n code: 'link-unrelated-screen',\n message: `\"${sent[0].label}\" links the home page, which does not do what its words say. Link the screen that does, or leave the link out when the site has none.`,\n nodeIds: unique(sent.map((entry) => entry.id)),\n },\n ]\n}\n\n/** A prop value with something in it: a destination, or words. */\nfunction isFilled(value: unknown): boolean {\n return typeof value === 'string' && value.trim() !== ''\n}\n\n/**\n * Rule 10, for a link that goes nowhere (AGL-3072). A Button or a Screen Link\n * goes where its `screenId` or its `href` says, and those are the only\n * destinations either element carries: the palette validator keeps a\n * `screenId` the site has, and an `href` that is a path on the site, an\n * `https:` address or a binding the caller admitted. Nothing else can stand\n * in for one. A form is sent by the button the Form draws from its own\n * `submitLabel`, the elements a page places carry no id an anchor could name\n * (AGL-2867), and a generated node sets no interaction. So a link with\n * neither is a dead control: a live About page's hero carried a \"Request a\n * Consultation\" button with no destination. It is refused, with a re-ask\n * naming its words and what it may link.\n *\n * On a page a plan lays out (`context.pageSections`), a link may also go to a\n * section of the same page (AGL-3097). A live hero's re-ask was answered with\n * \"#consultation-form\", an anchor to the form the plan places last, and the\n * page stopped at its first section. A link that names a section, by\n * `scrollTo` or by a fragment that section's name's words make up, goes\n * there, and the page step writes the platform's Scroll to element\n * interaction for it. On a page as stored (`context.scrollTargetIds`), a link\n * carrying that interaction to one of its section roots goes there. Two\n * faults get a sentence of their own:\n *\n * - `link-fragment`: an `href` fragment that names no section. The palette\n * validator drops it, so what the link was written with goes nowhere.\n * - `scroll-target-unknown`: a `scrollTo` naming no section of the page.\n *\n * `written` is the node as the model wrote it and `stored` the node as the\n * check was given it, each by an id of `tree`.\n */\nexport function detectLinksWithoutDestination(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: Pick<AiDoctrineTreeContext, 'pageSections' | 'scrollTargetIds'> = {},\n written: (id: string) => unknown = () => undefined,\n stored: (id: string) => unknown = () => undefined,\n): AiDoctrineViolation[] {\n if (outputKind === 'email' || outputKind === 'form') return []\n const sections = context.pageSections ?? []\n const targets = new Set(context.scrollTargetIds ?? [])\n const dead: Array<{ id: string; label: string; inForm: boolean }> = []\n const fragments: Array<{ id: string; label: string; value: string }> = []\n const unknown: Array<{ id: string; label: string; value: string }> = []\n for (const visit of walkTree(tree)) {\n const { node } = visit\n if (!LINK_COMPONENTS.has(node.componentId)) continue\n if (isFilled(node.props?.['screenId']) || isFilled(node.props?.['href'])) continue\n if (aiStoredScrollTargets(stored(visit.id)).some((target) => targets.has(target))) continue\n const label = typeof node.props?.['children'] === 'string' ? node.props['children'].trim() : ''\n const target = aiPageLinkTarget(written(visit.id), sections)\n if (target?.kind === 'section') continue\n if (target?.kind === 'unknown' && target.via === 'href') {\n fragments.push({ id: visit.id, label, value: target.value })\n } else if (target?.kind === 'unknown' && context.pageSections) {\n unknown.push({ id: visit.id, label, value: target.value })\n } else {\n dead.push({ id: visit.id, label, inForm: hasAncestor(tree, visit, (ancestor) => ancestor.componentId === 'form') })\n }\n }\n const wordsOf = (entry: { id: string; label: string }): string =>\n entry.label ? `\"${entry.label}\"` : `A ${displayName(tree.nodes[entry.id].componentId)}`\n const names = sections.map((name) => `\"${name}\"`)\n const listed = names.length > 1 ? `${names.slice(0, -1).join(', ')} or ${names[names.length - 1]}` : names.join('')\n const toSection = `To take a visitor to a section of this page, set \"${AI_PAGE_SCROLL_TO_PROP}\" to that section's name in the plan: ${listed}.`\n const violations: AiDoctrineViolation[] = []\n if (fragments.length) {\n const [first] = fragments\n violations.push({\n rule: 10,\n code: 'link-fragment',\n message: `${wordsOf(first)} links \"${first.value}\", an anchor, and no element on a page carries an id an anchor could name, so it goes nowhere. ${\n context.pageSections\n ? `${toSection} Otherwise give it the \"screenId\" of a screen the site has that does what its words say, or take it out.`\n : 'Give it the \"screenId\" of a screen the site has that does what its words say, or an \"href\" that is a path on this site or an https: address the brief gives, or take it out.'\n }`,\n nodeIds: unique(fragments.map((entry) => entry.id)),\n })\n }\n if (unknown.length) {\n const [first] = unknown\n violations.push({\n rule: 10,\n code: 'scroll-target-unknown',\n message: `${wordsOf(first)} scrolls to \"${first.value}\", and this page has no section of that name. Set \"${AI_PAGE_SCROLL_TO_PROP}\" to one of its sections' names in the plan: ${listed}, or take the link out.`,\n nodeIds: unique(unknown.map((entry) => entry.id)),\n })\n }\n if (dead.length) {\n const [first] = dead\n const instead = dead.some((entry) => entry.inForm)\n ? ' A Form draws its own send button from its \"submitLabel\", so take out a button drawn inside one and set that label instead.'\n : context.pageSections\n ? ` ${toSection} When none of these fits, take it out.`\n : ' When the site has no page for it, take it out: a form on this page is sent by its own button, and no element can be reached by an anchor.'\n violations.push({\n rule: 10,\n code: 'link-without-destination',\n message: `${wordsOf(first)} goes nowhere. Give it the \"screenId\" of a screen the site has that does what its words say, or an \"href\" that is a path on this site or an https: address the brief gives.${instead}`,\n nodeIds: unique(dead.map((entry) => entry.id)),\n })\n }\n return violations\n}\n\n/** Answer fields that say \"publish\", wherever the answer put them. */\nconst PUBLISH_KEYS = /^(?:publish|published|publishNow|publishAt|goLive|isLive|live|makeLive)$/i\n\n/**\n * Rule 13. The AI writes drafts. An answer that asks for anything to be\n * published, or to go live, is refused whatever else it got right; nothing\n * downstream reads such a field, and the refusal is what keeps a future\n * reader from starting to.\n */\nexport function detectPublishIntent(answer: unknown): AiDoctrineViolation[] {\n const paths: string[] = []\n const visit = (value: unknown, path: string, depth: number) => {\n if (depth > 12 || paths.length >= 5) return\n if (Array.isArray(value)) {\n value.forEach((inner, index) => visit(inner, `${path}[${index}]`, depth + 1))\n return\n }\n if (!isRecord(value)) return\n for (const [key, inner] of Object.entries(value)) {\n const here = path ? `${path}.${key}` : key\n // An element's props and styles are page content, not instructions.\n if (key === 'props' || key === 'sx') continue\n if (\n PUBLISH_KEYS.test(key) &&\n inner !== false &&\n inner !== null &&\n inner !== undefined &&\n inner !== ''\n ) {\n paths.push(here)\n } else if (\n key === 'status' &&\n typeof inner === 'string' &&\n /^(?:published|live|public)$/i.test(inner.trim())\n ) {\n paths.push(here)\n } else {\n visit(inner, here, depth + 1)\n }\n }\n }\n visit(answer, '', 0)\n return paths.length\n ? [\n {\n rule: 13,\n code: 'publish-intent',\n message:\n 'The answer asked to publish. Everything the AI builds is a new draft; review it and publish it yourself.',\n paths,\n },\n ]\n : []\n}\n\n/** A fact the brief never gave, marked in square brackets: `[Office phone number]`. */\nconst BRACKETED_FACT = /\\[([^[\\]{}\\n]{1,80})\\]/g\n\n/**\n * The facts in square brackets copy holds (rule 14), each once whatever its\n * case, in the order they first appear, as the copy spells them\n * (AGL-3056): what a member fills in before a draft is published.\n */\nexport function aiBracketedFacts(texts: Iterable<string>): string[] {\n const facts = new Map<string, string>()\n for (const text of texts) {\n for (const match of text.matchAll(BRACKETED_FACT)) {\n const fact = match[1].trim()\n if (fact && !facts.has(fact.toLowerCase())) facts.set(fact.toLowerCase(), `[${fact}]`)\n }\n }\n return [...facts.values()]\n}\n\n/**\n * Filler that stands in for copy. A bracketed marker for a fact the brief\n * never gave — `[phone number]` — is deliberately NOT here: it is the honest\n * alternative to inventing the fact, and refusing it would push the re-ask\n * toward a made-up number.\n */\nconst FILLER_COPY =\n /\\blorem\\b|\\bipsum\\b|\\bdolor sit\\b|\\b(?:your|insert|add) (?:text|copy|content|headline|title|description|tagline) here\\b|\\b(?:placeholder|sample|dummy|filler) (?:text|copy|content)\\b|\\b(?:text|copy|content) goes here\\b/i\nconst JUDGMENT =\n /\\b(?:simply|obviously|no-brainer|cheap|effortless(?:ly)?|dead simple|super easy|just (?:a|one) click)\\b/i\n\nexport interface AiCopySample {\n /** A node id for a tree, a path for a plan. */\n at: string\n text: string\n}\n\n/**\n * Rule 14. Copy in the site's voice: no lorem ipsum or \"your text here\"\n * filler, and — for copy framed for agencies and enterprises — no words that\n * judge the reader's work as simple or cheap.\n */\nexport function detectOffVoiceCopy(\n samples: readonly AiCopySample[],\n framing: AiCopyFraming = null,\n): AiDoctrineViolation[] {\n const filler = samples.filter((sample) => FILLER_COPY.test(sample.text))\n const judged =\n framing === 'agency' || framing === 'enterprise'\n ? samples.filter((sample) => JUDGMENT.test(sample.text))\n : []\n const at = (list: readonly AiCopySample[]) => {\n const ids = unique(list.map((sample) => sample.at))\n const paths = ids.filter((id) => /[.[\\]]/.test(id))\n const nodeIds = ids.filter((id) => !/[.[\\]]/.test(id))\n return { ...(nodeIds.length ? { nodeIds } : {}), ...(paths.length ? { paths } : {}) }\n }\n const violations: AiDoctrineViolation[] = []\n if (filler.length) {\n violations.push({\n rule: 14,\n code: 'filler-copy',\n message:\n \"This leaves filler copy. Write the real words in the site's voice, from what the brief and the site already say.\",\n ...at(filler),\n })\n }\n if (judged.length) {\n violations.push({\n rule: 14,\n code: 'judgment-words',\n message:\n 'This copy calls the work simple or cheap, which reads as a judgment to an agency or enterprise audience. Say what it does instead.',\n ...at(judged),\n })\n }\n return violations\n}\n\n/** Every piece of copy a tree carries, with the node it sits on. */\nexport function aiTreeCopy(\n tree: AiDoctrineTree,\n context: AiNodeTreeContext = {},\n): AiCopySample[] {\n const samples: AiCopySample[] = []\n for (const { id, node } of walkTree(tree)) {\n const roles = AI_PALETTE[node.componentId]?.propRoles ?? {}\n for (const [name, value] of Object.entries(node.props ?? {})) {\n if (roles[name] === 'text' && typeof value === 'string' && value.trim()) {\n samples.push({ at: id, text: value })\n }\n }\n const refId = node.props?.[AI_INSTANCE_REF_PROP]\n const values = node.props?.[REUSABLE_INSTANCE_PROP_VALUES_KEY]\n if (typeof refId === 'string' && isRecord(values)) {\n const declared = context.componentProps?.[refId] ?? {}\n for (const [name, value] of Object.entries(values)) {\n const type = declared[name] ?? 'text'\n if ((type === 'text' || type === 'richText') && typeof value === 'string') {\n samples.push({ at: id, text: value })\n }\n }\n }\n }\n return samples\n}\n\n/**\n * The props a heading, a subhead or a body text shows as a line a reader\n * reads, by element. A button's or a link's label, a form field's label, a\n * run of inline text inside a sentence and every accessible name are not\n * lines, and how they end is not held.\n */\nconst LINE_PROPS: Readonly<Record<string, readonly string[]>> = {\n muiTypography: ['children'],\n muiListItemText: ['primary', 'secondary'],\n muiCardHeader: ['title', 'subheader'],\n muiAccordionSummary: ['children'],\n emailText: ['children'],\n}\n\n/** Text styles that label rather than say: a caption, an overline, a micro label. */\nconst LABEL_VARIANTS = new Set(['caption', 'overline', 'micro'])\n\n/**\n * Words no finished line ends on: an article, or a conjunction that joins two\n * parts. \"a\" counts only in lowercase, since \"Plan A\" ends on a name.\n */\nconst DANGLING_WORDS = new Set(['an', 'the', 'and', 'or', 'but', 'nor', '&'])\n\n/**\n * Words that open a phrase. A title may end on one it strands, as \"What we\n * help with\" does, but a line that ends on one right after a comma or a dash\n * opened a phrase it never wrote: \"…that matter most, with\".\n */\nconst OPENING_WORDS = new Set([\n 'about',\n 'across',\n 'after',\n 'against',\n 'along',\n 'among',\n 'as',\n 'at',\n 'because',\n 'before',\n 'between',\n 'by',\n 'for',\n 'from',\n 'if',\n 'in',\n 'into',\n 'like',\n 'of',\n 'on',\n 'onto',\n 'since',\n 'so',\n 'than',\n 'that',\n 'through',\n 'to',\n 'toward',\n 'towards',\n 'unless',\n 'until',\n 'upon',\n 'via',\n 'when',\n 'where',\n 'whereas',\n 'while',\n 'with',\n 'within',\n 'without',\n])\n\n/** A line that closes itself: a sentence's end, a closing quote or bracket, or a colon that introduces what follows. */\nconst CLOSED_LINE = /[.!?…:;\"'”’»)\\]]$/\n\n/**\n * The word a line ends on when that word leaves it unfinished (AGL-3072), or\n * `null`. A line that closes itself, ends on a binding or a bracketed fact the\n * member fills, or ends on any other word, is finished as far as a check can\n * tell. Exported for the specs that hold the closed list.\n */\nexport function aiDanglingWord(line: string): string | null {\n const text = line.trim()\n if (!text || CLOSED_LINE.test(text)) return null\n const word = /(?:^|[^A-Za-z&'’])([A-Za-z]+|&)$/.exec(text)?.[1]\n if (!word) return null\n const lower = word.toLowerCase()\n if (word === 'a' || DANGLING_WORDS.has(lower)) return word\n // A comma, a semicolon or a dash breaks the line before the word; the hyphen\n // of \"Drop-in\" or \"Add-on\" joins one word and breaks nothing.\n const before = text.slice(0, text.length - word.length)\n return OPENING_WORDS.has(lower) && /(?:[,;—–]|\\s-)\\s*$/.test(before) ? word : null\n}\n\n/** The last words of a line, as a re-ask quotes them. */\nfunction lineTail(line: string): string {\n const words = line.trim().split(/\\s+/)\n return words.length > 6 ? `…${words.slice(-6).join(' ')}` : words.join(' ')\n}\n\n/**\n * Rule 14, for a line cut short (AGL-3072). Copy in the site's voice is\n * finished copy: a heading, a subhead or a body text that ends on an article\n * or a joining conjunction, or on a word that opens a phrase right after a\n * comma, with no closing punctuation, reads as a sentence cut off mid-thought.\n * A live About page's hero subhead ended \"…that matter most, with\". A closed\n * list of words, on the lines a reader reads, keeps it deterministic: a\n * label, a button, a caption and a bracketed fact are never held to it.\n */\nexport function detectDanglingWords(tree: AiDoctrineTree): AiDoctrineViolation[] {\n const found: Array<{ id: string; line: string; word: string }> = []\n for (const { id, node } of walkTree(tree)) {\n const props = LINE_PROPS[node.componentId]\n if (!props) continue\n if (node.componentId === 'muiTypography' && LABEL_VARIANTS.has(String(node.props?.['variant'] ?? ''))) continue\n if (node.componentId === 'emailText' && node.props?.['variant'] === 'caption') continue\n for (const name of props) {\n const line = node.props?.[name]\n const word = typeof line === 'string' ? aiDanglingWord(line) : null\n if (word) found.push({ id, line: line as string, word })\n }\n }\n if (!found.length) return []\n const [first] = found\n return [\n {\n rule: 14,\n code: 'dangling-word',\n message: `\"${lineTail(first.line)}\" has no closing punctuation, and its last word, \"${first.word}\", leaves the sentence unfinished. Finish the sentence, or end the line before \"${first.word}\".`,\n nodeIds: unique(found.map((entry) => entry.id)),\n },\n ]\n}\n\n/** The labels a button or a link shows, beside the lines: cut, they read as broken too. */\nconst LABEL_PROPS: Readonly<Record<string, readonly string[]>> = {\n muiButton: ['children'],\n muiScreenLink: ['children'],\n emailButton: ['children'],\n}\n\n/** The line the palette validator writes when it cuts a prop at its ceiling. */\nconst CUT_REPAIR = /^(.+)\\.([A-Za-z0-9_]+) was over (\\d+) characters; truncated$/\n\n/** The first words of a line, as a re-ask quotes them. */\nfunction lineHead(line: string): string {\n const words = line.trim().split(/\\s+/)\n return words.length > 8 ? `${words.slice(0, 8).join(' ')}…` : words.join(' ')\n}\n\n/**\n * Rule 14, for a line cut at its ceiling (AGL-3076). The palette validator\n * holds copy to a ceiling for its role and cuts what runs past it, and says so\n * only in its repairs. A cut line is unfinished wherever the cut falls, after\n * a word or inside one, and a heading style's ceiling of\n * `AI_TEXT_LIMITS.headline` characters is one the catalog never shows a model:\n * a live About page's hero subhead, a Typography in the h5 style, was cut at\n * 120 characters to \"…that matter most, with\". So a heading, a subhead, a body\n * line, or a button's or a link's label the validator cut is refused, with a\n * re-ask naming the ceiling.\n *\n * `repairs` are the palette validator's, naming nodes by the ids of the tree\n * it was given, `written`; `idOf` turns such an id into the id the violation\n * names.\n */\nexport function detectCutLines(\n repairs: readonly string[],\n written: Readonly<Record<string, unknown>>,\n idOf: (id: string) => string = (id) => id,\n): AiDoctrineViolation[] {\n const cut: Array<{ id: string; line: string; limit: number; heading: boolean }> = []\n for (const repair of repairs) {\n const match = CUT_REPAIR.exec(repair)\n if (!match) continue\n const [, nodeId, name, limit] = match\n const node = written[nodeId]\n if (!isRecord(node) || typeof node['componentId'] !== 'string') continue\n const props = isRecord(node['props']) ? node['props'] : {}\n const shown = LINE_PROPS[node['componentId']] ?? LABEL_PROPS[node['componentId']] ?? []\n const line = props[name]\n if (!shown.includes(name) || typeof line !== 'string') continue\n cut.push({\n id: idOf(nodeId),\n line,\n limit: Number(limit),\n heading: node['componentId'] === 'muiTypography' && isHeadlineVariant(props['variant']),\n })\n }\n if (!cut.length) return []\n const [first] = cut\n const message = first.heading\n ? `A line in a heading style holds at most ${first.limit} characters, and \"${lineHead(first.line)}\" runs past them, so it was cut off where they end. Write it whole within ${first.limit} characters, or give a longer line a subtitle or body style.`\n : `\"${lineHead(first.line)}\" runs past the ${first.limit} characters its element holds, so it was cut off where they end. Write it whole within ${first.limit} characters.`\n return [{ rule: 14, code: 'copy-cut-at-ceiling', message, nodeIds: unique(cut.map((entry) => entry.id)) }]\n}\n\nconst PURE_CONTAINERS = new Set(['muiBox', 'muiStack', 'muiContainer', 'muiGrid', 'section'])\nconst EMBED_COMPONENTS = new Set(['videoEmbed', 'custom-html', 'functionWidget'])\nconst DUPLICATE_SX_MIN_KEYS = 2\nconst DUPLICATE_SX_MIN_NODES = 4\n\n/**\n * Rule 16. The flattest tree that renders the design: no container that\n * wraps one other container and adds nothing, no empty containers, no inline\n * style repeated where a token or a component prop would carry it, no font\n * beyond the theme's, images lazy below the first, video by poster rather\n * than autoplay, and no third-party embed the plan did not name.\n */\nexport function detectHeavyDocument(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext = {},\n): AiDoctrineViolation[] {\n const visits = walkTree(tree)\n const wrappers: string[] = []\n const empty: string[] = []\n const fonts: string[] = []\n const eager: string[] = []\n const video: string[] = []\n const embeds: string[] = []\n const sxSeen = new Map<string, string[]>()\n let images = 0\n for (const { id, node } of visits) {\n const entry = AI_PALETTE[node.componentId]\n const children = (node.nodes ?? []).filter((child) => tree.nodes[child])\n const ownProps = Object.entries(node.props ?? {}).filter(\n ([name, value]) => !(name === 'component' && value === 'div'),\n )\n if (\n id !== tree.rootId &&\n PURE_CONTAINERS.has(node.componentId) &&\n children.length === 1 &&\n PURE_CONTAINERS.has(tree.nodes[children[0]].componentId) &&\n !ownProps.length &&\n !Object.keys(node.sx ?? {}).length\n ) {\n wrappers.push(id)\n }\n const boundForm = node.componentId === 'form' && typeof node.props?.['formId'] === 'string'\n if (entry?.acceptsChildren && !children.length && !boundForm) empty.push(id)\n if (outputKind !== 'email' && node.sx?.['fontFamily'] !== undefined) fonts.push(id)\n if (node.componentId === 'image') {\n images += 1\n if (images > 1 && node.props?.['loading'] === 'eager') eager.push(id)\n }\n if (\n node.componentId === 'video' &&\n (node.props?.['autoPlay'] === true ||\n node.props?.['preload'] === 'auto' ||\n (typeof node.props?.['src'] === 'string' && node.props['src'] && !node.props?.['poster']))\n ) {\n video.push(id)\n }\n if (EMBED_COMPONENTS.has(node.componentId) && !context.allowEmbeds) embeds.push(id)\n const sx = node.sx ?? {}\n if (Object.keys(sx).length >= DUPLICATE_SX_MIN_KEYS) {\n const key = JSON.stringify(Object.keys(sx).sort().map((name) => [name, sx[name]]))\n sxSeen.set(key, [...(sxSeen.get(key) ?? []), id])\n }\n }\n const duplicatedSx = [...sxSeen.values()]\n .filter((ids) => ids.length >= DUPLICATE_SX_MIN_NODES)\n .flat()\n const violations: AiDoctrineViolation[] = []\n const add = (code: string, ids: string[], message: string) => {\n if (ids.length) violations.push({ rule: 16, code, message, nodeIds: ids })\n }\n add(\n 'wrapper-in-wrapper',\n wrappers,\n 'A container wraps a single container and adds nothing. Remove the outer one.',\n )\n add('empty-container', empty, 'An element meant to hold content is empty. Remove it, or fill it.')\n add(\n 'duplicated-inline-style',\n duplicatedSx,\n 'The same inline style repeats across elements. Carry it in a theme token or a component prop, once.',\n )\n add('extra-font', fonts, \"This names a font the theme does not load. Use the theme's typography.\")\n add(\n 'eager-image',\n eager,\n 'An image below the first loads eagerly. Leave loading unset so images further down the page load when they are reached.',\n )\n add(\n 'autoplay-video',\n video,\n 'A video loads its file before anyone plays it. Give it a poster, and let it play on click.',\n )\n add(\n 'third-party-embed',\n embeds,\n 'This embeds a third-party player or script, which loads its own code on every visit. Use a Video from the media library, or name the embed and its cost in the plan.',\n )\n return violations\n}\n\n/** The items a list or a row of cards repeats, as a re-ask names them. */\nconst ITEM_NOUNS: Readonly<Record<string, string>> = { muiListItem: 'list item', muiCard: 'card' }\n\n/** Elements that frame or space what they hold and show nothing of their own. */\nconst FRAME_COMPONENTS = new Set([\n 'div',\n 'section',\n 'muiBox',\n 'muiStack',\n 'muiContainer',\n 'muiGrid',\n 'muiPaper',\n 'muiCard',\n 'muiCardContent',\n 'muiCardActions',\n 'muiListItem',\n 'muiAccordion',\n 'muiAccordionDetails',\n])\n\n/** Elements that show only their words, by the props that hold them. */\nconst WORD_PROPS: Readonly<Record<string, readonly string[]>> = {\n ...LINE_PROPS,\n muiList: ['subheader'],\n muiInlineText: ['children'],\n muiButton: ['children'],\n muiScreenLink: ['children'],\n}\n\n/** Whether a node shows anything of its own: its words, or whatever an element that is neither a frame nor words draws. */\nfunction showsOwn(node: AiDoctrineNode): boolean {\n const words = WORD_PROPS[node.componentId]\n if (words) return words.some((name) => isFilled(node.props?.[name]))\n return !FRAME_COMPONENTS.has(node.componentId)\n}\n\n/**\n * Rule 16, for an item with nothing in it (AGL-3072). A list item or a card\n * that holds elements, none of which shows a word, a picture or anything\n * else, is an empty row or an empty box on the page: a live About page's list\n * of estate planning services ended on a List Item whose List Item Text had\n * no words. An item that holds no element at all is `empty-container`'s, and\n * is not reported twice.\n */\nexport function detectEmptyItems(tree: AiDoctrineTree): AiDoctrineViolation[] {\n const empty: Array<{ id: string; noun: string }> = []\n for (const { id, node } of walkTree(tree)) {\n const noun = ITEM_NOUNS[node.componentId]\n if (!noun || !(node.nodes ?? []).some((child) => tree.nodes[child])) continue\n if (!walkTree({ rootId: id, nodes: tree.nodes }).some((inner) => showsOwn(inner.node))) {\n empty.push({ id, noun })\n }\n }\n if (!empty.length) return []\n const nouns = unique(empty.map((entry) => entry.noun))\n const message =\n nouns.length > 1\n ? 'A list item and a card hold nothing to read or see. Give each its words, or take it out.'\n : nouns[0] === 'list item'\n ? 'A list item holds no words, so its row shows empty. Write the words of its List Item Text, or take the item out.'\n : 'A card holds nothing to read or see. Give it its words, or take the card out.'\n return [{ rule: 16, code: 'empty-item', message, nodeIds: empty.map((entry) => entry.id) }]\n}\n\n// ── Rule 17: the budget, measured ────────────────────────────────────────\n\nexport interface AiOutputScore {\n nodes: number\n /** The stored node map, in the save's own bytes. */\n bytes: number\n /** What the placed library images request, from their recorded sizes. */\n imageBytes: number\n /** Placed images the media library could not size: hot-linked, or no facts supplied. */\n imagesUnmeasured: number\n embeds: number\n fontFamilies: number\n /** An email's rendered HTML; `null` for every other output. */\n emailHtmlBytes: number | null\n}\n\nconst EMAIL_COLUMN_PX = 600\nconst MEDIA_IMAGE_PROPS: Record<string, readonly string[]> = {\n image: ['src'],\n emailImage: ['src'],\n video: ['poster'],\n collectionEntryAuthor: ['image'],\n contentAuthorProfile: ['image'],\n}\n\n/** The variant a slot of this width is served. */\nfunction servedVariantWidth(slotWidth: number | null): number {\n const widest = MEDIA_CDN_VARIANT_WIDTHS[MEDIA_CDN_VARIANT_WIDTHS.length - 1]\n if (!slotWidth) return widest\n return MEDIA_CDN_VARIANT_WIDTHS.find((width) => width >= slotWidth) ?? widest\n}\n\nfunction pixels(value: unknown): number | null {\n const parsed = typeof value === 'number' ? value : Number.parseFloat(String(value ?? ''))\n return Number.isFinite(parsed) && parsed > 0 ? parsed : null\n}\n\nfunction imageRequests(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext,\n): Array<{ id: string; bytes: number | null }> {\n const requests: Array<{ id: string; bytes: number | null }> = []\n for (const { id, node } of walkTree(tree)) {\n const named = MEDIA_IMAGE_PROPS[node.componentId] ?? []\n const values = mediaValues(node, context).filter(\n ({ name }) =>\n named.includes(name) || name.startsWith(`${REUSABLE_INSTANCE_PROP_VALUES_KEY}.`),\n )\n for (const { value } of values) {\n const ref = parseMediaRef(value)\n const facts = ref ? context.assets?.[ref.mediaId] : undefined\n if (!facts?.sizeBytes) {\n requests.push({ id, bytes: null })\n continue\n }\n const slot = pixels(node.props?.['width'])\n const variant = servedVariantWidth(\n outputKind === 'email' ? Math.min(slot ?? EMAIL_COLUMN_PX, EMAIL_COLUMN_PX) : slot,\n )\n // A variant is the original scaled down, so its bytes scale with its\n // area; a variant wider than the original is the original.\n const ratio = facts.width ? Math.min(1, variant / facts.width) : 1\n requests.push({ id, bytes: Math.round(facts.sizeBytes * ratio * ratio) })\n }\n }\n return requests\n}\n\n/** The rule-17 measurements of one validated tree. */\nexport function scoreAiOutput(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext = {},\n): AiOutputScore {\n const visits = walkTree(tree)\n const images = imageRequests(tree, outputKind, context)\n const families = new Set<string>()\n for (const { node } of visits) {\n for (const family of sxValues(node.sx?.['fontFamily'])) {\n if (typeof family === 'string' && family.trim()) families.add(family.trim().toLowerCase())\n }\n }\n let emailHtmlBytes: number | null = null\n if (outputKind === 'email') {\n const { html } = renderEmailHtml({\n nodes: tree.nodes as Parameters<typeof renderEmailHtml>[0]['nodes'],\n rootId: tree.rootId,\n sanitize: (value: string) => sanitizeAuthorHtml(value),\n })\n emailHtmlBytes = new TextEncoder().encode(html).length\n }\n return {\n nodes: visits.length,\n bytes: nodeMapBytes(tree.nodes),\n imageBytes: images.reduce((sum, image) => sum + (image.bytes ?? 0), 0),\n imagesUnmeasured: images.filter((image) => image.bytes === null).length,\n embeds: visits.filter(({ node }) => EMBED_COMPONENTS.has(node.componentId)).length,\n fontFamilies: families.size,\n emailHtmlBytes,\n }\n}\n\nconst METRIC_LABELS: Record<AiBudgetMetric, string> = {\n nodes: 'elements',\n bytes: 'stored size',\n imageBytes: 'image weight',\n embeds: 'third-party embeds',\n fontFamilies: 'extra font families',\n emailHtmlBytes: `rendered size (mail clients clip past ${formatBytes(AI_EMAIL_CLIP_BYTES)})`,\n}\n\nfunction figure(metric: AiBudgetMetric, value: number): string {\n return metric === 'nodes' || metric === 'embeds' || metric === 'fontFamilies'\n ? value.toLocaleString('en-US')\n : formatBytes(value)\n}\n\n/** The parts of a tree that weigh most under one metric, heaviest first. */\nfunction heaviest(\n metric: AiBudgetMetric,\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext,\n): string[] {\n switch (metric) {\n case 'bytes':\n case 'emailHtmlBytes':\n return measureNodeMap(tree.nodes).largest.map((entry) => entry.id)\n case 'nodes': {\n const index = indexShapes(tree)\n return index.visits\n .filter((visit) => visit.depth >= 1 && visit.depth <= 2)\n .sort((a, b) => (index.sizeOf.get(b.id) ?? 0) - (index.sizeOf.get(a.id) ?? 0))\n .slice(0, 3)\n .map((visit) => visit.id)\n }\n case 'imageBytes':\n return imageRequests(tree, outputKind, context)\n .filter((image) => image.bytes !== null)\n .sort((a, b) => (b.bytes ?? 0) - (a.bytes ?? 0))\n .slice(0, 3)\n .map((image) => image.id)\n case 'embeds':\n return walkTree(tree)\n .filter(({ node }) => EMBED_COMPONENTS.has(node.componentId))\n .map((visit) => visit.id)\n case 'fontFamilies':\n return walkTree(tree)\n .filter(({ node }) => node.sx?.['fontFamily'] !== undefined)\n .map((visit) => visit.id)\n }\n}\n\nconst BUDGET_METRICS: readonly AiBudgetMetric[] = [\n 'nodes',\n 'bytes',\n 'imageBytes',\n 'embeds',\n 'fontFamilies',\n 'emailHtmlBytes',\n]\n\n/**\n * Rule 17. An output over its kind's budget is refused with the figure, the\n * budget and the heaviest parts named, so the re-ask knows where to cut.\n */\nexport function detectOverBudget(\n score: AiOutputScore,\n outputKind: AiOutputKind,\n tree: AiDoctrineTree,\n context: AiDoctrineTreeContext = {},\n): AiDoctrineViolation[] {\n const budget = AI_OUTPUT_BUDGETS[outputKind]\n const violations: AiDoctrineViolation[] = []\n for (const metric of BUDGET_METRICS) {\n const value = score[metric]\n const limit = budget[metric]\n if (value === null || limit === undefined || value <= limit) continue\n const offenders = heaviest(metric, tree, outputKind, context)\n const parts = offenders.length ? ` The heaviest parts: ${listNames(offenders, tree)}.` : ''\n violations.push({\n rule: 17,\n code: `over-budget-${metric}`,\n message: `This ${outputKind} measures ${figure(metric, value)} of ${METRIC_LABELS[metric]} against a budget of ${figure(metric, limit)}.${parts}`,\n nodeIds: offenders,\n figure: { metric, value, budget: limit },\n })\n }\n return violations\n}\n\n/**\n * What a first visit to a generated output is estimated to transfer.\n *\n * The page half is a MEASUREMENT the platform already holds, not a guess:\n * `ESTIMATED_PAGE_TRANSFER_BYTES` is the first-party weight a published page\n * measured at settle, which `check:page-view-rate` holds against the\n * tenant page budget and the bandwidth meter is priced from. The tenant's\n * real-user vitals (`web-vitals-rum.ts`) report to analytics per visit and\n * are not readable for a draft nobody has visited, so they are not a second\n * source here. On top of that weight go this output's own stored document\n * and the images it places. A component or a layout reports what it adds to\n * a page; an email is not a page load and has none.\n */\nexport function estimateAiOutputLoad(\n score: AiOutputScore,\n outputKind: AiOutputKind,\n): AiLoadEstimate | null {\n if (outputKind === 'email') return null\n const pageBytes =\n outputKind === 'page' || outputKind === 'template' ? ESTIMATED_PAGE_TRANSFER_BYTES : 0\n return {\n pageBytes,\n documentBytes: score.bytes,\n imageBytes: score.imageBytes,\n imagesUnmeasured: score.imagesUnmeasured,\n embeds: score.embeds,\n totalBytes: Math.round(pageBytes + score.bytes + score.imageBytes),\n }\n}\n\n/**\n * A NODE MAP THAT DOES NOT AGREE WITH ITSELF (AGL-3143).\n *\n * A flat node map is two halves that have to match: what each node lists\n * under `nodes`, and what the map holds. A model writing one section in one\n * pass gets them out of step in two ways, and neither reaches it as\n * something it can act on.\n *\n * An element written but listed by nobody is dropped on the way in, so the\n * container that should have held it reads as empty and the answer comes\n * back \"an element meant to hold content is empty — remove it, or fill it\".\n * The content is already written; it is one line away from being placed, and\n * the re-ask does not say so. A live page build was told exactly that of a\n * card grid whose repeated card it had written and not placed; it answered by\n * naming four children and writing one.\n *\n * Which is the other half: a name listed under `nodes` that the map never\n * holds. That one is refused, but by the sanitizer under the palette\n * validator, as `Missing node \"card2\"` — which the door turns into \"the\n * answer could not be used as a section\", with no rule, no node and nothing\n * to change. It cost that page its last attempt and the build stopped three\n * sections in, so the page's form — the thing being measured — was never\n * reached at all.\n *\n * Both are read off the tree AS THE MODEL WROTE IT, before the palette\n * validator drops anything, so a re-ask can quote the node at fault.\n */\nexport function detectDisagreeingNodes(input: unknown): AiDoctrineViolation[] {\n if (!isRecord(input) || typeof input['rootId'] !== 'string' || !isRecord(input['nodes'])) return []\n const rootId = input['rootId']\n const nodes = input['nodes']\n if (!isRecord(nodes[rootId])) return []\n const childrenOf = (id: string): string[] => {\n const node = nodes[id]\n const listed = isRecord(node) ? node['nodes'] : undefined\n return Array.isArray(listed) ? listed.filter((child): child is string => typeof child === 'string') : []\n }\n const reached = new Set<string>([rootId])\n const missing = new Map<string, string[]>()\n const queue = [rootId]\n while (queue.length) {\n const id = queue.shift() as string\n for (const child of childrenOf(id)) {\n if (!isRecord(nodes[child])) {\n missing.set(id, [...(missing.get(id) ?? []), child])\n continue\n }\n if (reached.has(child)) continue\n reached.add(child)\n queue.push(child)\n }\n }\n const orphans = Object.keys(nodes).filter((id) => !reached.has(id) && isRecord(nodes[id]))\n const violations: AiDoctrineViolation[] = []\n if (missing.size) {\n const named = unique([...missing.values()].flat())\n violations.push({\n rule: null,\n code: 'missing-child',\n message:\n 'This holds elements that were never written, so the answer could not be read. Write each one, or take its name out of the list of what this holds.',\n detail: `Listed under \"nodes\" and missing from the answer: ${named.map((id) => `\"${id}\"`).join(', ')}.`,\n nodeIds: [...missing.keys()],\n })\n }\n if (orphans.length) {\n violations.push({\n rule: 16,\n code: 'orphan-node',\n message:\n 'This element was written, but nothing holds it, so none of it reaches the page. List it under the element it belongs in, or take it out.',\n nodeIds: orphans,\n })\n }\n return violations\n}\n\nexport interface AiDoctrineTreeReport {\n ok: boolean\n /** The palette validator's result: the tree to store, its repairs and its id map. */\n tree: Extract<AiNodeTreeResult, { ok: true }> | null\n violations: AiDoctrineViolation[]\n score: AiOutputScore | null\n load: AiLoadEstimate | null\n}\n\n/**\n * The whole check on one emitted tree: the palette validator first, then\n * every tree rule, then the budget. `otherPages` are the trees generated\n * beside this one, for the across-pages half of rule 1.\n */\nexport function validateAiDoctrineTree(\n input: unknown,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext = {},\n otherPages: readonly AiDoctrineTree[] = [],\n): AiDoctrineTreeReport {\n const publish = detectPublishIntent(input)\n // Asked of the answer as written, because the palette validator drops an\n // element nobody lists and refuses a name nobody wrote in words no re-ask\n // can act on (AGL-3143).\n const disagreeing = detectDisagreeingNodes(input)\n if (disagreeing.length) {\n return { ok: false, tree: null, violations: [...disagreeing, ...publish], score: null, load: null }\n }\n const validated = validateAiNodeTree(input, AI_OUTPUT_SURFACE[outputKind], context)\n if (validated.ok === false) {\n return {\n ok: false,\n tree: null,\n violations: [\n {\n rule: null,\n code: `tree-${validated.code}`,\n message: `The answer could not be used as a ${outputKind}.`,\n detail: validated.error,\n },\n ...publish,\n ],\n score: null,\n load: null,\n }\n }\n const tree: AiDoctrineTree = {\n rootId: validated.rootId,\n nodes: validated.nodes as unknown as Record<string, AiDoctrineNode>,\n }\n // The validator's repairs name the nodes as they were written; every finding names the minted ids.\n const minted = new Map(Object.entries(validated.sourceIds).map(([id, source]) => [source, id]))\n const written = isRecord(input) && isRecord(input['nodes']) ? input['nodes'] : {}\n // What the model wrote of a node, by its minted id: the answer this check was\n // given, or what the caller says was written of a tree it stored first.\n const writtenOf = (id: string): unknown => {\n const source = validated.sourceIds[id] ?? id\n return context.writtenNode ? context.writtenNode(source) : written[source]\n }\n // A node as this check was given it, by its minted id: for a page as stored, what the page carries.\n const storedOf = (id: string): unknown => written[validated.sourceIds[id] ?? id]\n const violations = [\n ...publish,\n ...detectRepeatedSubtrees(tree, otherPages, context),\n ...detectLayoutRegions(tree, outputKind),\n ...detectInlineForms(tree, outputKind, context),\n ...detectLiteralStyles(tree, outputKind),\n ...detectInvisibleLinks(tree, outputKind),\n ...detectOffBrandEmail(tree, outputKind, context.brand),\n ...detectTypedData(tree),\n ...detectImageSources(tree, context),\n ...detectUnrelatedScreenLinks(tree, outputKind, context),\n ...detectLinksWithoutDestination(tree, outputKind, context, writtenOf, storedOf),\n ...detectDocumentStructure(tree, outputKind),\n ...detectAdHocWidths(tree, outputKind),\n ...detectUnresponsiveGrids(tree, outputKind, writtenOf),\n ...detectOffVoiceCopy(aiTreeCopy(tree, context), context.framing),\n ...detectCutLines(validated.repairs, written, (id) => minted.get(id) ?? id),\n ...detectDanglingWords(tree),\n ...detectHeavyDocument(tree, outputKind, context),\n ...detectEmptyItems(tree),\n ]\n const score = scoreAiOutput(tree, outputKind, context)\n violations.push(...detectOverBudget(score, outputKind, tree, context))\n return {\n ok: violations.length === 0,\n tree: validated,\n violations,\n score,\n load: estimateAiOutputLoad(score, outputKind),\n }\n}\n\n// ── Plans ────────────────────────────────────────────────────────────────\n\ntype RecordKind =\n | 'component'\n | 'layout'\n | 'template'\n | 'form'\n | 'dataset'\n | 'collection'\n | 'screen'\n\nconst NAME_STOPWORDS = new Set([\n 'a',\n 'an',\n 'and',\n 'the',\n 'of',\n 'for',\n 'to',\n 'our',\n 'your',\n 'my',\n 'us',\n 'we',\n 'page',\n 'pages',\n 'section',\n 'new',\n 'site',\n 'block',\n 'main',\n])\n\nfunction nameTokens(value: string): string[] {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, ' ')\n .split(' ')\n .filter(Boolean)\n .map((word) =>\n word.length > 3 && word.endsWith('s') && !word.endsWith('ss') ? word.slice(0, -1) : word,\n )\n .filter((word) => !NAME_STOPWORDS.has(word))\n}\n\n/**\n * Whether two names name the same thing: the same words once filler is\n * dropped, or every word of a name of two or more words inside the other.\n */\nexport function aiNamesMatch(left: string, right: string): boolean {\n const a = new Set(nameTokens(left))\n const b = new Set(nameTokens(right))\n if (!a.size || !b.size) return false\n const [small, large] = a.size <= b.size ? [a, b] : [b, a]\n return (\n [...small].every((word) => large.has(word)) &&\n (small.size === large.size || small.size >= 2)\n )\n}\n\nfunction inventoryKinds(inventory: AiSiteInventory | null): Map<string, RecordKind> {\n const kinds = new Map<string, RecordKind>()\n if (!inventory) return kinds\n const add = (rows: Array<{ id: string }>, kind: RecordKind) => {\n for (const row of rows) kinds.set(row.id, kind)\n }\n add(inventory.components, 'component')\n add(inventory.layouts, 'layout')\n add(inventory.templates, 'template')\n add(inventory.forms, 'form')\n add(inventory.datasets, 'dataset')\n add(inventory.collections, 'collection')\n add(inventory.screens, 'screen')\n return kinds\n}\n\n/** What a plan reference resolves to: an inventory record's kind, or a creation's. */\nfunction refKind(\n ref: string | null,\n plan: AiBuildPlan,\n kinds: Map<string, RecordKind>,\n): RecordKind | AiBuildPlanCreateKind | null {\n if (!ref) return null\n if (isAiPlanNewRef(ref)) return aiPlanCreateFor(plan, ref)?.kind ?? null\n return kinds.get(ref) ?? null\n}\n\nfunction sectionPaths(plan: AiBuildPlan) {\n return plan.screens.flatMap((screen, screenIndex) =>\n screen.sections.map((section, sectionIndex) => ({\n screen,\n screenIndex,\n section,\n path: `screens[${screenIndex}].sections[${sectionIndex}]`,\n })),\n )\n}\n\nconst LAYOUT_REGION_NAME =\n /\\b(?:site header|header|nav(?:igation)?|nav ?bar|footer|announcement(?: bar)?|cookie(?: notice| banner| consent)?|top ?bar)\\b/i\nconst FORM_SECTION_NAME =\n /\\bform\\b|\\bsign[- ]?up\\b|\\bsubscribe\\b|\\bnewsletter\\b|\\bcontact us\\b|\\b(?:get|request) a quote\\b|\\bregist(?:er|ration)\\b|\\b(?:en|in)quiry\\b/i\n\n/**\n * Rule 1 (plan): repeated items place a component, and a section two screens\n * share is one. A workspace that keeps no reusable components draws them in\n * their sections instead (AGL-3030), and nothing is refused.\n */\nexport function detectPlanRepeats(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n if (capabilities?.reusableComponents === false) return []\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const placesComponent = (uses: string[]) =>\n uses.some((ref) => refKind(ref, plan, kinds) === 'component')\n const bound = (uses: string[]) =>\n uses.some((ref) => ['dataset', 'collection'].includes(String(refKind(ref, plan, kinds))))\n const repeated = sectionPaths(plan).filter(\n ({ section }) =>\n section.items >= AI_REPEAT_MIN_COUNT && !placesComponent(section.uses) && !bound(section.uses),\n )\n if (repeated.length) {\n violations.push({\n rule: 1,\n code: 'plan-repeated-items',\n message:\n 'A section repeats items without a component. Plan one reusable component for the item, reuse one the site has, or bind the items to data.',\n paths: repeated.map((entry) => entry.path),\n })\n }\n const byName = new Map<string, ReturnType<typeof sectionPaths>>()\n for (const entry of sectionPaths(plan)) {\n const key = nameTokens(entry.section.name).join(' ')\n if (!key || LAYOUT_REGION_NAME.test(entry.section.name)) continue\n byName.set(key, [...(byName.get(key) ?? []), entry])\n }\n for (const entries of byName.values()) {\n const screens = new Set(entries.map((entry) => entry.screenIndex))\n if (screens.size < 2) continue\n const shared = entries\n .map((entry) => entry.section.uses.filter((ref) => refKind(ref, plan, kinds) === 'component'))\n .reduce((common, refs) => common.filter((ref) => refs.includes(ref)))\n if (shared.length) continue\n violations.push({\n rule: 1,\n code: 'plan-section-across-screens',\n message: `The \"${entries[0].section.name}\" section is planned on ${screens.size} screens. Plan it as one reusable component and place it on each.`,\n paths: entries.map((entry) => entry.path),\n })\n }\n return violations\n}\n\n/** The fewest sections of one item, side by side and of one kind, that are one list split apart. */\nexport const AI_SPLIT_LIST_MIN_SECTIONS = 2\n\n/** A section name's label: what comes before a colon or a spaced dash, as \"practice area\" in \"practice area: family law\". */\nconst SECTION_LABEL = /^(.+?)\\s*(?::|\\s[-–—])\\s*\\S/\n\n/** A name for many of what a name names one of. */\nfunction pluralOf(name: string): string {\n const words = name.trim()\n if (/s$/i.test(words)) return words\n return /[^aeiou]y$/i.test(words) ? `${words.slice(0, -1)}ies` : `${words}s`\n}\n\n/**\n * What kind of item a section of one item shows, for telling a list split\n * into sections apart from sections that each show one different thing: the\n * components it places, else the label its name gives the item. `null` when\n * neither says, or when the section binds its item to data.\n */\nfunction sectionItemKind(\n section: AiBuildPlanSection,\n plan: AiBuildPlan,\n kinds: Map<string, RecordKind>,\n inventory: AiSiteInventory | null,\n): { key: string; name: string; components: string[] } | null {\n if (section.uses.some((ref) => ['dataset', 'collection'].includes(String(refKind(ref, plan, kinds))))) return null\n const label = SECTION_LABEL.exec(section.name)?.[1]?.trim() ?? ''\n const components = section.uses.filter((ref) => refKind(ref, plan, kinds) === 'component')\n if (components.length) {\n const [first] = components\n const named = isAiPlanNewRef(first)\n ? aiPlanCreateFor(plan, first)?.name\n : inventory?.components.find((row) => row.id === first)?.name\n return {\n key: `component:${components.map((ref) => ref.toLowerCase()).sort().join('|')}`,\n name: pluralOf(label || named || first),\n components,\n }\n }\n const words = nameTokens(label).join(' ')\n return words ? { key: `label:${words}`, name: pluralOf(label), components: [] } : null\n}\n\n/**\n * Rule 1 (plan): a list is one section whose items repeat (AGL-3071). A\n * section's `items` counts what it repeats, so two or more sections side by\n * side that each show one item of the same kind — the same component, or a\n * name that labels the same kind of item — are one list split apart. A live\n * Free About page planned \"the four areas we practice\" as four sections of one\n * item: none was drawn from the one written-once item a repeated section is\n * built from, and the four came out in three different shapes. The re-ask\n * names the sections and gives the one section to plan instead. Where the\n * workspace keeps reusable components, a list long enough for rule 1 places\n * one for its item, so the section it gives places one too.\n *\n * Sections of several items are never joined: two lists that share a card\n * are two lists, and rule 8 counts each within its own section (AGL-3061).\n */\nexport function detectPlanSplitLists(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n plan.screens.forEach((screen, screenIndex) => {\n let run: Array<{ index: number; kind: NonNullable<ReturnType<typeof sectionItemKind>> }> = []\n const close = () => {\n if (run.length >= AI_SPLIT_LIST_MIN_SECTIONS) {\n const names = run.map(({ index }) => `\"${screen.sections[index].name}\"`)\n const listed = `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`\n const [{ kind }] = run\n // Rule 1 asks a list this long on a workspace that keeps components to place one for its item.\n const component =\n !kind.components.length && capabilities?.reusableComponents !== false && run.length >= AI_REPEAT_MIN_COUNT\n const section = { name: kind.name, uses: component ? ['new:<name>'] : kind.components, items: run.length }\n const instead = component\n ? `, placing one reusable component for the item: reuse one the site has by its id, or declare one in create and place it as new:<name>, as in ${JSON.stringify(section)}.`\n : `: ${JSON.stringify(section)}.`\n violations.push({\n rule: 1,\n code: 'plan-split-list',\n message: `The sections ${listed} each show one item of the same kind, so they are one list split apart. Plan them as one section whose ${run.length} items repeat${instead}`,\n paths: run.map(({ index }) => `screens[${screenIndex}].sections[${index}]`),\n })\n }\n run = []\n }\n screen.sections.forEach((section, index) => {\n const kind = section.items === 1 ? sectionItemKind(section, plan, kinds, inventory) : null\n if (!kind || (run.length && run[0].kind.key !== kind.key)) close()\n if (kind) run.push({ index, kind })\n })\n close()\n })\n return violations\n}\n\n/** Where the plan's sections place a record of one kind, as `screens[0].sections[1].uses[0]`. */\nfunction placementsOf(\n plan: AiBuildPlan,\n kinds: Map<string, RecordKind>,\n kind: RecordKind,\n): string[] {\n return sectionPaths(plan).flatMap(({ section, path }) =>\n section.uses.flatMap((ref, index) =>\n refKind(ref, plan, kinds) === kind ? [`${path}.uses[${index}]`] : [],\n ),\n )\n}\n\n/**\n * Rule 2 (plan): every screen declares a layout, no section is a copy of a\n * layout region, and no section places a layout, which frames a whole screen\n * (AGL-3040). A site with no layout, where this job may not create one\n * (AGL-3030), has nothing to declare: its screens name none, and a screen\n * that names none is not refused there. A screen whose layout is a `new:`\n * reference the plan never creates is refused here, and only here.\n */\nexport function detectPlanLayoutRegions(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const mayCreateLayout = !capabilities || capabilities.create.layout.allowed\n const noLayoutToName = !mayCreateLayout && !(inventory?.layouts.length ?? 0)\n const unlaid = plan.screens\n .map((screen, index) => ({ screen, index }))\n .filter(\n ({ screen }) =>\n refKind(screen.layout, plan, kinds) !== 'layout' &&\n !(noLayoutToName && screen.layout === null),\n )\n if (unlaid.length) {\n violations.push({\n rule: 2,\n code: 'plan-screen-without-layout',\n message: noLayoutToName\n ? 'A screen names a layout the site does not have, and this job may not create one. Leave the layout empty.'\n : mayCreateLayout\n ? \"A screen names no layout the site has or the plan creates. Put every screen in the site's layout, or plan one.\"\n : 'A screen names no layout the site has, and this job may not create one. Put every screen in a layout the site has.',\n paths: unlaid.map(({ index }) => `screens[${index}].layout`),\n })\n }\n const regions = sectionPaths(plan).filter(({ section }) =>\n LAYOUT_REGION_NAME.test(section.name),\n )\n if (regions.length) {\n violations.push({\n rule: 2,\n code: 'plan-layout-region-section',\n message:\n 'A screen plans its own header, navigation or footer. Those live in the layout; take the section off the screen.',\n paths: regions.map((entry) => entry.path),\n })\n }\n const placed = placementsOf(plan, kinds, 'layout')\n if (placed.length) {\n violations.push({\n rule: 2,\n code: 'plan-layout-in-section',\n message:\n \"A section places a layout. A layout frames a whole screen and is never placed inside one: name it as the screen's layout, and take it out of the section's uses.\",\n paths: placed,\n })\n }\n return violations\n}\n\n/**\n * Rule 3 (plan): a section that collects answers places a form from the Forms\n * page. A workspace that keeps no saved forms draws the form on the page\n * (AGL-3030), and nothing is refused.\n */\nexport function detectPlanInlineForms(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n if (capabilities?.reusableComponents === false) return []\n const kinds = inventoryKinds(inventory)\n const unbound = sectionPaths(plan).filter(\n ({ section }) =>\n FORM_SECTION_NAME.test(section.name) &&\n !section.uses.some((ref) => refKind(ref, plan, kinds) === 'form'),\n )\n return unbound.length\n ? [\n {\n rule: 3,\n code: 'plan-form-not-placed',\n message:\n 'A section collects answers without a form. Reuse a form from the Forms page, or plan one there, and place it by id.',\n paths: unbound.map((entry) => entry.path),\n },\n ]\n : []\n}\n\n/** Pages sharing one shape this many times are a template applied. */\nexport const AI_SIMILAR_PAGES_MIN = 3\n\n/**\n * Rule 4 (plan): three or more screens with the same sections share one\n * template, and a template is what a screen applies, never what one of its\n * sections places (AGL-3040).\n */\nexport function detectUntemplatedSimilarPages(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null = null,\n): AiDoctrineViolation[] {\n const groups = new Map<string, number[]>()\n plan.screens.forEach((screen, index) => {\n if (screen.sections.length < 2) return\n const signature = screen.sections\n .map((section) => nameTokens(section.name).join(' '))\n .join('|')\n groups.set(signature, [...(groups.get(signature) ?? []), index])\n })\n const violations: AiDoctrineViolation[] = []\n for (const indexes of groups.values()) {\n if (indexes.length < AI_SIMILAR_PAGES_MIN) continue\n const templates = new Set(indexes.map((index) => plan.screens[index].template))\n if (templates.size === 1 && !templates.has(null)) continue\n violations.push({\n rule: 4,\n code: 'plan-similar-pages',\n message: `${indexes.length} screens share one shape. Plan one template and apply it ${indexes.length} times with each page's copy, or bind it to a collection.`,\n paths: indexes.map((index) => `screens[${index}].template`),\n })\n }\n const placed = placementsOf(plan, inventoryKinds(inventory), 'template')\n if (placed.length) {\n violations.push({\n rule: 4,\n code: 'plan-template-in-section',\n message:\n \"A section places a template. A template is applied to a whole screen and is never placed inside one: take it out of the section's uses, and name it as the screen's template only when the whole screen is built from it.\",\n paths: placed,\n })\n }\n return violations\n}\n\n/** Rule 5 (plan): a color value belongs only in a theme change. */\nexport function detectPlanLiteralColors(plan: AiBuildPlan): AiDoctrineViolation[] {\n const paths: string[] = []\n plan.create.forEach((entry, index) => {\n if (entry.kind === 'theme-change') return\n if (hasLiteralColor(entry.why) || entry.fields.some(hasLiteralColor)) {\n paths.push(`create[${index}]`)\n }\n })\n for (const { section, path } of sectionPaths(plan)) {\n if (hasLiteralColor(section.name)) paths.push(path)\n }\n return paths.length\n ? [\n {\n rule: 5,\n code: 'plan-literal-color',\n message:\n 'The plan writes a color by value outside a theme change. Name theme tokens, and plan a theme change for a color the theme lacks.',\n paths,\n },\n ]\n : []\n}\n\nconst REUSE_BEFORE_CREATE_KINDS: ReadonlySet<AiBuildPlanCreateKind> = new Set([\n 'component',\n 'layout',\n 'form',\n 'dataset',\n])\n\n/** Rule 7 (plan): reuse names real records, and a creation is an exception that says why. */\nexport function detectCreateBeforeReuse(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const unknown = plan.reuse\n .map((entry, index) => ({ entry, index }))\n .filter(({ entry }) => entry.kind !== 'theme' && kinds.get(entry.id) !== entry.kind)\n if (unknown.length) {\n violations.push({\n rule: 7,\n code: 'plan-reuse-unknown',\n message:\n 'The plan reuses something the site does not have. Reuse only what the site inventory lists.',\n paths: unknown.map(({ index }) => `reuse[${index}]`),\n })\n }\n const unexplained = plan.create\n .map((entry, index) => ({ entry, index }))\n .filter(({ entry }) => !entry.why.trim())\n if (unexplained.length) {\n violations.push({\n rule: 7,\n code: 'plan-create-without-why',\n message: 'The plan creates something without saying why nothing the site has will do.',\n paths: unexplained.map(({ index }) => `create[${index}].why`),\n })\n }\n const rows: Record<string, Array<{ id: string; name: string }>> = {\n component: inventory?.components ?? [],\n layout: inventory?.layouts ?? [],\n form: inventory?.forms ?? [],\n dataset: inventory?.datasets ?? [],\n }\n plan.create.forEach((entry, index) => {\n if (!REUSE_BEFORE_CREATE_KINDS.has(entry.kind) || entry.duplicateOf) return\n const existing = rows[entry.kind].find((row) => aiNamesMatch(row.name, entry.name))\n if (!existing) return\n violations.push({\n rule: 7,\n code: 'plan-duplicates-existing',\n message: `The site already has a ${entry.kind} named \"${existing.name}\". Reuse it, or propose extending it, instead of creating \"${entry.name}\".`,\n paths: [`create[${index}]`],\n })\n })\n return violations\n}\n\n/**\n * Rule 7 (plan): a plan creates only what the request says this job may\n * create on this site (AGL-3030) — what the workspace's plan includes, what\n * the site has room for, and what the job builds itself. One violation a\n * creation, each saying why and what to do instead.\n */\nexport function detectPlanUncreatable(\n plan: AiBuildPlan,\n capabilities: AiPlanCapabilities | null,\n): AiDoctrineViolation[] {\n if (!capabilities) return []\n return aiPlanUncreatable(plan, capabilities).map((entry) => ({\n rule: 7,\n code: 'plan-create-not-allowed',\n message: entry.message,\n paths: [entry.path],\n }))\n}\n\n/**\n * What a section most likely meant by a creation it places and the plan never\n * declares, so the refusal can name the way out: a form where the reference\n * or its section reads as one and the section places no form yet, otherwise\n * a component. Only the message reads it; the reference is refused whatever\n * it was meant to be.\n */\nfunction undeclaredPlacementKind(\n name: string,\n section: AiBuildPlanSection,\n plan: AiBuildPlan,\n kinds: Map<string, RecordKind>,\n): 'form' | 'component' {\n if (FORM_SECTION_NAME.test(name)) return 'form'\n const placesForm = section.uses.some((ref) => refKind(ref, plan, kinds) === 'form')\n return FORM_SECTION_NAME.test(section.name) && !placesForm ? 'form' : 'component'\n}\n\n/**\n * Rule 7 (plan): what a plan places, it reuses or it creates (AGL-3040). The\n * doctrine has a plan refer to what it creates as new:<name>, so a reference\n * that names no entry of the create list is a creation nothing builds. A page\n * kept with one stops at its first pass, sending the member to make that\n * creation by hand, which a workspace that cannot make it never can. Each is\n * refused with the one re-ask, once a name however often it is placed, and\n * says what to do on THIS workspace: declare the creation where the job may\n * make one more of that kind, and otherwise build the page without it, drawn\n * on the page or placed from what the site has. A screen's layout is rule\n * 2's (`plan-screen-without-layout`), and is not reported twice.\n */\nexport function detectPlanUndeclaredCreations(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const byName = new Map<string, AiPlanUndeclaredRef[]>()\n for (const ref of aiPlanUndeclaredRefs(plan)) {\n if (ref.field === 'layout') continue\n const key = ref.name.toLowerCase()\n byName.set(key, [...(byName.get(key) ?? []), ref])\n }\n return [...byName.values()].map((refs): AiDoctrineViolation => {\n const [first] = refs\n const screen = plan.screens[first.screenIndex]\n const section = first.field === 'uses' ? screen.sections[first.sectionIndex] : null\n const kind: AiBuildPlanCreateKind = section\n ? undeclaredPlacementKind(first.name, section, plan, kinds)\n : 'template'\n const refused = capabilities ? aiPlanUncreatableKind(plan, kind, capabilities) : null\n const where = section\n ? `${section.name ? `The \"${section.name}\" section` : 'A section'} places a creation named \"${first.name}\", but the plan never creates it`\n : `${screen.title ? `The screen \"${screen.title}\"` : 'A screen'} applies a template named \"${first.name}\", but the plan never creates it`\n let message: string\n if (!refused) {\n const otherwise = section\n ? `place ${aiCreationNoun(kind)} the site already has by its id`\n : \"leave the screen's template empty\"\n message = `${where}. Declare it in create as ${aiCreationNoun(kind)}, with why nothing the site has will do, or ${otherwise}.`\n } else if (section) {\n message = `${where}, and ${refused.reason}. ${refused.instead} Take it out of the section's uses.`\n } else {\n message = `${where}, and ${refused.reason}. Leave the screen's template empty, or apply a template the site already has.`\n }\n return { rule: 7, code: 'plan-creation-undeclared', message, paths: refs.map((ref) => ref.path) }\n })\n}\n\n/**\n * Rule 8 (plan): long lists are bound, and a list the site already holds is\n * bound to it. Where this job may not create a dataset (AGL-3030), the way\n * out the refusal names is a shorter list rather than a dataset it would\n * only refuse next.\n */\nexport function detectPlanTypedData(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const data = [...(inventory?.datasets ?? []), ...(inventory?.collections ?? [])]\n const typed: string[] = []\n const unbound: Array<{ path: string; name: string }> = []\n for (const { section, path } of sectionPaths(plan)) {\n const bindsData = section.uses.some((ref) =>\n ['dataset', 'collection'].includes(String(refKind(ref, plan, kinds))),\n )\n if (bindsData) continue\n if (section.items >= AI_TYPED_LIST_MIN_ITEMS) typed.push(path)\n const match = data.find((row) => aiNamesMatch(row.name, section.name))\n if (match) unbound.push({ path, name: match.name })\n }\n if (typed.length) {\n violations.push({\n rule: 8,\n code: 'plan-typed-list',\n message:\n capabilities && !capabilities.create.dataset.allowed\n ? `A section plans a long list of typed-out items. Bind it to a dataset or collection the site has, or plan fewer than ${AI_TYPED_LIST_MIN_ITEMS} items.`\n : 'A section plans a long list of typed-out items. Bind it to a dataset or collection, or plan a dataset for data the site does not have yet.',\n paths: typed,\n })\n }\n if (unbound.length) {\n violations.push({\n rule: 8,\n code: 'plan-existing-data-unbound',\n message: `The site already holds \"${unbound[0].name}\" as data. Bind the section to it instead of copying it into the page.`,\n paths: unbound.map((entry) => entry.path),\n })\n }\n return violations\n}\n\nconst SLUG = /^\\/?[a-z0-9]+(?:-[a-z0-9]+)*(?:\\/[a-z0-9]+(?:-[a-z0-9]+)*)*\\/?$|^\\/$/\nexport const AI_SEO_TITLE_MAX = 70\nexport const AI_SEO_DESCRIPTION_MAX = 170\n\nfunction slugKey(slug: string): string {\n return slug.trim().toLowerCase().replace(/^\\/+|\\/+$/g, '')\n}\n\n/** Rule 10 (plan): every screen has a free, well-formed slug, an SEO title and description. */\nexport function detectMissingNavAndSeo(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n): AiDoctrineViolation[] {\n const violations: AiDoctrineViolation[] = []\n const taken = new Map(\n (inventory?.screens ?? []).map((screen) => [slugKey(screen.slug), screen.name]),\n )\n const seen = new Set<string>()\n const badSlugs: string[] = []\n const collisions: string[] = []\n const seo: string[] = []\n plan.screens.forEach((screen, index) => {\n const key = slugKey(screen.slug)\n if (!screen.slug.trim() || !SLUG.test(screen.slug.trim())) {\n badSlugs.push(`screens[${index}].slug`)\n } else if (seen.has(key) || taken.has(key)) {\n collisions.push(`screens[${index}].slug`)\n }\n seen.add(key)\n if (!screen.seoTitle || screen.seoTitle.length > AI_SEO_TITLE_MAX) {\n seo.push(`screens[${index}].seoTitle`)\n }\n if (!screen.seoDescription || screen.seoDescription.length > AI_SEO_DESCRIPTION_MAX) {\n seo.push(`screens[${index}].seoDescription`)\n }\n })\n if (badSlugs.length) {\n violations.push({\n rule: 10,\n code: 'plan-slug',\n message:\n 'A screen has no usable address. Give each one a slug of lowercase words joined by hyphens.',\n paths: badSlugs,\n })\n }\n if (collisions.length) {\n violations.push({\n rule: 10,\n code: 'plan-slug-taken',\n message:\n 'A screen reuses an address the site or the plan already uses. Give each screen its own slug.',\n paths: collisions,\n })\n }\n if (seo.length) {\n violations.push({\n rule: 10,\n code: 'plan-seo',\n message: `A screen is missing its search title or description, or runs past ${AI_SEO_TITLE_MAX} and ${AI_SEO_DESCRIPTION_MAX} characters. Write both for every screen.`,\n paths: seo,\n })\n }\n return violations\n}\n\n/** Every piece of copy a plan carries, with its path. */\nexport function aiPlanCopy(plan: AiBuildPlan): AiCopySample[] {\n const samples: AiCopySample[] = []\n plan.screens.forEach((screen, index) => {\n samples.push({ at: `screens[${index}].title`, text: screen.title })\n samples.push({ at: `screens[${index}].seoTitle`, text: screen.seoTitle })\n samples.push({ at: `screens[${index}].seoDescription`, text: screen.seoDescription })\n })\n plan.create.forEach((entry, index) => {\n samples.push({ at: `create[${index}].name`, text: entry.name })\n })\n return samples\n}\n\n/** Rule 15 (plan): a screen or template like one the site has starts as its duplicate. */\nexport function detectMissedDuplicate(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const unresolved: string[] = []\n plan.screens.forEach((screen, index) => {\n if (screen.duplicateOf) {\n if (kinds.get(screen.duplicateOf) !== 'screen') {\n unresolved.push(`screens[${index}].duplicateOf`)\n }\n return\n }\n const nearest = (inventory?.screens ?? []).find(\n (existing) => !existing.template && aiNamesMatch(existing.name, screen.title),\n )\n if (nearest) {\n violations.push({\n rule: 15,\n code: 'plan-missed-duplicate',\n message: `The site already has \"${nearest.name}\". Start the new screen from a duplicate of it, which keeps its bindings and SEO, and edit that.`,\n paths: [`screens[${index}].duplicateOf`],\n })\n }\n })\n plan.create.forEach((entry, index) => {\n if (entry.duplicateOf) {\n const kind = kinds.get(entry.duplicateOf)\n if (!kind || (kind !== entry.kind && !(entry.kind === 'template' && kind === 'screen'))) {\n unresolved.push(`create[${index}].duplicateOf`)\n }\n return\n }\n if (entry.kind !== 'template') return\n const nearest = (inventory?.templates ?? []).find((existing) =>\n aiNamesMatch(existing.name, entry.name),\n )\n if (nearest) {\n violations.push({\n rule: 15,\n code: 'plan-missed-duplicate',\n message: `The site already has the \"${nearest.name}\" template. Start from a duplicate of it and edit that.`,\n paths: [`create[${index}].duplicateOf`],\n })\n }\n })\n if (unresolved.length) {\n violations.push({\n rule: 15,\n code: 'plan-duplicate-unknown',\n message:\n 'The plan duplicates something the site does not have. Duplicate only what the site inventory lists.',\n paths: unresolved,\n })\n }\n return violations\n}\n\n/** What each exchange of a Free page job comes to at its worst, in credits. */\nexport interface AiFreePageWorstCase {\n /** The page plan. */\n plan: number\n /** The one layout a Free plan includes, built first on a site with none (AGL-3031). */\n layout: number\n /** The first section pass, which writes the cached prefix. */\n firstSection: number\n /** Each later section pass, which reads it. */\n laterSection: number\n /** A page's listing. */\n listing: number\n}\n\n/**\n * The Free taste's wall at its worst (AGL-3030, AGL-3070): each exchange of a\n * Free page job in credits, every answer at its ceiling, as\n * `jobs/ai-job-free-page.spec.ts` derives them from the page plan and the\n * layout generation measured live and the requests as they stand. The spec\n * fails when a figure it derives moves and this does not, so the section cap\n * below cannot drift from the proof.\n */\nexport const AI_FREE_PAGE_WORST_CASE_CREDITS: Readonly<AiFreePageWorstCase> = {\n plan: 83,\n layout: 64,\n firstSection: 44,\n laterSection: 20,\n listing: 3,\n}\n\n/**\n * The most sections a Free job fits in `FREE_AI_TASTE_CREDITS_PER_MONTH` at\n * its worst: the plan, the layouts it builds first, a listing for each page\n * and the first section's pass, then as many later passes as the rest pays\n * for; none when that is already past the wall. A component or a form is never\n * a Free creation, since rule 7 refuses both on a workspace that keeps no\n * reusable components, so the wall's proof measures neither.\n */\nexport function aiFreePageSectionsWithin(\n creations: { layouts: number; pages?: number },\n credits: Readonly<AiFreePageWorstCase> = AI_FREE_PAGE_WORST_CASE_CREDITS,\n): number {\n const before =\n credits.plan + creations.layouts * credits.layout + (creations.pages ?? 1) * credits.listing + credits.firstSection\n if (before > FREE_AI_TASTE_CREDITS_PER_MONTH) return 0\n return 1 + Math.floor((FREE_AI_TASTE_CREDITS_PER_MONTH - before) / credits.laterSection)\n}\n\n/**\n * The layouts a Free plan's job builds before its sections: the ones it\n * creates that the workspace may make, and on a site with no layout where it\n * may make one, the one rule 2 asks the plan to create.\n */\nfunction freePlanLayouts(plan: AiBuildPlan, inventory: AiSiteInventory | null, capabilities: AiPlanCapabilities): number {\n const refused = aiPlanUncreatable(plan, capabilities).filter((entry) => entry.kind === 'layout').length\n const creates = plan.create.filter((entry) => entry.kind === 'layout').length - refused\n const needs = !(inventory?.layouts.length ?? 0) && capabilities.create.layout.allowed ? 1 : 0\n return Math.max(creates, needs)\n}\n\n/**\n * The Free wall (plan): a plan asks for no more sections than the Free taste\n * pays for at its worst beside what the job builds first (AGL-3070). A live\n * Free plan asked for eight sections beside its layout, where the wall's worst\n * case pays for six, and fit only because every exchange ran under its\n * ceiling; one that does not runs out of credits with its page half built. The\n * cap only lowers what a plan may ask for, from the same figures the wall is\n * proven with, so no plan the proof admits is refused. It is no building rule,\n * so it names none.\n */\nexport function detectPlanOverFreeWall(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null,\n): AiDoctrineViolation[] {\n if (!capabilities?.freeTaste) return []\n const asked = plan.screens.reduce((sum, screen) => sum + screen.sections.length, 0)\n const layouts = freePlanLayouts(plan, inventory, capabilities)\n const pages = Math.max(plan.screens.length, 1)\n const fits = aiFreePageSectionsWithin({ layouts, pages })\n if (asked <= fits) return []\n const job = pages > 1 ? `a Free plan of ${pages} pages` : 'a Free page'\n const beside = layouts ? ` that creates ${layouts > 1 ? `${layouts} layouts` : 'its layout'}` : ''\n return [\n {\n rule: null,\n code: 'plan-over-free-wall',\n message: `This plan asks for ${asked} sections, and ${job}${beside} fits ${fits} in the ${FREE_AI_TASTE_CREDITS_PER_MONTH} AI credits a Free workspace has a month. Plan at most ${fits}: draw a list's repeated items in one section, and leave out a section the brief does not ask for.`,\n paths: plan.screens.map((_, index) => `screens[${index}].sections`),\n },\n ]\n}\n\n/**\n * Rule 2 (plan): a layout the plan creates lists the regions it has, and\n * every one is a region this platform builds (AGL-3024).\n *\n * A layout has no properties, so its `fields` are its REGIONS — the promise\n * the build is later held to. A word the vocabulary does not hold is refused\n * HERE, on the plan, where the re-ask costs a sentence: a promise nothing can\n * look for would otherwise reach the build as a commitment no check can\n * settle, and a build that cannot settle its own plan stops for a person\n * instead of reporting itself done.\n */\nexport function detectPlanUnreadableRegions(plan: AiBuildPlan): AiDoctrineViolation[] {\n const unreadable: Array<{ word: string; path: string }> = []\n plan.create.forEach((entry, index) => {\n if (entry.kind !== 'layout') return\n entry.fields.forEach((field, fieldIndex) => {\n if (!aiLayoutRegionOf(field)) {\n unreadable.push({ word: field, path: `create[${index}].fields[${fieldIndex}]` })\n }\n })\n })\n if (!unreadable.length) return []\n const one = unreadable.length === 1\n return [\n {\n rule: 2,\n code: 'plan-layout-region-unknown',\n message: `A layout lists ${unreadable\n .map((entry) => `\"${entry.word}\"`)\n .join(', ')} among its regions, and a layout is built out of ${AI_LAYOUT_REGION_NAMES.join(\n ', ',\n )}. Name ${one ? 'it' : 'them'} with one of those, or leave ${one ? 'it' : 'them'} off the layout.`,\n paths: unreadable.map((entry) => entry.path),\n },\n ]\n}\n\n/**\n * Every plan rule, against the site inventory the plan was made from and,\n * where the job read them, what it may create there (AGL-3030). `null`\n * capabilities restrict nothing: the doctrine applies whole.\n */\nexport function validateAiBuildPlan(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n framing: AiCopyFraming = null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n return [\n ...detectPlanRepeats(plan, inventory, capabilities),\n ...detectPlanSplitLists(plan, inventory, capabilities),\n ...detectPlanOverFreeWall(plan, inventory, capabilities),\n ...detectPlanLayoutRegions(plan, inventory, capabilities),\n ...detectPlanUnreadableRegions(plan),\n ...detectPlanInlineForms(plan, inventory, capabilities),\n ...detectUntemplatedSimilarPages(plan, inventory),\n ...detectPlanLiteralColors(plan),\n ...detectCreateBeforeReuse(plan, inventory),\n ...detectPlanUncreatable(plan, capabilities),\n ...detectPlanUndeclaredCreations(plan, inventory, capabilities),\n ...detectPlanTypedData(plan, inventory, capabilities),\n ...detectMissingNavAndSeo(plan, inventory),\n ...detectOffVoiceCopy(aiPlanCopy(plan), framing),\n ...detectMissedDuplicate(plan, inventory),\n ]\n}\n"],"names":["sanitizeAuthorHtml","formatBytes","measureNodeMap","nodeMapBytes","MEDIA_CDN_VARIANT_WIDTHS","parseMediaRef","ESTIMATED_PAGE_TRANSFER_BYTES","FREE_AI_TASTE_CREDITS_PER_MONTH","REUSABLE_INSTANCE_COMPONENT_ID","REUSABLE_INSTANCE_PROP_VALUES_KEY","parseBreakpointSpan","renderEmailHtml","aiPlanCreateFor","aiPlanUndeclaredRefs","isAiPlanNewRef","aiCreationNoun","aiPlanUncreatable","aiPlanUncreatableKind","AI_INSTANCE_REF_PROP","validateAiNodeTree","AI_PAGE_SCROLL_TO_PROP","aiPageLinkTarget","aiStoredScrollTargets","AI_EMAIL_CLIP_BYTES","AI_OUTPUT_BUDGETS","AI_OUTPUT_SURFACE","isHeadlineVariant","AI_PALETTE","AI_SX_TOKENS","AI_DOCTRINE_RULES","AI_DOCTRINE_RULE_NUMBERS","Object","keys","map","Number","aiDoctrineViolationText","violation","rule","message","isRecord","value","Array","isArray","walkTree","tree","visits","seen","Set","stack","id","rootId","depth","ancestors","length","node","pop","nodes","has","add","push","children","index","displayName","componentId","elementOf","props","hasAncestor","visit","test","some","unique","values","listNames","ids","names","join","slice","AI_REPEAT_MIN_NODES","AI_REPEAT_MIN_COUNT","AI_REPEAT_ACROSS_PAGES_MIN_NODES","AI_TYPED_LIST_MIN_ITEMS","indexShapes","shapeOf","Map","sizeOf","schema","propsSchema","properties","sort","key","declared","structural","Boolean","enum","type","String","filter","child","set","get","reduce","sum","repeatedByData","repeatedShapes","minNodes","minCount","groupOf","byShape","shape","JSON","stringify","repeated","entries","repeatedIds","flatMap","ancestorsOf","every","ancestor","detectRepeatedSubtrees","otherPages","context","reusableComponents","violations","name","code","nodeIds","elsewhere","other","otherIndex","shared","sharedIds","outermost","aiRepeatedItemCount","most","count","aiBindsRepeatedItems","REGION_ELEMENTS","REGION_WORDS","header","footer","nav","AI_LAYOUT_REGIONS","elements","componentIds","sidebar","main","AI_LAYOUT_REGION_NAMES","LAYOUT_REGION_ALIASES","masthead","navigation","menu","aside","drawer","rail","slot","content","aiLayoutRegionOf","word","read","cleaned","split","replace","toLowerCase","trim","includes","aiTreeLayoutRegions","found","element","region","where","detectLayoutRegions","outputKind","regions","entry","detectInlineForms","inline","loose","unbound","shadowed","empty","bound","inner","COLOR_SX_KEYS","COLOR_IN_VALUE_SX_KEYS","SPACING_SX_KEYS","TYPE_SX_KEYS","COLOR_KEYWORDS","LITERAL_COLOR","LENGTH_WITH_UNIT","paletteTokens","palette","hasLiteralColor","parts","part","sxValues","detectLiteralStyles","colors","lengths","raw","sx","normalizeHex","hex","detectOffBrandEmail","brand","allowed","fonts","font","offBrand","candidates","family","candidate","detectTypedData","sectionOf","reverse","find","byComponent","childId","ref","mediaValues","out","roles","propRoles","refId","componentProps","detectImageSources","hotlinked","missingAlt","alt","decorative","aiHeadingLevel","match","exec","detectDocumentStructure","headings","mains","slots","rootElement","slotElement","chosenAway","level","h1s","heading","page","skipped","previous","WIDTH_SX_KEYS","detectAdHocWidths","fixed","GRID","GRID_CONTAINER_PROPS","GRID_ROW_PROPS","GRID_ROW_DIRECTIONS","GRID_COLUMN_DIRECTION","GRID_ITEM_WRAPPERS","GRID_GAP_SX_KEYS","GRID_DEFAULT_COLUMNS","GRID_QUOTED_MAX_CHARS","writtenValueText","text","cut","gridColumns","columns","isInteger","gridItemSpan","size","span","phoneFull","steps","undefined","base","xs","breakpoint","gridItemSizeFor","items","across","Math","min","max","md","floor","sm","detectUnresponsiveGrids","written","shapes","childrenOf","isGrid","isContainer","isSized","writtenProp","unreadContainer","wrapsItems","writtenColumn","direction","setsOutRow","refused","rows","stacks","outside","texts","unsized","suggested","gapped","parentId","grandparentId","parent","sized","wrappedItem","holdsSized","isItem","setsContainerProps","within","column","offending","item","gap","spacing","first","LINK_COLOR_FAMILIES","LINK_COMPONENTS","isAiLinkElement","PAPER_COMPONENTS","FAMILY_TOKEN","familyOf","bandOf","background","token","color","linkWordsFamily","own","styledAsButton","detectInvisibleLinks","hidden","band","HOME_WORDS","detectUnrelatedScreenLinks","home","homeScreenIds","sent","screenId","linksHome","label","inNavigation","isFilled","detectLinksWithoutDestination","stored","sections","pageSections","targets","scrollTargetIds","dead","fragments","unknown","target","kind","via","inForm","wordsOf","listed","toSection","instead","PUBLISH_KEYS","detectPublishIntent","answer","paths","path","forEach","here","BRACKETED_FACT","aiBracketedFacts","facts","matchAll","fact","FILLER_COPY","JUDGMENT","detectOffVoiceCopy","samples","framing","filler","sample","judged","at","list","aiTreeCopy","LINE_PROPS","muiTypography","muiListItemText","muiCardHeader","muiAccordionSummary","emailText","LABEL_VARIANTS","DANGLING_WORDS","OPENING_WORDS","CLOSED_LINE","aiDanglingWord","line","lower","before","lineTail","words","detectDanglingWords","LABEL_PROPS","muiButton","muiScreenLink","emailButton","CUT_REPAIR","lineHead","detectCutLines","repairs","idOf","repair","nodeId","limit","shown","PURE_CONTAINERS","EMBED_COMPONENTS","DUPLICATE_SX_MIN_KEYS","DUPLICATE_SX_MIN_NODES","detectHeavyDocument","wrappers","eager","video","embeds","sxSeen","images","ownProps","boundForm","acceptsChildren","allowEmbeds","duplicatedSx","flat","ITEM_NOUNS","muiListItem","muiCard","FRAME_COMPONENTS","WORD_PROPS","muiList","muiInlineText","showsOwn","detectEmptyItems","noun","nouns","EMAIL_COLUMN_PX","MEDIA_IMAGE_PROPS","image","emailImage","collectionEntryAuthor","contentAuthorProfile","servedVariantWidth","slotWidth","widest","width","pixels","parsed","parseFloat","isFinite","imageRequests","requests","named","startsWith","assets","mediaId","sizeBytes","bytes","variant","ratio","round","scoreAiOutput","families","emailHtmlBytes","html","sanitize","TextEncoder","encode","imageBytes","imagesUnmeasured","fontFamilies","METRIC_LABELS","figure","metric","toLocaleString","heaviest","largest","a","b","BUDGET_METRICS","detectOverBudget","score","budget","offenders","estimateAiOutputLoad","pageBytes","documentBytes","totalBytes","detectDisagreeingNodes","input","reached","missing","queue","shift","orphans","detail","validateAiDoctrineTree","publish","disagreeing","ok","load","validated","error","minted","sourceIds","source","writtenOf","writtenNode","storedOf","NAME_STOPWORDS","nameTokens","endsWith","aiNamesMatch","left","right","small","large","inventoryKinds","inventory","kinds","row","components","layouts","templates","forms","datasets","collections","screens","refKind","plan","sectionPaths","screen","screenIndex","section","sectionIndex","LAYOUT_REGION_NAME","FORM_SECTION_NAME","detectPlanRepeats","capabilities","placesComponent","uses","byName","common","refs","AI_SPLIT_LIST_MIN_SECTIONS","SECTION_LABEL","pluralOf","sectionItemKind","detectPlanSplitLists","run","close","component","placementsOf","detectPlanLayoutRegions","mayCreateLayout","create","layout","noLayoutToName","unlaid","placed","detectPlanInlineForms","AI_SIMILAR_PAGES_MIN","detectUntemplatedSimilarPages","groups","signature","indexes","template","detectPlanLiteralColors","why","fields","REUSE_BEFORE_CREATE_KINDS","detectCreateBeforeReuse","reuse","unexplained","form","dataset","duplicateOf","existing","detectPlanUncreatable","undeclaredPlacementKind","placesForm","detectPlanUndeclaredCreations","field","title","otherwise","reason","detectPlanTypedData","data","typed","bindsData","SLUG","AI_SEO_TITLE_MAX","AI_SEO_DESCRIPTION_MAX","slugKey","slug","detectMissingNavAndSeo","taken","badSlugs","collisions","seo","seoTitle","seoDescription","aiPlanCopy","detectMissedDuplicate","unresolved","nearest","AI_FREE_PAGE_WORST_CASE_CREDITS","firstSection","laterSection","listing","aiFreePageSectionsWithin","creations","credits","pages","freePlanLayouts","creates","needs","detectPlanOverFreeWall","freeTaste","asked","fits","job","beside","_","detectPlanUnreadableRegions","unreadable","fieldIndex","one","validateAiBuildPlan"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/ai-doctrine-validators.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { sanitizeAuthorHtml } from '@aglyn/aglyn/app-utils/author-html'\nimport {\n formatBytes,\n measureNodeMap,\n nodeMapBytes,\n} from '@aglyn/aglyn/app-utils/measure-node-map'\nimport {\n MEDIA_CDN_VARIANT_WIDTHS,\n parseMediaRef,\n} from '@aglyn/aglyn/app-utils/media-ref'\nimport {\n ESTIMATED_PAGE_TRANSFER_BYTES,\n FREE_AI_TASTE_CREDITS_PER_MONTH,\n} from '@aglyn/aglyn/app-utils/plan-entitlements'\nimport {\n REUSABLE_INSTANCE_COMPONENT_ID,\n REUSABLE_INSTANCE_PROP_VALUES_KEY,\n} from '@aglyn/aglyn/app-utils/reusable-component-keys'\nimport { parseBreakpointSpan } from '@aglyn/shared-data-enums/breakpoint-span'\nimport { renderEmailHtml } from '@aglyn/shared-util-email/email-render'\nimport {\n aiPlanCreateFor,\n aiPlanUndeclaredRefs,\n isAiPlanNewRef,\n type AiBuildPlan,\n type AiBuildPlanCreateKind,\n type AiBuildPlanSection,\n type AiPlanUndeclaredRef,\n} from '../model/ai-build-plan'\nimport {\n aiCreationNoun,\n aiPlanUncreatable,\n aiPlanUncreatableKind,\n type AiPlanCapabilities,\n} from '../model/ai-plan-capabilities'\nimport type { AiSiteInventory } from '../model/ai-site-inventory'\nimport {\n AI_INSTANCE_REF_PROP,\n validateAiNodeTree,\n type AiNodeTreeContext,\n type AiNodeTreeResult,\n} from './ai-node-tree'\nimport { AI_PAGE_SCROLL_TO_PROP, aiPageLinkTarget, aiStoredScrollTargets } from './ai-page-links'\nimport {\n AI_EMAIL_CLIP_BYTES,\n AI_OUTPUT_BUDGETS,\n AI_OUTPUT_SURFACE,\n isHeadlineVariant,\n type AiBudgetMetric,\n type AiLoadEstimate,\n type AiOutputKind,\n} from './ai-palette'\nimport { AI_PALETTE, AI_SX_TOKENS } from './ai-palette.generated'\n\n/**\n * The building doctrine's validators (AGL-2935): the rules a generated\n * document is held to, each checked by code rather than asked of a prompt.\n *\n * A generator's system prompt carries the doctrine (`ai-doctrine.ts`), and a\n * model mostly follows it. \"Mostly\" is what these are for. Every tree and\n * every plan passes through them inside `runValidatedGeneration`; a finding\n * is a VIOLATION that names its rule and says, in a sentence a customer can\n * read, what was refused and what to do instead. The runtime re-asks the\n * model once with the findings, and stops for a person when the second\n * answer still breaks one.\n *\n * Trees are checked AFTER `validateAiNodeTree` (AGL-2905) has admitted them,\n * never instead of it: the palette validator decides what may be stored at\n * all, and these decide whether it was built the way a careful author would\n * build it. Plans are checked against the site inventory, which is where\n * \"reuse before create\" becomes checkable.\n *\n * Rule 17 is a MEASUREMENT, in the platform's existing units: the stored\n * node map in the bytes the save counts (`nodeMapBytes`), images at the size\n * the media library recorded, an email's HTML as the send path renders it,\n * and a page's load on top of the page weight the platform already measured.\n * Nothing here invents a second measure of a page.\n */\n\nexport type AiDoctrineRuleNumber =\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | 10\n | 11\n | 12\n | 13\n | 14\n | 15\n | 16\n | 17\n\n/** Each rule's title, in the words the proposal and the docs page use. */\nexport const AI_DOCTRINE_RULES: Readonly<Record<AiDoctrineRuleNumber, string>> = {\n 1: 'Repeats become one reusable component',\n 2: 'Site-wide regions live in the layout',\n 3: 'Forms are built on the Forms page, then placed',\n 4: 'Similar pages share one template',\n 5: 'Colors, spacing and type come from the theme',\n 6: 'Emails use the brand',\n 7: 'Reuse before creating',\n 8: 'Data is bound, not typed',\n 9: 'Images come from the media library, with alt text',\n 10: 'Navigation and SEO travel with a page',\n 11: 'One main landmark and an ordered outline',\n 12: \"Responsive by the theme's breakpoints\",\n 13: 'Drafts only',\n 14: 'Your voice, with no filler copy',\n 15: 'Start from a duplicate of the nearest thing',\n 16: 'The smallest document that does the job',\n 17: 'A measured budget for every output',\n}\n\nexport const AI_DOCTRINE_RULE_NUMBERS = Object.keys(AI_DOCTRINE_RULES).map(\n Number,\n) as AiDoctrineRuleNumber[]\n\nexport interface AiDoctrineViolation {\n /**\n * The rule broken; `null` when the answer could not be read as the output\n * at all, or asks for what its job does not build rather than breaking a\n * building rule.\n */\n rule: AiDoctrineRuleNumber | null\n /** Stable per finding, for specs and logs. */\n code: string\n /** One customer-safe sentence: what was refused and what to do instead. */\n message: string\n /** What the model is told beyond `message`, when the validator's own words say more. */\n detail?: string\n /** Offending nodes, by the ids of the tree that was checked. */\n nodeIds?: string[]\n /** Offending plan entries or answer fields, as `screens[1].sections[2]`. */\n paths?: string[]\n /** Rule 17: the measured figure against its budget. */\n figure?: { metric: AiBudgetMetric; value: number; budget: number }\n}\n\n/** A violation as one line: the rule's number and title, then its sentence. */\nexport function aiDoctrineViolationText(violation: AiDoctrineViolation): string {\n return violation.rule === null\n ? violation.message\n : `Rule ${violation.rule} (${AI_DOCTRINE_RULES[violation.rule]}): ${violation.message}`\n}\n\n/** Who the copy is framed for; agency and enterprise copy holds to the judgment-word rule. */\nexport type AiCopyFraming = 'agency' | 'enterprise' | null\n\n// ── Trees ────────────────────────────────────────────────────────────────\n\nexport interface AiDoctrineNode {\n componentId: string\n props?: Record<string, unknown>\n sx?: Record<string, unknown>\n nodes?: string[]\n}\n\n/** A validated flat node map, as `validateAiNodeTree` returns it. */\nexport interface AiDoctrineTree {\n rootId: string\n nodes: Record<string, AiDoctrineNode>\n}\n\n/** What a library asset records about itself, for the image weight. */\nexport interface AiAssetFacts {\n sizeBytes?: number\n width?: number\n height?: number\n}\n\nexport interface AiDoctrineTreeContext extends AiNodeTreeContext {\n /** The brand an email is held to: palette path → color, and the families. */\n brand?: { colors: Record<string, string>; fonts: string[] } | null\n /** Placed library assets by media id. */\n assets?: Record<string, AiAssetFacts>\n /** The plan named a third-party embed the brief asked for, and its cost. */\n allowEmbeds?: boolean\n framing?: AiCopyFraming\n /**\n * Whether the workspace keeps reusable components and saved forms\n * (AGL-3030). `false` builds inline, the one way such a workspace can: a\n * form is a Form holding its fields, and a repeated block is drawn where it\n * repeats. Absent is `true`, the doctrine whole.\n */\n reusableComponents?: boolean\n /**\n * The site's home screens, by id (AGL-3056): the screen a link falls back\n * to when the site has none for what it promises. Absent: none is known.\n */\n homeScreenIds?: readonly string[]\n /**\n * The node as the model wrote it, by the id the checked tree gives it\n * (AGL-3078), for a tree that was stored before it is checked: a page\n * section is checked as part of the page, whose props the palette validator\n * has already read, and a value it could not read is absent there. Absent,\n * the tree the check is given is what the model wrote.\n */\n writtenNode?: (id: string) => unknown\n /**\n * The page's sections by their names in its plan, in order, where the tree\n * is a page a plan lays out (AGL-3097). A Button or a Screen Link may then go\n * to one of them, by `scrollTo` naming it or an `href` fragment its name's\n * words make up, which the page step writes as the platform's Scroll to\n * element interaction. Absent: a link goes only where its `screenId` or\n * `href` says.\n */\n pageSections?: readonly string[]\n /**\n * The section roots of the page, by id, where the tree checked is the page as\n * the page step stores it (AGL-3097): a link there that carries a Scroll to\n * element interaction to one of them, built or still to come, goes there.\n * Only a stored page is given them. The palette validator drops every\n * interaction a model writes before anything is stored, and an answer's own\n * are never read.\n */\n scrollTargetIds?: readonly string[]\n}\n\n/** One node of a walk: its id, its depth, and its ancestors' ids from the root down. */\nexport interface Visit {\n id: string\n node: AiDoctrineNode\n depth: number\n ancestors: string[]\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Every reachable node in document order, each once. Exported for a door's\n * own checks (`extend`), which read a tree the way these detectors do.\n */\nexport function walkTree(tree: AiDoctrineTree): Visit[] {\n const visits: Visit[] = []\n const seen = new Set<string>()\n const stack: Array<{ id: string; depth: number; ancestors: string[] }> = [\n { id: tree.rootId, depth: 0, ancestors: [] },\n ]\n while (stack.length) {\n const { id, depth, ancestors } = stack.pop() as (typeof stack)[number]\n const node = tree.nodes[id]\n if (!node || seen.has(id)) continue\n seen.add(id)\n visits.push({ id, node, depth, ancestors })\n const children = node.nodes ?? []\n for (let index = children.length - 1; index >= 0; index -= 1) {\n stack.push({ id: children[index], depth: depth + 1, ancestors: [...ancestors, id] })\n }\n }\n return visits\n}\n\nfunction displayName(componentId: string): string {\n return AI_PALETTE[componentId]?.displayName ?? componentId\n}\n\n/** The HTML element a node was told to render as. */\nfunction elementOf(node: AiDoctrineNode | undefined): string {\n const value = node?.props?.['component'] ?? node?.props?.['element']\n return typeof value === 'string' ? value : ''\n}\n\nfunction hasAncestor(\n tree: AiDoctrineTree,\n visit: Visit,\n test: (node: AiDoctrineNode) => boolean,\n): boolean {\n return visit.ancestors.some((id) => {\n const node = tree.nodes[id]\n return node ? test(node) : false\n })\n}\n\nfunction unique<T>(values: T[]): T[] {\n return [...new Set(values)]\n}\n\nfunction listNames(ids: string[], tree: AiDoctrineTree): string {\n const names = unique(ids.map((id) => displayName(tree.nodes[id]?.componentId ?? '')))\n return names.length <= 1\n ? names.join('')\n : `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`\n}\n\n// Rule 1 and rule 8 read the same index: which subtrees share a shape.\n\n/** Below this, a repeat is a row of buttons, not a block worth a component. */\nexport const AI_REPEAT_MIN_NODES = 3\n/** Rule 1: a block on one page this many times is a component. */\nexport const AI_REPEAT_MIN_COUNT = 3\n/** Rule 1 across pages: a block this large on two pages is a component. */\nexport const AI_REPEAT_ACROSS_PAGES_MIN_NODES = 5\n/** Rule 8: a hand-typed list this long is data. */\nexport const AI_TYPED_LIST_MIN_ITEMS = 8\n\ninterface ShapeIndex {\n visits: Visit[]\n shapeOf: Map<string, string>\n sizeOf: Map<string, number>\n}\n\n/**\n * A subtree's shape: element ids, the prop NAMES it sets, and the values of\n * the props that change structure (enums, switches, numbers) — but never the\n * values of copy, links or media, which is what differs between the twelve\n * cards that should have been one component.\n */\nfunction indexShapes(tree: AiDoctrineTree): ShapeIndex {\n const shapeOf = new Map<string, string>()\n const sizeOf = new Map<string, number>()\n const visits = walkTree(tree)\n for (let index = visits.length - 1; index >= 0; index -= 1) {\n const { id, node } = visits[index]\n const schema = AI_PALETTE[node.componentId]?.propsSchema.properties ?? {}\n const props = Object.keys(node.props ?? {})\n .sort()\n .map((key) => {\n const declared = schema[key]\n const structural =\n Boolean(declared?.enum) ||\n declared?.type === 'boolean' ||\n declared?.type === 'number' ||\n declared?.type === 'integer'\n return structural ? `${key}=${String(node.props?.[key])}` : key\n })\n .join(',')\n const children = (node.nodes ?? []).filter((child) => shapeOf.has(child))\n shapeOf.set(\n id,\n `${node.componentId}(${props})[${children.map((child) => shapeOf.get(child)).join('|')}]`,\n )\n sizeOf.set(id, 1 + children.reduce((sum, child) => sum + (sizeOf.get(child) ?? 0), 0))\n }\n return { visits, shapeOf, sizeOf }\n}\n\n/** Whether a node sits inside a collection repeater, whose child is authored once and repeated by data. */\nfunction repeatedByData(tree: AiDoctrineTree, visit: Visit): boolean {\n return hasAncestor(tree, visit, (node) => node.componentId === 'collectionEntries')\n}\n\n/**\n * Shapes that repeat at least `minCount` times, reported only where they are\n * the outermost repeat: the header inside each of twelve cards repeats\n * because the card does, and the fix is the card. `groupOf` counts each\n * group's repeats apart; absent, the whole tree is one group.\n */\nfunction repeatedShapes(\n tree: AiDoctrineTree,\n index: ShapeIndex,\n minNodes: number,\n minCount: number,\n groupOf: (visit: Visit) => string = () => tree.rootId,\n): Array<{ shape: string; ids: string[] }> {\n const byShape = new Map<string, string[]>()\n for (const visit of index.visits) {\n if (visit.id === tree.rootId) continue\n if ((index.sizeOf.get(visit.id) ?? 0) < minNodes) continue\n if (repeatedByData(tree, visit)) continue\n const shape = JSON.stringify([groupOf(visit), index.shapeOf.get(visit.id)])\n byShape.set(shape, [...(byShape.get(shape) ?? []), visit.id])\n }\n const repeated = [...byShape.entries()].filter(([, ids]) => ids.length >= minCount)\n const repeatedIds = new Set(repeated.flatMap(([, ids]) => ids))\n const ancestorsOf = new Map(index.visits.map((visit) => [visit.id, visit.ancestors]))\n return repeated\n .filter(\n ([, ids]) =>\n !ids.every((id) => (ancestorsOf.get(id) ?? []).some((ancestor) => repeatedIds.has(ancestor))),\n )\n .map(([shape, ids]) => ({ shape, ids }))\n}\n\n/**\n * Rule 1. A block repeated on one page, or a block this page shares with\n * another page generated beside it, is one component placed as instances.\n *\n * A workspace that keeps no reusable components can place no instance, so\n * there a repeated block is drawn where it repeats, and nothing is refused.\n */\nexport function detectRepeatedSubtrees(\n tree: AiDoctrineTree,\n otherPages: readonly AiDoctrineTree[] = [],\n context: Pick<AiDoctrineTreeContext, 'reusableComponents'> = {},\n): AiDoctrineViolation[] {\n if (context.reusableComponents === false) return []\n const index = indexShapes(tree)\n const violations: AiDoctrineViolation[] = repeatedShapes(\n tree,\n index,\n AI_REPEAT_MIN_NODES,\n AI_REPEAT_MIN_COUNT,\n ).map(({ ids }) => {\n const name = displayName(tree.nodes[ids[0]].componentId)\n return {\n rule: 1,\n code: 'repeated-subtree',\n message: `The same ${name} block appears ${ids.length} times. Make it one reusable component with props for what changes, and place it ${ids.length} times.`,\n nodeIds: ids,\n }\n })\n if (otherPages.length) {\n const elsewhere = new Set<string>()\n for (const other of otherPages) {\n const otherIndex = indexShapes(other)\n for (const visit of otherIndex.visits) {\n if (visit.id === other.rootId) continue\n if ((otherIndex.sizeOf.get(visit.id) ?? 0) >= AI_REPEAT_ACROSS_PAGES_MIN_NODES) {\n elsewhere.add(otherIndex.shapeOf.get(visit.id) as string)\n }\n }\n }\n const shared = index.visits.filter(\n (visit) =>\n visit.id !== tree.rootId &&\n (index.sizeOf.get(visit.id) ?? 0) >= AI_REPEAT_ACROSS_PAGES_MIN_NODES &&\n elsewhere.has(index.shapeOf.get(visit.id) as string),\n )\n const sharedIds = new Set(shared.map((visit) => visit.id))\n const outermost = shared.filter((visit) => !visit.ancestors.some((id) => sharedIds.has(id)))\n for (const visit of outermost) {\n violations.push({\n rule: 1,\n code: 'repeated-across-pages',\n message: `This page and another share the same ${displayName(visit.node.componentId)} block. Make it one reusable component and place it on both.`,\n nodeIds: [visit.id],\n })\n }\n }\n return violations\n}\n\n/**\n * How many copies of one repeated thing a document shows, read as\n * generously as the tree allows (AGL-3024): the largest group of nodes the\n * shape index calls the same shape — the index rule 1 counts repeats with —\n * or, where a node's children outnumber that, its fan-out.\n *\n * GENEROUS ON PURPOSE. The one caller compares this against a count a plan\n * promised and speaks only when the count is SHORT, so every reading that\n * finds more items makes the check quieter, never louder: three cards whose\n * headings a hero's subtitle happens to match read as four and are let\n * through, and four cards laid out as two rows of two read as four either by\n * their shared shape or by the rows' fan-out. What it cannot do is find four\n * items in a document that holds three of everything.\n */\nexport function aiRepeatedItemCount(tree: AiDoctrineTree): number {\n const index = indexShapes(tree)\n const byShape = new Map<string, number>()\n let most = 0\n for (const visit of index.visits) {\n if (visit.id !== tree.rootId) {\n const shape = index.shapeOf.get(visit.id)\n if (shape) {\n const count = (byShape.get(shape) ?? 0) + 1\n byShape.set(shape, count)\n if (count > most) most = count\n }\n }\n const children = (visit.node.nodes ?? []).filter((id) => tree.nodes[id]).length\n if (children > most) most = children\n }\n return most\n}\n\n/** Whether a document draws its repeated items from a collection, which fills them at render. */\nexport function aiBindsRepeatedItems(tree: AiDoctrineTree): boolean {\n return walkTree(tree).some(({ node }) => node.componentId === 'collectionEntries')\n}\n\nconst REGION_ELEMENTS = new Set(['header', 'footer', 'nav'])\nconst REGION_WORDS: Record<string, string> = {\n header: 'header',\n footer: 'footer',\n nav: 'navigation',\n}\n\n/**\n * The regions a layout is built out of, and how each one is found in a tree\n * (AGL-3024): the landmark elements it may be written as, and the palette\n * elements that ARE one wherever they appear.\n *\n * A CLOSED vocabulary, because it is what a plan's promise of a region is\n * checked against: a planner naming a region outside it has promised\n * something no check can find, which the plan rules refuse rather than let\n * pass as built.\n */\nexport const AI_LAYOUT_REGIONS = {\n header: { elements: ['header'], componentIds: ['muiAppBar'] },\n nav: { elements: ['nav'], componentIds: [] },\n sidebar: { elements: ['aside'], componentIds: [] },\n main: { elements: ['main'], componentIds: ['layoutSlot'] },\n footer: { elements: ['footer'], componentIds: [] },\n} as const satisfies Record<string, { elements: readonly string[]; componentIds: readonly string[] }>\n\nexport type AiLayoutRegion = keyof typeof AI_LAYOUT_REGIONS\n\nexport const AI_LAYOUT_REGION_NAMES = Object.keys(AI_LAYOUT_REGIONS) as AiLayoutRegion[]\n\n/** The words a plan may name each region by, beyond the region's own name. */\nconst LAYOUT_REGION_ALIASES: Readonly<Record<string, AiLayoutRegion>> = {\n 'app bar': 'header',\n masthead: 'header',\n 'top bar': 'header',\n navigation: 'nav',\n 'nav bar': 'nav',\n menu: 'nav',\n aside: 'sidebar',\n 'side bar': 'sidebar',\n 'side nav': 'sidebar',\n drawer: 'sidebar',\n rail: 'sidebar',\n slot: 'main',\n 'layout slot': 'main',\n content: 'main',\n}\n\n/**\n * The region a plan's word names, or `null` for a word the vocabulary does\n * not hold.\n *\n * Read the way a recorded plan writes one. A planner names a region as\n * `header`, as `layoutSlot:slot` or as `footer:region (firm name, address)`,\n * so the name is what stands before the first colon, capitals are word\n * breaks, and a trailing \"region\" or \"area\" is filler once the whole name has\n * been tried: \"Sidebar region\", \"side-bar\" and `sidebar:links` are one thing.\n */\nexport function aiLayoutRegionOf(word: string): AiLayoutRegion | null {\n const cleaned = word\n .split(':')[0]\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, ' ')\n .trim()\n const read = (value: string): AiLayoutRegion | null =>\n (AI_LAYOUT_REGION_NAMES as string[]).includes(value)\n ? (value as AiLayoutRegion)\n : (LAYOUT_REGION_ALIASES[value] ?? null)\n if (!cleaned) return null\n return read(cleaned) ?? read(cleaned.replace(/\\s+(?:region|area)$/, ''))\n}\n\n/** Every region a built tree carries, by the elements and palette elements it holds. */\nexport function aiTreeLayoutRegions(tree: AiDoctrineTree): Set<AiLayoutRegion> {\n const found = new Set<AiLayoutRegion>()\n for (const { node } of walkTree(tree)) {\n const element = elementOf(node)\n for (const region of AI_LAYOUT_REGION_NAMES) {\n const where = AI_LAYOUT_REGIONS[region]\n if (\n (element && (where.elements as readonly string[]).includes(element)) ||\n (where.componentIds as readonly string[]).includes(node.componentId)\n ) {\n found.add(region)\n }\n }\n }\n return found\n}\n\n/**\n * Rule 2. A page carries no copy of what every page carries: an app bar, or\n * a header, navigation or footer element near the top of the document. The\n * header of an article inside the page is the article's, not the site's.\n */\nexport function detectLayoutRegions(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n if (outputKind !== 'page' && outputKind !== 'template') return []\n const found: Array<{ id: string; region: string }> = []\n for (const visit of walkTree(tree)) {\n if (visit.id === tree.rootId) continue\n if (visit.node.componentId === 'muiAppBar') {\n found.push({ id: visit.id, region: 'header' })\n continue\n }\n const element = elementOf(visit.node)\n if (\n REGION_ELEMENTS.has(element) &&\n visit.depth <= 3 &&\n !hasAncestor(tree, visit, (node) => elementOf(node) === 'article')\n ) {\n found.push({ id: visit.id, region: REGION_WORDS[element] })\n }\n }\n if (!found.length) return []\n const regions = unique(found.map((entry) => entry.region)).join(' and ')\n return [\n {\n rule: 2,\n code: 'layout-region-in-screen',\n message: `This page carries its own site ${regions}. Headers, navigation and footers live in the site's layout; put the page in the layout instead of copying them onto it.`,\n nodeIds: found.map((entry) => entry.id),\n },\n ]\n}\n\n/**\n * Rule 3. A form on a page is a Form bound by id to a form built on the\n * Forms page — fields, validation, consent and routing kept in one place.\n * Loose fields, an unbound Form, and fields drawn inside a bound Form (which\n * the page never renders: the placed form's own design replaces them) are\n * refused. A form's own design is the one place fields are drawn.\n *\n * A workspace that keeps no saved forms (AGL-3030) has no Forms page to build\n * one on, so there the form IS the page's: an unbound Form holding its Form\n * Fields, which the site's submit route collects like any other. Loose fields\n * are still refused, and so is an unbound Form with no field to send.\n */\nexport function detectInlineForms(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: Pick<AiDoctrineTreeContext, 'reusableComponents'> = {},\n): AiDoctrineViolation[] {\n if (outputKind === 'form' || outputKind === 'email') return []\n const inline = context.reusableComponents === false\n const loose: string[] = []\n const unbound: string[] = []\n const shadowed: string[] = []\n const empty: string[] = []\n const visits = walkTree(tree)\n for (const visit of visits) {\n if (\n visit.node.componentId === 'formField' &&\n !hasAncestor(tree, visit, (node) => node.componentId === 'form')\n ) {\n loose.push(visit.id)\n }\n if (visit.node.componentId === 'form') {\n const bound = visit.node.props?.['formId']\n if (typeof bound === 'string' && bound) {\n if ((visit.node.nodes ?? []).length) shadowed.push(visit.id)\n } else if (!inline) {\n unbound.push(visit.id)\n } else if (\n !visits.some(\n (inner) => inner.node.componentId === 'formField' && inner.ancestors.includes(visit.id),\n )\n ) {\n empty.push(visit.id)\n }\n }\n }\n const violations: AiDoctrineViolation[] = []\n if (inline && loose.length) {\n violations.push({\n rule: 3,\n code: 'loose-form-field',\n message:\n 'This draws form fields outside a form, where nothing sends them. Put every Form Field inside the Form it belongs to.',\n nodeIds: loose,\n })\n }\n if (empty.length) {\n violations.push({\n rule: 3,\n code: 'form-without-fields',\n message: 'This form has no field to send. Give it the Form Fields it collects.',\n nodeIds: empty,\n })\n }\n if (!inline && (loose.length || unbound.length)) {\n violations.push({\n rule: 3,\n code: 'inline-form',\n message:\n 'This draws a form inline. Build the form on the Forms page, with its fields, validation, consent and routing, then place it here by its id.',\n nodeIds: [...unbound, ...loose],\n })\n }\n if (shadowed.length) {\n violations.push({\n rule: 3,\n code: 'fields-inside-bound-form',\n message:\n 'This form is placed by its id, so its fields come from the Forms page. Remove the copies of the fields drawn inside it.',\n nodeIds: shadowed,\n })\n }\n return violations\n}\n\nconst COLOR_SX_KEYS = new Set(['color', 'bgcolor', 'backgroundColor', 'borderColor'])\nconst COLOR_IN_VALUE_SX_KEYS = new Set([\n 'border',\n 'borderTop',\n 'borderRight',\n 'borderBottom',\n 'borderLeft',\n 'boxShadow',\n])\nconst SPACING_SX_KEYS = new Set([\n 'm',\n 'mt',\n 'mr',\n 'mb',\n 'ml',\n 'mx',\n 'my',\n 'margin',\n 'marginTop',\n 'marginRight',\n 'marginBottom',\n 'marginLeft',\n 'p',\n 'pt',\n 'pr',\n 'pb',\n 'pl',\n 'px',\n 'py',\n 'padding',\n 'paddingTop',\n 'paddingRight',\n 'paddingBottom',\n 'paddingLeft',\n 'gap',\n 'rowGap',\n 'columnGap',\n])\nconst TYPE_SX_KEYS = new Set(['fontSize', 'lineHeight', 'letterSpacing'])\nconst COLOR_KEYWORDS = new Set([\n 'inherit',\n 'transparent',\n 'currentcolor',\n 'initial',\n 'unset',\n 'none',\n])\nconst LITERAL_COLOR =\n /#[0-9a-f]{3,8}\\b|\\b(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color)\\s*\\(|\\b(?:black|white|red|green|blue|yellow|orange|purple|pink|gray|grey|brown|cyan|magenta|navy|teal|maroon|olive|lime|aqua|silver|gold|indigo|violet|beige|coral|crimson|salmon|tomato|turquoise|khaki|lavender|ivory|azure)\\b/i\nconst LENGTH_WITH_UNIT = /-?\\d*\\.?\\d+\\s*(?:px|rem|em|pt|vh|vw|ch)\\b/i\nconst paletteTokens = new Set<string>(AI_SX_TOKENS.palette)\n\n/** Whether a value names a color by value rather than by theme token. */\nfunction hasLiteralColor(value: unknown): boolean {\n if (typeof value !== 'string') return false\n const parts = value\n .trim()\n .split(/\\s+/)\n .filter((part) => !paletteTokens.has(part) && !COLOR_KEYWORDS.has(part.toLowerCase()))\n return LITERAL_COLOR.test(parts.join(' '))\n}\n\n/** An `sx` value and each of its responsive values. */\nfunction sxValues(value: unknown): unknown[] {\n return isRecord(value) ? Object.values(value) : [value]\n}\n\n/**\n * Rule 5. Every color, spacing, radius and type size is a theme token. A\n * color the theme lacks is a theme change for the theme door to draft, not a\n * value written onto one element.\n */\nexport function detectLiteralStyles(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n if (outputKind === 'email') return []\n const colors: string[] = []\n const lengths: string[] = []\n for (const { id, node } of walkTree(tree)) {\n for (const [key, raw] of Object.entries(node.sx ?? {})) {\n for (const value of sxValues(raw)) {\n if ((COLOR_SX_KEYS.has(key) || COLOR_IN_VALUE_SX_KEYS.has(key)) && hasLiteralColor(value)) {\n colors.push(id)\n } else if (\n (SPACING_SX_KEYS.has(key) || key === 'borderRadius' || TYPE_SX_KEYS.has(key)) &&\n typeof value === 'string' &&\n LENGTH_WITH_UNIT.test(value)\n ) {\n lengths.push(id)\n } else if (key === 'fontSize' && typeof value === 'number' && value > 0) {\n lengths.push(id)\n }\n }\n }\n const schema = AI_PALETTE[node.componentId]?.propsSchema.properties ?? {}\n for (const [name, value] of Object.entries(node.props ?? {})) {\n if (\n /(?:^|[a-z])(?:color|Color|bgcolor)$/.test(name) &&\n !schema[name]?.enum &&\n hasLiteralColor(value)\n ) {\n colors.push(id)\n }\n }\n }\n const violations: AiDoctrineViolation[] = []\n if (colors.length) {\n violations.push({\n rule: 5,\n code: 'literal-color',\n message:\n \"This sets colors by value. Use the theme's color tokens, and propose a theme change for a color the theme does not have.\",\n nodeIds: unique(colors),\n })\n }\n if (lengths.length) {\n violations.push({\n rule: 5,\n code: 'literal-length',\n message:\n \"This sets spacing, corners or type sizes in fixed units. Use the theme's spacing scale, shape and typography styles.\",\n nodeIds: unique(lengths),\n })\n }\n return violations\n}\n\nfunction normalizeHex(value: string): string {\n const hex = value.trim().toLowerCase()\n return /^#[0-9a-f]{3}$/.test(hex)\n ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}`\n : hex\n}\n\n/**\n * Rule 6. An email is painted with the brand: its colors are the site's\n * brand colors and its fonts the brand's. A mail client cannot resolve a\n * theme token, so the brand's own values are what an email may name — and\n * with no brand recorded, the blocks' own defaults.\n */\nexport function detectOffBrandEmail(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n brand: AiDoctrineTreeContext['brand'],\n): AiDoctrineViolation[] {\n if (outputKind !== 'email') return []\n const allowed = new Set(Object.values(brand?.colors ?? {}).map(normalizeHex))\n const fonts = new Set((brand?.fonts ?? []).map((font) => font.toLowerCase()))\n const offBrand: string[] = []\n const values: string[] = []\n for (const { id, node } of walkTree(tree)) {\n const candidates: unknown[] = []\n for (const name of ['color', 'backgroundColor']) candidates.push(node.props?.[name])\n for (const [key, raw] of Object.entries(node.sx ?? {})) {\n if (COLOR_SX_KEYS.has(key)) candidates.push(...sxValues(raw))\n if (key === 'fontFamily') {\n for (const family of sxValues(raw)) {\n if (typeof family === 'string' && !fonts.has(family.trim().toLowerCase())) {\n offBrand.push(id)\n values.push(family.trim())\n }\n }\n }\n }\n for (const candidate of candidates) {\n if (typeof candidate !== 'string' || !candidate.trim()) continue\n if (!allowed.has(normalizeHex(candidate))) {\n offBrand.push(id)\n values.push(candidate.trim())\n }\n }\n }\n if (!offBrand.length) return []\n return [\n {\n rule: 6,\n code: 'off-brand-email',\n message: `This email uses ${unique(values).slice(0, 3).join(', ')}, outside the brand. Use the brand's colors and fonts so every email reads as the same sender.`,\n nodeIds: unique(offBrand),\n },\n ]\n}\n\n/**\n * Rule 8 (tree). A long list typed out item by item is data: bound to a\n * dataset or a content collection it stays current; typed, it is a copy that\n * goes stale. Instances of one component filled in side by side are the same\n * list in a component's clothes, and are counted the same way.\n *\n * A list is counted within the Section it sits in, the unit a plan counts a\n * section's items in (AGL-3061): a page's four practice areas and its four\n * steps are two short lists that happen to share a card, not one long one,\n * and a plan that kept them must not build a page this refuses. The same\n * list split across a section's columns is still one list. A tree with no\n * Section is one group.\n */\nexport function detectTypedData(tree: AiDoctrineTree): AiDoctrineViolation[] {\n const index = indexShapes(tree)\n const sectionOf = (visit: Visit): string =>\n [...visit.ancestors].reverse().find((id) => tree.nodes[id]?.componentId === 'section') ?? tree.rootId\n const violations: AiDoctrineViolation[] = repeatedShapes(\n tree,\n index,\n AI_REPEAT_MIN_NODES - 1,\n AI_TYPED_LIST_MIN_ITEMS,\n sectionOf,\n ).map(({ ids }) => ({\n rule: 8,\n code: 'typed-list',\n message: `${ids.length} ${displayName(tree.nodes[ids[0]].componentId)} items are typed out by hand. Bind the list to a dataset or content collection, or propose a dataset for data the site does not have yet.`,\n nodeIds: ids,\n }))\n for (const visit of index.visits) {\n if (repeatedByData(tree, visit) || visit.node.componentId === 'collectionEntries') continue\n const byComponent = new Map<string, string[]>()\n for (const childId of visit.node.nodes ?? []) {\n const child = tree.nodes[childId]\n const ref = child?.props?.[AI_INSTANCE_REF_PROP]\n if (child?.componentId !== REUSABLE_INSTANCE_COMPONENT_ID || typeof ref !== 'string') continue\n byComponent.set(ref, [...(byComponent.get(ref) ?? []), childId])\n }\n for (const ids of byComponent.values()) {\n if (ids.length < AI_TYPED_LIST_MIN_ITEMS) continue\n violations.push({\n rule: 8,\n code: 'typed-instances',\n message: `${ids.length} copies of one component are filled in by hand. Bind them to a dataset or content collection, or propose a dataset for data the site does not have yet.`,\n nodeIds: ids,\n })\n }\n }\n return violations\n}\n\n/**\n * An instance that fills none of the props its component declares (AGL-3024).\n *\n * Rule 1 says an instance is `\"reusableInstance\"` whose `refId` names the\n * component and whose `propValues` FILL its props, and until now nothing read\n * the second half back. A placed instance with no `propValues` is not empty on\n * the page: it renders the component's own `defaultValue` for every prop, so\n * three of them render three identical cards of placeholder text.\n *\n * MEASURED 2026-09-21 on `attorney-profile-template-v2` (`sak5ei_9Wv`), whose\n * three instances of `practice-area-card` each carried `{\"refId\": …}` and\n * nothing else. It was recorded as the component shipping placeholder content;\n * the component is correct and declares `title`, `description` and `icon` with\n * labels and descriptions. The template placed it three times and filled\n * nothing, so every attorney's page showed the same `[Practice area name]`.\n *\n * Only an instance filling NOTHING is refused. A component may declare a prop\n * whose default is right for most placements, and a partly filled instance is\n * a judgment the doctrine does not have the information to second-guess.\n */\nexport function detectUnfilledInstances(\n tree: AiDoctrineTree,\n context: Pick<AiDoctrineTreeContext, 'componentProps'>,\n): AiDoctrineViolation[] {\n const declared = context.componentProps ?? {}\n const unfilled: string[] = []\n for (const [id, node] of Object.entries(tree.nodes)) {\n if (node?.componentId !== REUSABLE_INSTANCE_COMPONENT_ID) continue\n const ref = node.props?.[AI_INSTANCE_REF_PROP]\n if (typeof ref !== 'string') continue\n const props = declared[ref]\n if (!props || !Object.keys(props).length) continue\n const values = node.props?.['propValues']\n const filled =\n typeof values === 'object' && values !== null && !Array.isArray(values)\n ? Object.keys(values as Record<string, unknown>).filter((name) => name in props)\n : []\n if (!filled.length) unfilled.push(id)\n }\n if (!unfilled.length) return []\n const first = tree.nodes[unfilled[0]]\n const ref = first?.props?.[AI_INSTANCE_REF_PROP] as string\n const names = Object.keys(declared[ref] ?? {})\n const one = unfilled.length === 1\n return [\n {\n rule: 1,\n code: 'instance-props-unfilled',\n message: `${\n one ? 'An instance places' : `${unfilled.length} instances place`\n } a component and fill none of its props, so ${\n one ? 'it shows' : 'they all show'\n } the placeholder text the component falls back to. Fill \"propValues\" with what ${\n one ? 'this one' : 'each one'\n } should say: ${names.join(', ')}.`,\n nodeIds: unfilled,\n },\n ]\n}\n\n/** The media-role props of a node, with the declared image props of an instance. */\nfunction mediaValues(\n node: AiDoctrineNode,\n context: AiNodeTreeContext,\n): Array<{ name: string; value: string }> {\n const out: Array<{ name: string; value: string }> = []\n const roles = AI_PALETTE[node.componentId]?.propRoles ?? {}\n for (const [name, value] of Object.entries(node.props ?? {})) {\n if (roles[name] === 'media' && typeof value === 'string' && value.trim()) {\n out.push({ name, value: value.trim() })\n }\n }\n const refId = node.props?.[AI_INSTANCE_REF_PROP]\n const values = node.props?.[REUSABLE_INSTANCE_PROP_VALUES_KEY]\n if (typeof refId === 'string' && isRecord(values)) {\n const declared = context.componentProps?.[refId] ?? {}\n for (const [name, value] of Object.entries(values)) {\n if (declared[name] === 'image' && typeof value === 'string' && value.trim()) {\n out.push({ name: `${REUSABLE_INSTANCE_PROP_VALUES_KEY}.${name}`, value: value.trim() })\n }\n }\n }\n return out\n}\n\n/**\n * Rule 9. Images are placed from the media library — an asset, or an empty\n * slot for the author to fill — never hot-linked from another site, and\n * every picture carries alt text (or says it is decorative).\n */\nexport function detectImageSources(\n tree: AiDoctrineTree,\n context: AiNodeTreeContext = {},\n): AiDoctrineViolation[] {\n const hotlinked: string[] = []\n const missingAlt: string[] = []\n for (const { id, node } of walkTree(tree)) {\n if (mediaValues(node, context).some(({ value }) => /^https?:\\/\\//i.test(value))) {\n hotlinked.push(id)\n }\n if (node.componentId === 'image' || node.componentId === 'emailImage') {\n const alt = node.props?.['alt']\n const decorative = node.props?.['decorative'] === true\n if (!decorative && (typeof alt !== 'string' || !alt.trim())) missingAlt.push(id)\n }\n }\n const violations: AiDoctrineViolation[] = []\n if (hotlinked.length) {\n violations.push({\n rule: 9,\n code: 'hotlinked-image',\n message:\n 'This loads images from another website. Place images from the media library, or leave the slot empty for an upload.',\n nodeIds: hotlinked,\n })\n }\n if (missingAlt.length) {\n violations.push({\n rule: 9,\n code: 'missing-alt',\n message:\n 'An image has no alt text. Describe what each picture shows, or mark a purely decorative one as decorative.',\n nodeIds: missingAlt,\n })\n }\n return violations\n}\n\n/**\n * A heading's level: the element it renders as, else the variant's own.\n * Exported for a door's own checks, which read an outline the way rule 11\n * reads a page's.\n */\nexport function aiHeadingLevel(node: AiDoctrineNode): number | null {\n if (node.componentId !== 'muiTypography') return null\n const element =\n typeof node.props?.['component'] === 'string' ? String(node.props['component']) : ''\n const match = /^h([1-6])$/.exec(element || String(node.props?.['variant'] ?? ''))\n return match ? Number(match[1]) : null\n}\n\n/**\n * Rule 11. One `main` landmark per document, and a heading outline that\n * starts at one `h1` and never skips a level. The platform places the one\n * landmark on the layout's slot, or on a page's root when it has no layout\n * (`stampDocumentLandmark`); a tree that declares two leaves it to pick the\n * wrong one. A component, a form or an email is placed inside pages, so it\n * carries no landmark of its own, and a layout carries no `h1`: every page\n * placed in it brings its own.\n */\nexport function detectDocumentStructure(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n const visits = walkTree(tree)\n const mains = visits.filter((visit) => elementOf(visit.node) === 'main').map((visit) => visit.id)\n const violations: AiDoctrineViolation[] = []\n if (outputKind === 'component' || outputKind === 'email' || outputKind === 'form') {\n if (mains.length) {\n violations.push({\n rule: 11,\n code: 'landmark-in-fragment',\n message: `A ${outputKind} is placed inside pages, so it cannot carry the main landmark. Leave the element unset.`,\n nodeIds: mains,\n })\n }\n } else if (mains.length > 1) {\n violations.push({\n rule: 11,\n code: 'multiple-main',\n message: 'This declares more than one main landmark. A page has exactly one.',\n nodeIds: mains,\n })\n }\n if (outputKind === 'layout') {\n const slots = visits.filter((visit) => visit.node.componentId === 'layoutSlot')\n const rootElement = elementOf(tree.nodes[tree.rootId])\n const slotElement = slots[0] ? elementOf(slots[0].node) : ''\n // The landmark goes on the slot, else on the root — unless an author\n // chose another element for each.\n const chosenAway =\n rootElement !== '' &&\n rootElement !== 'main' &&\n (!slots.length || (slotElement !== '' && slotElement !== 'main'))\n if (slots.length !== 1 || chosenAway) {\n violations.push({\n rule: 11,\n code: 'layout-slot',\n message:\n 'A layout has exactly one Layout Slot, where each page renders, and the slot is the main landmark.',\n nodeIds: slots.map((slot) => slot.id),\n })\n }\n }\n if (outputKind === 'email' || outputKind === 'form') return violations\n\n const headings = visits\n .map((visit) => ({ id: visit.id, level: aiHeadingLevel(visit.node) }))\n .filter((entry): entry is { id: string; level: number } => entry.level !== null)\n const h1s = headings.filter((heading) => heading.level === 1).map((heading) => heading.id)\n const page = outputKind === 'page' || outputKind === 'template'\n if (page && h1s.length !== 1) {\n violations.push({\n rule: 11,\n code: h1s.length ? 'multiple-h1' : 'missing-h1',\n message: h1s.length\n ? `This page has ${h1s.length} top-level headings. A page has one h1; make the others h2.`\n : \"This page has no top-level heading. Give the page's title one h1.\",\n nodeIds: h1s,\n })\n } else if (!page && h1s.length > (outputKind === 'layout' ? 0 : 1)) {\n violations.push({\n rule: 11,\n code: 'multiple-h1',\n message:\n outputKind === 'layout'\n ? 'A layout wraps pages that bring their own h1, so it carries none.'\n : 'A component carries at most one h1.',\n nodeIds: h1s,\n })\n }\n const skipped: string[] = []\n let previous = page ? 0 : (headings[0]?.level ?? 1) - 1\n for (const heading of headings) {\n if (heading.level > previous + 1) skipped.push(heading.id)\n previous = heading.level\n }\n if (skipped.length) {\n violations.push({\n rule: 11,\n code: 'skipped-heading',\n message:\n 'The heading outline skips a level. Step down one level at a time — an h2 before any h3.',\n nodeIds: skipped,\n })\n }\n return violations\n}\n\nconst WIDTH_SX_KEYS = new Set(['width', 'minWidth', 'maxWidth'])\n\n/**\n * Rule 12. Widths follow the theme's breakpoints and the palette's\n * responsive props — a Container's max width, a Grid's span — never a fixed\n * pixel or viewport width that holds at one screen size. An email's column\n * is fixed by the medium, and is exempt.\n */\nexport function detectAdHocWidths(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n if (outputKind === 'email') return []\n const fixed: string[] = []\n for (const { id, node } of walkTree(tree)) {\n for (const [key, raw] of Object.entries(node.sx ?? {})) {\n if (!WIDTH_SX_KEYS.has(key)) continue\n for (const value of sxValues(raw)) {\n // MUI reads a number up to 1 as a fraction of the parent.\n if (\n (typeof value === 'number' && value > 1) ||\n (typeof value === 'string' && LENGTH_WITH_UNIT.test(value))\n ) {\n fixed.push(id)\n }\n }\n }\n }\n return fixed.length\n ? [\n {\n rule: 12,\n code: 'fixed-width',\n message:\n \"This sets fixed widths. Size elements with the theme's breakpoints — a Container's max width, a Grid span, or a percentage.\",\n nodeIds: unique(fixed),\n },\n ]\n : []\n}\n\nconst GRID = 'muiGrid'\n/** A Grid's props that only a container reads; on an item they do nothing. */\nconst GRID_CONTAINER_PROPS = ['direction', 'wrap', 'spacing', 'rowSpacing', 'columnSpacing', 'columns']\n/** A container's props that set what it holds side by side, which a group that only stacks never needs. */\nconst GRID_ROW_PROPS = ['wrap', 'columns', 'columnSpacing']\n/** The directions the palette keeps for a Grid, which lays out rows. */\nconst GRID_ROW_DIRECTIONS = ['row', 'row-reverse']\n/** A direction a Stack has and a Grid does not; the palette validator drops it from a Grid. */\nconst GRID_COLUMN_DIRECTION = /^column(?:-reverse)?$/i\n/** The elements an answer wraps a container's items in, where they belong in the container itself. */\nconst GRID_ITEM_WRAPPERS = new Set(['muiBox', 'muiStack'])\n/** `sx` keys that space a container's columns outside the widths its items are sized by. */\nconst GRID_GAP_SX_KEYS = ['gap', 'columnGap']\n/** The columns a container divides a row into when it names none. */\nconst GRID_DEFAULT_COLUMNS = 12\n/** The most characters of a written value a re-ask quotes back. */\nconst GRID_QUOTED_MAX_CHARS = 24\n\n/** A value as the model wrote it, as a re-ask quotes it: text in quotes, anything else as JSON, cut short. */\nfunction writtenValueText(value: unknown): string {\n const text = typeof value === 'string' ? value : (JSON.stringify(value) ?? String(value))\n const cut = text.length > GRID_QUOTED_MAX_CHARS ? `${text.slice(0, GRID_QUOTED_MAX_CHARS)}…` : text\n return typeof value === 'string' ? `the text \"${cut}\"` : cut\n}\n\n/** A Grid's columns: its own `columns` when it names a count, else the renderer's twelve. */\nfunction gridColumns(node: AiDoctrineNode): number {\n const columns = Number(node.props?.['columns'])\n return Number.isInteger(columns) && columns > 0 ? columns : GRID_DEFAULT_COLUMNS\n}\n\n/**\n * Whether a Grid item's size is one the renderer reads, full width on a phone,\n * and whether it steps down to a column at a larger width. The size is the\n * stored string the besigner's breakpoint row writes and the Grid renderer\n * parses (`parseBreakpointSpan`): a bare span at every width, or pairs such as\n * `xs:12 md:4`.\n */\nfunction gridItemSpan(size: unknown, columns: number): { phoneFull: boolean; steps: boolean } {\n if (typeof size !== 'string' && typeof size !== 'number') return { phoneFull: false, steps: false }\n const span = parseBreakpointSpan(size)\n if (span.raw !== undefined) return { phoneFull: false, steps: false }\n if (span.base !== undefined) return { phoneFull: span.base === columns, steps: false }\n const values = span.values ?? {}\n return {\n phoneFull: values.xs === columns,\n steps: Object.entries(values).some(([breakpoint, value]) => breakpoint !== 'xs' && value !== columns),\n }\n}\n\n/** The size a container's column is asked for: full width on a phone, a row of up to four from md. */\nfunction gridItemSizeFor(items: number, columns: number): string {\n const across = Math.min(Math.max(items, 2), 4)\n const md = Math.max(1, Math.floor(columns / (items > 4 ? 3 : across)))\n const sm = Math.floor(columns / 2)\n return items >= 4 && sm !== md ? `xs:${columns} sm:${sm} md:${md}` : `xs:${columns} md:${md}`\n}\n\n/**\n * Rule 12, for a Grid (AGL-3055). The palette's Grid is one element in both\n * roles: a CONTAINER lays its direct Grid children out in columns, and an ITEM\n * takes a size. The sizes are fractions of the container's columns, so an\n * item under a Grid that is not a container is sized against nothing, and a\n * row of them stacks one under another at every width; a size that holds at\n * every width keeps a phone's columns as narrow as a desktop's; and an `sx`\n * gap on a container spaces the columns outside the widths the items were\n * sized by, so the last column wraps onto a row of its own. A live About\n * page's practice areas were the first: a Grid with no container holding three\n * items sized \"4\", one column at every width.\n *\n * A Grid that is not a container is told what to do by what it was written as\n * (AGL-3078), because one sentence does not mend every shape: a live About\n * page's section was refused twice for rule 12, with a re-ask that only ever\n * said to make the Grid a container of sized columns.\n *\n * - `grid-not-container`: a row that is not a container. A Grid that holds\n * sized Grid items, sets a prop only a row reads, or holds two or more\n * elements of one shape side by side. The rule's intent: a row of cards is a\n * container of sized items.\n * - `grid-as-stack`: any other Grid that is not a container and sets a prop\n * only a container reads, or holds two or more elements without being an\n * item: a group that only stacks, such as a heading over its text, or one\n * written with a column direction, which a Grid does not have. The re-ask\n * offers a Stack or a Box for the group, or a container of sized items.\n * - `grid-item-outside-container`: a sized Grid item that sits in another\n * element, such as a Box inside its container. A container sizes only the\n * items directly in it, so the re-ask asks to move the item there. A Box or a\n * Stack in a container that holds nothing but sized items is refused through\n * its items, not as a child of the container that is no item.\n * - `grid-container-text`: a Grid whose `container` was written as a value the\n * palette validator cannot read as true or false, such as the text \"True\". The\n * re-ask names the value as the fault.\n * - `grid-item-size`: a container's child that is not a Grid item sized full\n * width on a phone, or a container of several whose items never step down\n * to columns at a larger width.\n * - `grid-gap`: a container spaced by an `sx` gap rather than its spacing.\n *\n * Each re-ask names the Grid or its items by the model's own ids and says what\n * to write, in the size format the renderer reads. `written` is the node as\n * the model wrote it, by an id of `tree`, where that is known: the palette\n * validator reads a `container` it cannot parse, and a column direction, as\n * absent, and only what was written can name them.\n */\nexport function detectUnresponsiveGrids(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n written: (id: string) => unknown = () => undefined,\n): AiDoctrineViolation[] {\n if (outputKind === 'email' || outputKind === 'form') return []\n // Shapes are indexed only once a Grid needs its children compared.\n let shapes: ShapeIndex | null = null\n const shapeOf = (id: string): string | undefined => (shapes ??= indexShapes(tree)).shapeOf.get(id)\n const childrenOf = (id: string): string[] => (tree.nodes[id]?.nodes ?? []).filter((child) => tree.nodes[child])\n const isGrid = (id: string | undefined): boolean => id !== undefined && tree.nodes[id]?.componentId === GRID\n const isContainer = (id: string | undefined): boolean =>\n isGrid(id) && tree.nodes[id as string].props?.['container'] === true\n const isSized = (id: string): boolean => isGrid(id) && tree.nodes[id].props?.['size'] !== undefined\n const writtenProp = (id: string, name: string): unknown => {\n const node = written(id)\n return isRecord(node) && isRecord(node['props']) ? node['props'][name] : undefined\n }\n /** A `container` the model wrote that the palette validator could not read as true or false. */\n const unreadContainer = (id: string): unknown => {\n const value = writtenProp(id, 'container')\n return tree.nodes[id].props?.['container'] === undefined && value !== null ? value : undefined\n }\n /** A Box or a Stack holding nothing but sized Grid items, which belong directly in a container. */\n const wrapsItems = (id: string): boolean => {\n const children = childrenOf(id)\n return GRID_ITEM_WRAPPERS.has(tree.nodes[id].componentId) && children.length > 0 && children.every(isSized)\n }\n /** A direction the model wrote as a column, which the palette validator drops from a Grid. */\n const writtenColumn = (id: string): boolean => {\n const direction = writtenProp(id, 'direction')\n return typeof direction === 'string' && GRID_COLUMN_DIRECTION.test(direction.trim())\n }\n /** A Grid set out as a row: a row direction, a prop only a row reads, or elements of one shape. */\n const setsOutRow = (id: string, children: readonly string[]): boolean =>\n GRID_ROW_DIRECTIONS.includes(String(tree.nodes[id].props?.['direction'])) ||\n GRID_ROW_PROPS.some((name) => tree.nodes[id].props?.[name] !== undefined) ||\n (children.length >= 2 && new Set(children.map(shapeOf)).size === 1)\n\n const refused = new Set<string>()\n const rows: string[] = []\n const stacks: Array<{ id: string; column: boolean }> = []\n const outside: Array<{ id: string; within: string }> = []\n const texts: Array<{ id: string; value: unknown }> = []\n const unsized: string[] = []\n const suggested: string[] = []\n const gapped: Array<{ id: string; spacing: unknown }> = []\n for (const visit of walkTree(tree)) {\n const { id, node } = visit\n if (node.componentId !== GRID) continue\n const children = childrenOf(id)\n const [parentId, grandparentId] = [...visit.ancestors].reverse()\n const parent = parentId === undefined ? undefined : tree.nodes[parentId]\n const sized = node.props?.['size'] !== undefined\n // An item whose container sits one element above it: a Box or a Stack holding only items.\n const wrappedItem = sized && parentId !== undefined && wrapsItems(parentId) && isContainer(grandparentId)\n if (node.props?.['container'] !== true) {\n const holdsSized = children.some(isSized)\n // An item of a container, or of a Grid refused here for not being the container it is written as.\n const isItem =\n parentId !== undefined &&\n isGrid(parentId) &&\n (isContainer(parentId) ||\n childrenOf(parentId).some(isSized) ||\n (refused.has(parentId) && unreadContainer(parentId) !== undefined))\n const setsContainerProps = GRID_CONTAINER_PROPS.some((name) => node.props?.[name] !== undefined)\n if (!holdsSized && !setsContainerProps && (isItem || children.length < 2) && !wrappedItem) continue\n refused.add(id)\n const text = unreadContainer(id)\n if (text !== undefined) texts.push({ id, value: text })\n else if (holdsSized) rows.push(id)\n else if (sized && parent && parent.componentId !== GRID) outside.push({ id, within: parent.componentId })\n else if (writtenColumn(id)) stacks.push({ id, column: true })\n else if (setsOutRow(id, children)) rows.push(id)\n else stacks.push({ id, column: false })\n continue\n }\n if (wrappedItem && parent) outside.push({ id, within: parent.componentId })\n const columns = gridColumns(node)\n // The items a Box or a Stack holds for it are sized against it, and refused where they sit.\n const items = children.flatMap((child) => (wrapsItems(child) ? childrenOf(child) : [child]))\n let steps = false\n const offending: string[] = []\n for (const child of items) {\n const item = tree.nodes[child]\n const span = item.componentId === GRID ? gridItemSpan(item.props?.['size'], columns) : null\n if (!span?.phoneFull) offending.push(child)\n if (span?.steps) steps = true\n }\n if (offending.length) {\n unsized.push(...offending)\n } else if (items.length >= 2 && !steps) {\n unsized.push(...items)\n }\n if (offending.length || (items.length >= 2 && !steps)) {\n suggested.push(gridItemSizeFor(items.length, columns))\n }\n const sx = node.sx ?? {}\n const gap = GRID_GAP_SX_KEYS.find((key) => sx[key] !== undefined)\n if (gap) gapped.push({ id, spacing: sx[gap] })\n }\n const violations: AiDoctrineViolation[] = []\n if (rows.length) {\n violations.push({\n rule: 12,\n code: 'grid-not-container',\n message:\n 'A Grid lays out columns only as a container: this one is not, so what it holds stacks at every width. Set \"container\": true on it, and put each column in a Grid item sized like \"xs:12 md:4\".',\n nodeIds: unique(rows),\n })\n }\n if (stacks.length) {\n violations.push({\n rule: 12,\n code: 'grid-as-stack',\n message: `${\n stacks[0].column\n ? 'A Grid lays out rows and has no \"column\" direction, so this one only stacks what it holds.'\n : 'A Grid that is not a container lays nothing out, so this one only stacks what it holds.'\n } Use a Stack (or a Box) for a group that only stacks, such as a heading over its text, or make it a container of sized items: set \"container\": true on it, and put each column in a Grid item sized like \"xs:12 md:4\".`,\n nodeIds: unique(stacks.map((entry) => entry.id)),\n })\n }\n if (outside.length) {\n const within = displayName(outside[0].within)\n violations.push({\n rule: 12,\n code: 'grid-item-outside-container',\n message: `A Grid item is sized only by the Grid container it sits directly in, and this one sits in a ${within}, so its size does nothing and it stacks at every width. Move it directly under its Grid container, or, where it has none, put it and the items beside it in one (\"container\": true).`,\n nodeIds: unique(outside.map((entry) => entry.id)),\n })\n }\n if (texts.length) {\n const [first] = texts\n violations.push({\n rule: 12,\n code: 'grid-container-text',\n message: `This Grid's \"container\" is ${writtenValueText(first.value)}, not true, so it is not a container and what it holds stacks at every width. Write \"container\": true${\n typeof first.value === 'string' ? ', with no quotes around true' : ''\n }.`,\n nodeIds: unique(texts.map((entry) => entry.id)),\n })\n }\n if (unsized.length) {\n violations.push({\n rule: 12,\n code: 'grid-item-size',\n message: `Every child of a Grid container is a Grid item whose size is full width on a phone and steps up to columns at a larger width, written as one string. Size these like \"${suggested[0]}\", and wrap any other element in such an item.`,\n nodeIds: unique(unsized),\n })\n }\n if (gapped.length) {\n const [first] = gapped\n const spacing = typeof first.spacing === 'number' ? first.spacing : 2\n violations.push({\n rule: 12,\n code: 'grid-gap',\n message: `A Grid container's items are sized by its \"spacing\", so an sx gap pushes its last column onto a row of its own. Remove the sx gap and set \"spacing\": ${spacing}.`,\n nodeIds: gapped.map((entry) => entry.id),\n })\n }\n return violations\n}\n\n/** The palette colors a link or a button can take, and a band can be painted in. */\nconst LINK_COLOR_FAMILIES = new Set(['primary', 'secondary', 'success', 'error', 'info', 'warning'])\n/** The elements a page links with; each draws its words in its `color` unless told otherwise. */\nconst LINK_COMPONENTS = new Set(['muiButton', 'muiScreenLink'])\n\n/** Whether an element is one rule 10 holds to a destination: a Button or a Screen Link. */\nexport function isAiLinkElement(componentId: unknown): boolean {\n return typeof componentId === 'string' && LINK_COMPONENTS.has(componentId)\n}\n\n/** Surfaces that paint their own background, whatever band they sit on. */\nconst PAPER_COMPONENTS = new Set(['muiCard', 'muiPaper', 'muiAccordion', 'muiDrawer'])\n/** A palette color token of a link family: `primary.main`, `secondary.dark`. */\nconst FAMILY_TOKEN = /^([a-z]+)\\.(?:main|dark|light)$/\n\n/** The link family a color value names, if it names one. */\nfunction familyOf(value: unknown): string | null {\n const family = typeof value === 'string' ? FAMILY_TOKEN.exec(value.trim())?.[1] : undefined\n return family && LINK_COLOR_FAMILIES.has(family) ? family : null\n}\n\n/**\n * The band a node sits on: the nearest ancestor that paints a background. An\n * `sx` background in a link family's color is a band of that family, and an\n * App Bar is one in its `color`, which is primary when it names none. Any\n * other background, and every paper surface, is not.\n */\nfunction bandOf(tree: AiDoctrineTree, visit: Visit): { family: string; token: string } | null {\n for (const id of [...visit.ancestors].reverse()) {\n const node = tree.nodes[id]\n if (!node) continue\n const background = node.sx?.['bgcolor'] ?? node.sx?.['backgroundColor']\n if (background !== undefined) {\n const token = sxValues(background).find((value) => familyOf(value) !== null)\n return typeof token === 'string' ? { family: familyOf(token) as string, token: token.trim() } : null\n }\n if (node.componentId === 'muiAppBar') {\n const color = typeof node.props?.['color'] === 'string' ? node.props['color'] : 'primary'\n return LINK_COLOR_FAMILIES.has(color) ? { family: color, token: `${color}.main` } : null\n }\n if (PAPER_COMPONENTS.has(node.componentId)) return null\n }\n return null\n}\n\n/**\n * The palette family a link or a button draws its words in: its own `sx`\n * color when it sets one, else its `color` (primary when it names none). A\n * link told to inherit takes the band's own, and a contained button draws its\n * label in the family's contrast text on a fill of its own.\n */\nfunction linkWordsFamily(node: AiDoctrineNode): string | null {\n const own = node.sx?.['color']\n if (own !== undefined) {\n return sxValues(own).map(familyOf).find((family) => family !== null) ?? null\n }\n const color = typeof node.props?.['color'] === 'string' ? node.props['color'] : 'primary'\n if (!LINK_COLOR_FAMILIES.has(color)) return null\n const styledAsButton = node.componentId === 'muiButton' || node.props?.['renderAs'] !== 'link'\n return styledAsButton && node.props?.['variant'] === 'contained' ? null : color\n}\n\n/**\n * Rule 5, for a link on a colored band (AGL-3056). The doctrine asks for\n * palette tokens, and a band in `primary.main` holding a Screen Link that\n * sets no color is two valid tokens: but the link keeps the theme's primary\n * color, so its words are navy on navy. A live About page's footer was the\n * first, a \"Request a Consultation\" link on a primary band. A link or a button\n * whose words are drawn in the family of the band it sits on is refused, with\n * a re-ask to inherit the band's contrast text or to set it.\n */\nexport function detectInvisibleLinks(tree: AiDoctrineTree, outputKind: AiOutputKind): AiDoctrineViolation[] {\n if (outputKind === 'email' || outputKind === 'form') return []\n const hidden: Array<{ id: string; family: string; token: string }> = []\n for (const visit of walkTree(tree)) {\n if (!LINK_COMPONENTS.has(visit.node.componentId)) continue\n const family = linkWordsFamily(visit.node)\n const band = family ? bandOf(tree, visit) : null\n if (band && band.family === family) hidden.push({ id: visit.id, ...band })\n }\n if (!hidden.length) return []\n const [first] = hidden\n return [\n {\n rule: 5,\n code: 'link-color-on-band',\n message: `A link or button on a ${first.token} band draws its words in the theme's ${first.family} color, the band's own, so they cannot be read. Give it \"color\": \"inherit\" under a band whose sx color is ${first.family}.contrastText, or set its own sx color to ${first.family}.contrastText.`,\n nodeIds: unique(hidden.map((entry) => entry.id)),\n },\n ]\n}\n\n/** A link's words that say it goes home. */\nconst HOME_WORDS = /\\bhome(?:\\s?page)?\\b/i\n\n/**\n * Rule 10, for a link sent where the site has nothing for it (AGL-3056). A\n * link whose purpose the site has no screen for is left out; it never goes to\n * a screen that does something else. The site inventory cannot say what each\n * screen is for, but it can name the one a model falls back to: a live About\n * page's footer sent \"Request a Consultation\" to the home screen, because the\n * site had no consultation screen. So a Screen Link or a Button, outside the\n * header and the navigation, that links the home screen with words that do\n * not say home is refused, with a re-ask to link the screen that does what it\n * says, or to leave the link out.\n */\nexport function detectUnrelatedScreenLinks(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: Pick<AiDoctrineTreeContext, 'homeScreenIds'> = {},\n): AiDoctrineViolation[] {\n if (outputKind === 'email' || outputKind === 'form') return []\n const home = new Set(context.homeScreenIds ?? [])\n const sent: Array<{ id: string; label: string }> = []\n for (const visit of walkTree(tree)) {\n const { node } = visit\n if (!LINK_COMPONENTS.has(node.componentId)) continue\n const screenId = node.props?.['screenId']\n const linksHome = (typeof screenId === 'string' && home.has(screenId)) || node.props?.['href'] === '/'\n const label = typeof node.props?.['children'] === 'string' ? node.props['children'].trim() : ''\n if (!linksHome || !label || HOME_WORDS.test(label)) continue\n // The header and the navigation link home by name and by the site's own brand.\n const inNavigation = hasAncestor(\n tree,\n visit,\n (ancestor) => ancestor.componentId === 'muiAppBar' || ['header', 'nav'].includes(elementOf(ancestor)),\n )\n if (!inNavigation) sent.push({ id: visit.id, label })\n }\n if (!sent.length) return []\n return [\n {\n rule: 10,\n code: 'link-unrelated-screen',\n message: `\"${sent[0].label}\" links the home page, which does not do what its words say. Link the screen that does, or leave the link out when the site has none.`,\n nodeIds: unique(sent.map((entry) => entry.id)),\n },\n ]\n}\n\n/** A prop value with something in it: a destination, or words. */\nfunction isFilled(value: unknown): boolean {\n return typeof value === 'string' && value.trim() !== ''\n}\n\n/**\n * Rule 10, for a link that goes nowhere (AGL-3072). A Button or a Screen Link\n * goes where its `screenId` or its `href` says, and those are the only\n * destinations either element carries: the palette validator keeps a\n * `screenId` the site has, and an `href` that is a path on the site, an\n * `https:` address or a binding the caller admitted. Nothing else can stand\n * in for one. A form is sent by the button the Form draws from its own\n * `submitLabel`, the elements a page places carry no id an anchor could name\n * (AGL-2867), and a generated node sets no interaction. So a link with\n * neither is a dead control: a live About page's hero carried a \"Request a\n * Consultation\" button with no destination. It is refused, with a re-ask\n * naming its words and what it may link.\n *\n * On a page a plan lays out (`context.pageSections`), a link may also go to a\n * section of the same page (AGL-3097). A live hero's re-ask was answered with\n * \"#consultation-form\", an anchor to the form the plan places last, and the\n * page stopped at its first section. A link that names a section, by\n * `scrollTo` or by a fragment that section's name's words make up, goes\n * there, and the page step writes the platform's Scroll to element\n * interaction for it. On a page as stored (`context.scrollTargetIds`), a link\n * carrying that interaction to one of its section roots goes there. Two\n * faults get a sentence of their own:\n *\n * - `link-fragment`: an `href` fragment that names no section. The palette\n * validator drops it, so what the link was written with goes nowhere.\n * - `scroll-target-unknown`: a `scrollTo` naming no section of the page.\n *\n * `written` is the node as the model wrote it and `stored` the node as the\n * check was given it, each by an id of `tree`.\n */\nexport function detectLinksWithoutDestination(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: Pick<AiDoctrineTreeContext, 'pageSections' | 'scrollTargetIds'> = {},\n written: (id: string) => unknown = () => undefined,\n stored: (id: string) => unknown = () => undefined,\n): AiDoctrineViolation[] {\n if (outputKind === 'email' || outputKind === 'form') return []\n const sections = context.pageSections ?? []\n const targets = new Set(context.scrollTargetIds ?? [])\n const dead: Array<{ id: string; label: string; inForm: boolean }> = []\n const fragments: Array<{ id: string; label: string; value: string }> = []\n const unknown: Array<{ id: string; label: string; value: string }> = []\n for (const visit of walkTree(tree)) {\n const { node } = visit\n if (!LINK_COMPONENTS.has(node.componentId)) continue\n if (isFilled(node.props?.['screenId']) || isFilled(node.props?.['href'])) continue\n if (aiStoredScrollTargets(stored(visit.id)).some((target) => targets.has(target))) continue\n const label = typeof node.props?.['children'] === 'string' ? node.props['children'].trim() : ''\n const target = aiPageLinkTarget(written(visit.id), sections)\n if (target?.kind === 'section') continue\n if (target?.kind === 'unknown' && target.via === 'href') {\n fragments.push({ id: visit.id, label, value: target.value })\n } else if (target?.kind === 'unknown' && context.pageSections) {\n unknown.push({ id: visit.id, label, value: target.value })\n } else {\n dead.push({ id: visit.id, label, inForm: hasAncestor(tree, visit, (ancestor) => ancestor.componentId === 'form') })\n }\n }\n const wordsOf = (entry: { id: string; label: string }): string =>\n entry.label ? `\"${entry.label}\"` : `A ${displayName(tree.nodes[entry.id].componentId)}`\n const names = sections.map((name) => `\"${name}\"`)\n const listed = names.length > 1 ? `${names.slice(0, -1).join(', ')} or ${names[names.length - 1]}` : names.join('')\n const toSection = `To take a visitor to a section of this page, set \"${AI_PAGE_SCROLL_TO_PROP}\" to that section's name in the plan: ${listed}.`\n const violations: AiDoctrineViolation[] = []\n if (fragments.length) {\n const [first] = fragments\n violations.push({\n rule: 10,\n code: 'link-fragment',\n message: `${wordsOf(first)} links \"${first.value}\", an anchor, and no element on a page carries an id an anchor could name, so it goes nowhere. ${\n context.pageSections\n ? `${toSection} Otherwise give it the \"screenId\" of a screen the site has that does what its words say, or take it out.`\n : 'Give it the \"screenId\" of a screen the site has that does what its words say, or an \"href\" that is a path on this site or an https: address the brief gives, or take it out.'\n }`,\n nodeIds: unique(fragments.map((entry) => entry.id)),\n })\n }\n if (unknown.length) {\n const [first] = unknown\n violations.push({\n rule: 10,\n code: 'scroll-target-unknown',\n message: `${wordsOf(first)} scrolls to \"${first.value}\", and this page has no section of that name. Set \"${AI_PAGE_SCROLL_TO_PROP}\" to one of its sections' names in the plan: ${listed}, or take the link out.`,\n nodeIds: unique(unknown.map((entry) => entry.id)),\n })\n }\n if (dead.length) {\n const [first] = dead\n const instead = dead.some((entry) => entry.inForm)\n ? ' A Form draws its own send button from its \"submitLabel\", so take out a button drawn inside one and set that label instead.'\n : context.pageSections\n ? ` ${toSection} When none of these fits, take it out.`\n : ' When the site has no page for it, take it out: a form on this page is sent by its own button, and no element can be reached by an anchor.'\n violations.push({\n rule: 10,\n code: 'link-without-destination',\n message: `${wordsOf(first)} goes nowhere. Give it the \"screenId\" of a screen the site has that does what its words say, or an \"href\" that is a path on this site or an https: address the brief gives.${instead}`,\n nodeIds: unique(dead.map((entry) => entry.id)),\n })\n }\n return violations\n}\n\n/** Answer fields that say \"publish\", wherever the answer put them. */\nconst PUBLISH_KEYS = /^(?:publish|published|publishNow|publishAt|goLive|isLive|live|makeLive)$/i\n\n/**\n * Rule 13. The AI writes drafts. An answer that asks for anything to be\n * published, or to go live, is refused whatever else it got right; nothing\n * downstream reads such a field, and the refusal is what keeps a future\n * reader from starting to.\n */\nexport function detectPublishIntent(answer: unknown): AiDoctrineViolation[] {\n const paths: string[] = []\n const visit = (value: unknown, path: string, depth: number) => {\n if (depth > 12 || paths.length >= 5) return\n if (Array.isArray(value)) {\n value.forEach((inner, index) => visit(inner, `${path}[${index}]`, depth + 1))\n return\n }\n if (!isRecord(value)) return\n for (const [key, inner] of Object.entries(value)) {\n const here = path ? `${path}.${key}` : key\n // An element's props and styles are page content, not instructions.\n if (key === 'props' || key === 'sx') continue\n if (\n PUBLISH_KEYS.test(key) &&\n inner !== false &&\n inner !== null &&\n inner !== undefined &&\n inner !== ''\n ) {\n paths.push(here)\n } else if (\n key === 'status' &&\n typeof inner === 'string' &&\n /^(?:published|live|public)$/i.test(inner.trim())\n ) {\n paths.push(here)\n } else {\n visit(inner, here, depth + 1)\n }\n }\n }\n visit(answer, '', 0)\n return paths.length\n ? [\n {\n rule: 13,\n code: 'publish-intent',\n message:\n 'The answer asked to publish. Everything the AI builds is a new draft; review it and publish it yourself.',\n paths,\n },\n ]\n : []\n}\n\n/** A fact the brief never gave, marked in square brackets: `[Office phone number]`. */\nconst BRACKETED_FACT = /\\[([^[\\]{}\\n]{1,80})\\]/g\n\n/**\n * The facts in square brackets copy holds (rule 14), each once whatever its\n * case, in the order they first appear, as the copy spells them\n * (AGL-3056): what a member fills in before a draft is published.\n */\nexport function aiBracketedFacts(texts: Iterable<string>): string[] {\n const facts = new Map<string, string>()\n for (const text of texts) {\n for (const match of text.matchAll(BRACKETED_FACT)) {\n const fact = match[1].trim()\n if (fact && !facts.has(fact.toLowerCase())) facts.set(fact.toLowerCase(), `[${fact}]`)\n }\n }\n return [...facts.values()]\n}\n\n/**\n * Filler that stands in for copy. A bracketed marker for a fact the brief\n * never gave — `[phone number]` — is deliberately NOT here: it is the honest\n * alternative to inventing the fact, and refusing it would push the re-ask\n * toward a made-up number.\n */\nconst FILLER_COPY =\n /\\blorem\\b|\\bipsum\\b|\\bdolor sit\\b|\\b(?:your|insert|add) (?:text|copy|content|headline|title|description|tagline) here\\b|\\b(?:placeholder|sample|dummy|filler) (?:text|copy|content)\\b|\\b(?:text|copy|content) goes here\\b/i\nconst JUDGMENT =\n /\\b(?:simply|obviously|no-brainer|cheap|effortless(?:ly)?|dead simple|super easy|just (?:a|one) click)\\b/i\n\nexport interface AiCopySample {\n /** A node id for a tree, a path for a plan. */\n at: string\n text: string\n}\n\n/**\n * Rule 14. Copy in the site's voice: no lorem ipsum or \"your text here\"\n * filler, and — for copy framed for agencies and enterprises — no words that\n * judge the reader's work as simple or cheap.\n */\nexport function detectOffVoiceCopy(\n samples: readonly AiCopySample[],\n framing: AiCopyFraming = null,\n): AiDoctrineViolation[] {\n const filler = samples.filter((sample) => FILLER_COPY.test(sample.text))\n const judged =\n framing === 'agency' || framing === 'enterprise'\n ? samples.filter((sample) => JUDGMENT.test(sample.text))\n : []\n const at = (list: readonly AiCopySample[]) => {\n const ids = unique(list.map((sample) => sample.at))\n const paths = ids.filter((id) => /[.[\\]]/.test(id))\n const nodeIds = ids.filter((id) => !/[.[\\]]/.test(id))\n return { ...(nodeIds.length ? { nodeIds } : {}), ...(paths.length ? { paths } : {}) }\n }\n const violations: AiDoctrineViolation[] = []\n if (filler.length) {\n violations.push({\n rule: 14,\n code: 'filler-copy',\n message:\n \"This leaves filler copy. Write the real words in the site's voice, from what the brief and the site already say.\",\n ...at(filler),\n })\n }\n if (judged.length) {\n violations.push({\n rule: 14,\n code: 'judgment-words',\n message:\n 'This copy calls the work simple or cheap, which reads as a judgment to an agency or enterprise audience. Say what it does instead.',\n ...at(judged),\n })\n }\n return violations\n}\n\n/** Every piece of copy a tree carries, with the node it sits on. */\nexport function aiTreeCopy(\n tree: AiDoctrineTree,\n context: AiNodeTreeContext = {},\n): AiCopySample[] {\n const samples: AiCopySample[] = []\n for (const { id, node } of walkTree(tree)) {\n const roles = AI_PALETTE[node.componentId]?.propRoles ?? {}\n for (const [name, value] of Object.entries(node.props ?? {})) {\n if (roles[name] === 'text' && typeof value === 'string' && value.trim()) {\n samples.push({ at: id, text: value })\n }\n }\n const refId = node.props?.[AI_INSTANCE_REF_PROP]\n const values = node.props?.[REUSABLE_INSTANCE_PROP_VALUES_KEY]\n if (typeof refId === 'string' && isRecord(values)) {\n const declared = context.componentProps?.[refId] ?? {}\n for (const [name, value] of Object.entries(values)) {\n const type = declared[name] ?? 'text'\n if ((type === 'text' || type === 'richText') && typeof value === 'string') {\n samples.push({ at: id, text: value })\n }\n }\n }\n }\n return samples\n}\n\n/**\n * The props a heading, a subhead or a body text shows as a line a reader\n * reads, by element. A button's or a link's label, a form field's label, a\n * run of inline text inside a sentence and every accessible name are not\n * lines, and how they end is not held.\n */\nconst LINE_PROPS: Readonly<Record<string, readonly string[]>> = {\n muiTypography: ['children'],\n muiListItemText: ['primary', 'secondary'],\n muiCardHeader: ['title', 'subheader'],\n muiAccordionSummary: ['children'],\n emailText: ['children'],\n}\n\n/** Text styles that label rather than say: a caption, an overline, a micro label. */\nconst LABEL_VARIANTS = new Set(['caption', 'overline', 'micro'])\n\n/**\n * Words no finished line ends on: an article, or a conjunction that joins two\n * parts. \"a\" counts only in lowercase, since \"Plan A\" ends on a name.\n */\nconst DANGLING_WORDS = new Set(['an', 'the', 'and', 'or', 'but', 'nor', '&'])\n\n/**\n * Words that open a phrase. A title may end on one it strands, as \"What we\n * help with\" does, but a line that ends on one right after a comma or a dash\n * opened a phrase it never wrote: \"…that matter most, with\".\n */\nconst OPENING_WORDS = new Set([\n 'about',\n 'across',\n 'after',\n 'against',\n 'along',\n 'among',\n 'as',\n 'at',\n 'because',\n 'before',\n 'between',\n 'by',\n 'for',\n 'from',\n 'if',\n 'in',\n 'into',\n 'like',\n 'of',\n 'on',\n 'onto',\n 'since',\n 'so',\n 'than',\n 'that',\n 'through',\n 'to',\n 'toward',\n 'towards',\n 'unless',\n 'until',\n 'upon',\n 'via',\n 'when',\n 'where',\n 'whereas',\n 'while',\n 'with',\n 'within',\n 'without',\n])\n\n/** A line that closes itself: a sentence's end, a closing quote or bracket, or a colon that introduces what follows. */\nconst CLOSED_LINE = /[.!?…:;\"'”’»)\\]]$/\n\n/**\n * The word a line ends on when that word leaves it unfinished (AGL-3072), or\n * `null`. A line that closes itself, ends on a binding or a bracketed fact the\n * member fills, or ends on any other word, is finished as far as a check can\n * tell. Exported for the specs that hold the closed list.\n */\nexport function aiDanglingWord(line: string): string | null {\n const text = line.trim()\n if (!text || CLOSED_LINE.test(text)) return null\n const word = /(?:^|[^A-Za-z&'’])([A-Za-z]+|&)$/.exec(text)?.[1]\n if (!word) return null\n const lower = word.toLowerCase()\n if (word === 'a' || DANGLING_WORDS.has(lower)) return word\n // A comma, a semicolon or a dash breaks the line before the word; the hyphen\n // of \"Drop-in\" or \"Add-on\" joins one word and breaks nothing.\n const before = text.slice(0, text.length - word.length)\n return OPENING_WORDS.has(lower) && /(?:[,;—–]|\\s-)\\s*$/.test(before) ? word : null\n}\n\n/** The last words of a line, as a re-ask quotes them. */\nfunction lineTail(line: string): string {\n const words = line.trim().split(/\\s+/)\n return words.length > 6 ? `…${words.slice(-6).join(' ')}` : words.join(' ')\n}\n\n/**\n * Rule 14, for a line cut short (AGL-3072). Copy in the site's voice is\n * finished copy: a heading, a subhead or a body text that ends on an article\n * or a joining conjunction, or on a word that opens a phrase right after a\n * comma, with no closing punctuation, reads as a sentence cut off mid-thought.\n * A live About page's hero subhead ended \"…that matter most, with\". A closed\n * list of words, on the lines a reader reads, keeps it deterministic: a\n * label, a button, a caption and a bracketed fact are never held to it.\n */\nexport function detectDanglingWords(tree: AiDoctrineTree): AiDoctrineViolation[] {\n const found: Array<{ id: string; line: string; word: string }> = []\n for (const { id, node } of walkTree(tree)) {\n const props = LINE_PROPS[node.componentId]\n if (!props) continue\n if (node.componentId === 'muiTypography' && LABEL_VARIANTS.has(String(node.props?.['variant'] ?? ''))) continue\n if (node.componentId === 'emailText' && node.props?.['variant'] === 'caption') continue\n for (const name of props) {\n const line = node.props?.[name]\n const word = typeof line === 'string' ? aiDanglingWord(line) : null\n if (word) found.push({ id, line: line as string, word })\n }\n }\n if (!found.length) return []\n const [first] = found\n return [\n {\n rule: 14,\n code: 'dangling-word',\n message: `\"${lineTail(first.line)}\" has no closing punctuation, and its last word, \"${first.word}\", leaves the sentence unfinished. Finish the sentence, or end the line before \"${first.word}\".`,\n nodeIds: unique(found.map((entry) => entry.id)),\n },\n ]\n}\n\n/** The labels a button or a link shows, beside the lines: cut, they read as broken too. */\nconst LABEL_PROPS: Readonly<Record<string, readonly string[]>> = {\n muiButton: ['children'],\n muiScreenLink: ['children'],\n emailButton: ['children'],\n}\n\n/** The line the palette validator writes when it cuts a prop at its ceiling. */\nconst CUT_REPAIR = /^(.+)\\.([A-Za-z0-9_]+) was over (\\d+) characters; truncated$/\n\n/** The first words of a line, as a re-ask quotes them. */\nfunction lineHead(line: string): string {\n const words = line.trim().split(/\\s+/)\n return words.length > 8 ? `${words.slice(0, 8).join(' ')}…` : words.join(' ')\n}\n\n/**\n * Rule 14, for a line cut at its ceiling (AGL-3076). The palette validator\n * holds copy to a ceiling for its role and cuts what runs past it, and says so\n * only in its repairs. A cut line is unfinished wherever the cut falls, after\n * a word or inside one, and a heading style's ceiling of\n * `AI_TEXT_LIMITS.headline` characters is one the catalog never shows a model:\n * a live About page's hero subhead, a Typography in the h5 style, was cut at\n * 120 characters to \"…that matter most, with\". So a heading, a subhead, a body\n * line, or a button's or a link's label the validator cut is refused, with a\n * re-ask naming the ceiling.\n *\n * `repairs` are the palette validator's, naming nodes by the ids of the tree\n * it was given, `written`; `idOf` turns such an id into the id the violation\n * names.\n */\nexport function detectCutLines(\n repairs: readonly string[],\n written: Readonly<Record<string, unknown>>,\n idOf: (id: string) => string = (id) => id,\n): AiDoctrineViolation[] {\n const cut: Array<{ id: string; line: string; limit: number; heading: boolean }> = []\n for (const repair of repairs) {\n const match = CUT_REPAIR.exec(repair)\n if (!match) continue\n const [, nodeId, name, limit] = match\n const node = written[nodeId]\n if (!isRecord(node) || typeof node['componentId'] !== 'string') continue\n const props = isRecord(node['props']) ? node['props'] : {}\n const shown = LINE_PROPS[node['componentId']] ?? LABEL_PROPS[node['componentId']] ?? []\n const line = props[name]\n if (!shown.includes(name) || typeof line !== 'string') continue\n cut.push({\n id: idOf(nodeId),\n line,\n limit: Number(limit),\n heading: node['componentId'] === 'muiTypography' && isHeadlineVariant(props['variant']),\n })\n }\n if (!cut.length) return []\n const [first] = cut\n const message = first.heading\n ? `A line in a heading style holds at most ${first.limit} characters, and \"${lineHead(first.line)}\" runs past them, so it was cut off where they end. Write it whole within ${first.limit} characters, or give a longer line a subtitle or body style.`\n : `\"${lineHead(first.line)}\" runs past the ${first.limit} characters its element holds, so it was cut off where they end. Write it whole within ${first.limit} characters.`\n return [{ rule: 14, code: 'copy-cut-at-ceiling', message, nodeIds: unique(cut.map((entry) => entry.id)) }]\n}\n\nconst PURE_CONTAINERS = new Set(['muiBox', 'muiStack', 'muiContainer', 'muiGrid', 'section'])\nconst EMBED_COMPONENTS = new Set(['videoEmbed', 'custom-html', 'functionWidget'])\nconst DUPLICATE_SX_MIN_KEYS = 2\nconst DUPLICATE_SX_MIN_NODES = 4\n\n/**\n * Rule 16. The flattest tree that renders the design: no container that\n * wraps one other container and adds nothing, no empty containers, no inline\n * style repeated where a token or a component prop would carry it, no font\n * beyond the theme's, images lazy below the first, video by poster rather\n * than autoplay, and no third-party embed the plan did not name.\n */\nexport function detectHeavyDocument(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext = {},\n): AiDoctrineViolation[] {\n const visits = walkTree(tree)\n const wrappers: string[] = []\n const empty: string[] = []\n const fonts: string[] = []\n const eager: string[] = []\n const video: string[] = []\n const embeds: string[] = []\n const sxSeen = new Map<string, string[]>()\n let images = 0\n for (const { id, node } of visits) {\n const entry = AI_PALETTE[node.componentId]\n const children = (node.nodes ?? []).filter((child) => tree.nodes[child])\n const ownProps = Object.entries(node.props ?? {}).filter(\n ([name, value]) => !(name === 'component' && value === 'div'),\n )\n if (\n id !== tree.rootId &&\n PURE_CONTAINERS.has(node.componentId) &&\n children.length === 1 &&\n PURE_CONTAINERS.has(tree.nodes[children[0]].componentId) &&\n !ownProps.length &&\n !Object.keys(node.sx ?? {}).length\n ) {\n wrappers.push(id)\n }\n const boundForm = node.componentId === 'form' && typeof node.props?.['formId'] === 'string'\n if (entry?.acceptsChildren && !children.length && !boundForm) empty.push(id)\n if (outputKind !== 'email' && node.sx?.['fontFamily'] !== undefined) fonts.push(id)\n if (node.componentId === 'image') {\n images += 1\n if (images > 1 && node.props?.['loading'] === 'eager') eager.push(id)\n }\n if (\n node.componentId === 'video' &&\n (node.props?.['autoPlay'] === true ||\n node.props?.['preload'] === 'auto' ||\n (typeof node.props?.['src'] === 'string' && node.props['src'] && !node.props?.['poster']))\n ) {\n video.push(id)\n }\n if (EMBED_COMPONENTS.has(node.componentId) && !context.allowEmbeds) embeds.push(id)\n const sx = node.sx ?? {}\n if (Object.keys(sx).length >= DUPLICATE_SX_MIN_KEYS) {\n const key = JSON.stringify(Object.keys(sx).sort().map((name) => [name, sx[name]]))\n sxSeen.set(key, [...(sxSeen.get(key) ?? []), id])\n }\n }\n const duplicatedSx = [...sxSeen.values()]\n .filter((ids) => ids.length >= DUPLICATE_SX_MIN_NODES)\n .flat()\n const violations: AiDoctrineViolation[] = []\n const add = (code: string, ids: string[], message: string) => {\n if (ids.length) violations.push({ rule: 16, code, message, nodeIds: ids })\n }\n add(\n 'wrapper-in-wrapper',\n wrappers,\n 'A container wraps a single container and adds nothing. Remove the outer one.',\n )\n add('empty-container', empty, 'An element meant to hold content is empty. Remove it, or fill it.')\n add(\n 'duplicated-inline-style',\n duplicatedSx,\n 'The same inline style repeats across elements. Carry it in a theme token or a component prop, once.',\n )\n add('extra-font', fonts, \"This names a font the theme does not load. Use the theme's typography.\")\n add(\n 'eager-image',\n eager,\n 'An image below the first loads eagerly. Leave loading unset so images further down the page load when they are reached.',\n )\n add(\n 'autoplay-video',\n video,\n 'A video loads its file before anyone plays it. Give it a poster, and let it play on click.',\n )\n add(\n 'third-party-embed',\n embeds,\n 'This embeds a third-party player or script, which loads its own code on every visit. Use a Video from the media library, or name the embed and its cost in the plan.',\n )\n return violations\n}\n\n/** The items a list or a row of cards repeats, as a re-ask names them. */\nconst ITEM_NOUNS: Readonly<Record<string, string>> = { muiListItem: 'list item', muiCard: 'card' }\n\n/** Elements that frame or space what they hold and show nothing of their own. */\nconst FRAME_COMPONENTS = new Set([\n 'div',\n 'section',\n 'muiBox',\n 'muiStack',\n 'muiContainer',\n 'muiGrid',\n 'muiPaper',\n 'muiCard',\n 'muiCardContent',\n 'muiCardActions',\n 'muiListItem',\n 'muiAccordion',\n 'muiAccordionDetails',\n])\n\n/** Elements that show only their words, by the props that hold them. */\nconst WORD_PROPS: Readonly<Record<string, readonly string[]>> = {\n ...LINE_PROPS,\n muiList: ['subheader'],\n muiInlineText: ['children'],\n muiButton: ['children'],\n muiScreenLink: ['children'],\n}\n\n/** Whether a node shows anything of its own: its words, or whatever an element that is neither a frame nor words draws. */\nfunction showsOwn(node: AiDoctrineNode): boolean {\n const words = WORD_PROPS[node.componentId]\n if (words) return words.some((name) => isFilled(node.props?.[name]))\n return !FRAME_COMPONENTS.has(node.componentId)\n}\n\n/**\n * Rule 16, for an item with nothing in it (AGL-3072). A list item or a card\n * that holds elements, none of which shows a word, a picture or anything\n * else, is an empty row or an empty box on the page: a live About page's list\n * of estate planning services ended on a List Item whose List Item Text had\n * no words. An item that holds no element at all is `empty-container`'s, and\n * is not reported twice.\n */\nexport function detectEmptyItems(tree: AiDoctrineTree): AiDoctrineViolation[] {\n const empty: Array<{ id: string; noun: string }> = []\n for (const { id, node } of walkTree(tree)) {\n const noun = ITEM_NOUNS[node.componentId]\n if (!noun || !(node.nodes ?? []).some((child) => tree.nodes[child])) continue\n if (!walkTree({ rootId: id, nodes: tree.nodes }).some((inner) => showsOwn(inner.node))) {\n empty.push({ id, noun })\n }\n }\n if (!empty.length) return []\n const nouns = unique(empty.map((entry) => entry.noun))\n const message =\n nouns.length > 1\n ? 'A list item and a card hold nothing to read or see. Give each its words, or take it out.'\n : nouns[0] === 'list item'\n ? 'A list item holds no words, so its row shows empty. Write the words of its List Item Text, or take the item out.'\n : 'A card holds nothing to read or see. Give it its words, or take the card out.'\n return [{ rule: 16, code: 'empty-item', message, nodeIds: empty.map((entry) => entry.id) }]\n}\n\n// ── Rule 17: the budget, measured ────────────────────────────────────────\n\nexport interface AiOutputScore {\n nodes: number\n /** The stored node map, in the save's own bytes. */\n bytes: number\n /** What the placed library images request, from their recorded sizes. */\n imageBytes: number\n /** Placed images the media library could not size: hot-linked, or no facts supplied. */\n imagesUnmeasured: number\n embeds: number\n fontFamilies: number\n /** An email's rendered HTML; `null` for every other output. */\n emailHtmlBytes: number | null\n}\n\nconst EMAIL_COLUMN_PX = 600\nconst MEDIA_IMAGE_PROPS: Record<string, readonly string[]> = {\n image: ['src'],\n emailImage: ['src'],\n video: ['poster'],\n collectionEntryAuthor: ['image'],\n contentAuthorProfile: ['image'],\n}\n\n/** The variant a slot of this width is served. */\nfunction servedVariantWidth(slotWidth: number | null): number {\n const widest = MEDIA_CDN_VARIANT_WIDTHS[MEDIA_CDN_VARIANT_WIDTHS.length - 1]\n if (!slotWidth) return widest\n return MEDIA_CDN_VARIANT_WIDTHS.find((width) => width >= slotWidth) ?? widest\n}\n\nfunction pixels(value: unknown): number | null {\n const parsed = typeof value === 'number' ? value : Number.parseFloat(String(value ?? ''))\n return Number.isFinite(parsed) && parsed > 0 ? parsed : null\n}\n\nfunction imageRequests(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext,\n): Array<{ id: string; bytes: number | null }> {\n const requests: Array<{ id: string; bytes: number | null }> = []\n for (const { id, node } of walkTree(tree)) {\n const named = MEDIA_IMAGE_PROPS[node.componentId] ?? []\n const values = mediaValues(node, context).filter(\n ({ name }) =>\n named.includes(name) || name.startsWith(`${REUSABLE_INSTANCE_PROP_VALUES_KEY}.`),\n )\n for (const { value } of values) {\n const ref = parseMediaRef(value)\n const facts = ref ? context.assets?.[ref.mediaId] : undefined\n if (!facts?.sizeBytes) {\n requests.push({ id, bytes: null })\n continue\n }\n const slot = pixels(node.props?.['width'])\n const variant = servedVariantWidth(\n outputKind === 'email' ? Math.min(slot ?? EMAIL_COLUMN_PX, EMAIL_COLUMN_PX) : slot,\n )\n // A variant is the original scaled down, so its bytes scale with its\n // area; a variant wider than the original is the original.\n const ratio = facts.width ? Math.min(1, variant / facts.width) : 1\n requests.push({ id, bytes: Math.round(facts.sizeBytes * ratio * ratio) })\n }\n }\n return requests\n}\n\n/** The rule-17 measurements of one validated tree. */\nexport function scoreAiOutput(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext = {},\n): AiOutputScore {\n const visits = walkTree(tree)\n const images = imageRequests(tree, outputKind, context)\n const families = new Set<string>()\n for (const { node } of visits) {\n for (const family of sxValues(node.sx?.['fontFamily'])) {\n if (typeof family === 'string' && family.trim()) families.add(family.trim().toLowerCase())\n }\n }\n let emailHtmlBytes: number | null = null\n if (outputKind === 'email') {\n const { html } = renderEmailHtml({\n nodes: tree.nodes as Parameters<typeof renderEmailHtml>[0]['nodes'],\n rootId: tree.rootId,\n sanitize: (value: string) => sanitizeAuthorHtml(value),\n })\n emailHtmlBytes = new TextEncoder().encode(html).length\n }\n return {\n nodes: visits.length,\n bytes: nodeMapBytes(tree.nodes),\n imageBytes: images.reduce((sum, image) => sum + (image.bytes ?? 0), 0),\n imagesUnmeasured: images.filter((image) => image.bytes === null).length,\n embeds: visits.filter(({ node }) => EMBED_COMPONENTS.has(node.componentId)).length,\n fontFamilies: families.size,\n emailHtmlBytes,\n }\n}\n\nconst METRIC_LABELS: Record<AiBudgetMetric, string> = {\n nodes: 'elements',\n bytes: 'stored size',\n imageBytes: 'image weight',\n embeds: 'third-party embeds',\n fontFamilies: 'extra font families',\n emailHtmlBytes: `rendered size (mail clients clip past ${formatBytes(AI_EMAIL_CLIP_BYTES)})`,\n}\n\nfunction figure(metric: AiBudgetMetric, value: number): string {\n return metric === 'nodes' || metric === 'embeds' || metric === 'fontFamilies'\n ? value.toLocaleString('en-US')\n : formatBytes(value)\n}\n\n/** The parts of a tree that weigh most under one metric, heaviest first. */\nfunction heaviest(\n metric: AiBudgetMetric,\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext,\n): string[] {\n switch (metric) {\n case 'bytes':\n case 'emailHtmlBytes':\n return measureNodeMap(tree.nodes).largest.map((entry) => entry.id)\n case 'nodes': {\n const index = indexShapes(tree)\n return index.visits\n .filter((visit) => visit.depth >= 1 && visit.depth <= 2)\n .sort((a, b) => (index.sizeOf.get(b.id) ?? 0) - (index.sizeOf.get(a.id) ?? 0))\n .slice(0, 3)\n .map((visit) => visit.id)\n }\n case 'imageBytes':\n return imageRequests(tree, outputKind, context)\n .filter((image) => image.bytes !== null)\n .sort((a, b) => (b.bytes ?? 0) - (a.bytes ?? 0))\n .slice(0, 3)\n .map((image) => image.id)\n case 'embeds':\n return walkTree(tree)\n .filter(({ node }) => EMBED_COMPONENTS.has(node.componentId))\n .map((visit) => visit.id)\n case 'fontFamilies':\n return walkTree(tree)\n .filter(({ node }) => node.sx?.['fontFamily'] !== undefined)\n .map((visit) => visit.id)\n }\n}\n\nconst BUDGET_METRICS: readonly AiBudgetMetric[] = [\n 'nodes',\n 'bytes',\n 'imageBytes',\n 'embeds',\n 'fontFamilies',\n 'emailHtmlBytes',\n]\n\n/**\n * Rule 17. An output over its kind's budget is refused with the figure, the\n * budget and the heaviest parts named, so the re-ask knows where to cut.\n */\nexport function detectOverBudget(\n score: AiOutputScore,\n outputKind: AiOutputKind,\n tree: AiDoctrineTree,\n context: AiDoctrineTreeContext = {},\n): AiDoctrineViolation[] {\n const budget = AI_OUTPUT_BUDGETS[outputKind]\n const violations: AiDoctrineViolation[] = []\n for (const metric of BUDGET_METRICS) {\n const value = score[metric]\n const limit = budget[metric]\n if (value === null || limit === undefined || value <= limit) continue\n const offenders = heaviest(metric, tree, outputKind, context)\n const parts = offenders.length ? ` The heaviest parts: ${listNames(offenders, tree)}.` : ''\n violations.push({\n rule: 17,\n code: `over-budget-${metric}`,\n message: `This ${outputKind} measures ${figure(metric, value)} of ${METRIC_LABELS[metric]} against a budget of ${figure(metric, limit)}.${parts}`,\n nodeIds: offenders,\n figure: { metric, value, budget: limit },\n })\n }\n return violations\n}\n\n/**\n * What a first visit to a generated output is estimated to transfer.\n *\n * The page half is a MEASUREMENT the platform already holds, not a guess:\n * `ESTIMATED_PAGE_TRANSFER_BYTES` is the first-party weight a published page\n * measured at settle, which `check:page-view-rate` holds against the\n * tenant page budget and the bandwidth meter is priced from. The tenant's\n * real-user vitals (`web-vitals-rum.ts`) report to analytics per visit and\n * are not readable for a draft nobody has visited, so they are not a second\n * source here. On top of that weight go this output's own stored document\n * and the images it places. A component or a layout reports what it adds to\n * a page; an email is not a page load and has none.\n */\nexport function estimateAiOutputLoad(\n score: AiOutputScore,\n outputKind: AiOutputKind,\n): AiLoadEstimate | null {\n if (outputKind === 'email') return null\n const pageBytes =\n outputKind === 'page' || outputKind === 'template' ? ESTIMATED_PAGE_TRANSFER_BYTES : 0\n return {\n pageBytes,\n documentBytes: score.bytes,\n imageBytes: score.imageBytes,\n imagesUnmeasured: score.imagesUnmeasured,\n embeds: score.embeds,\n totalBytes: Math.round(pageBytes + score.bytes + score.imageBytes),\n }\n}\n\n/**\n * A NODE MAP THAT DOES NOT AGREE WITH ITSELF (AGL-3143).\n *\n * A flat node map is two halves that have to match: what each node lists\n * under `nodes`, and what the map holds. A model writing one section in one\n * pass gets them out of step in two ways, and neither reaches it as\n * something it can act on.\n *\n * An element written but listed by nobody is dropped on the way in, so the\n * container that should have held it reads as empty and the answer comes\n * back \"an element meant to hold content is empty — remove it, or fill it\".\n * The content is already written; it is one line away from being placed, and\n * the re-ask does not say so. A live page build was told exactly that of a\n * card grid whose repeated card it had written and not placed; it answered by\n * naming four children and writing one.\n *\n * Which is the other half: a name listed under `nodes` that the map never\n * holds. That one is refused, but by the sanitizer under the palette\n * validator, as `Missing node \"card2\"` — which the door turns into \"the\n * answer could not be used as a section\", with no rule, no node and nothing\n * to change. It cost that page its last attempt and the build stopped three\n * sections in, so the page's form — the thing being measured — was never\n * reached at all.\n *\n * Both are read off the tree AS THE MODEL WROTE IT, before the palette\n * validator drops anything, so a re-ask can quote the node at fault.\n */\nexport function detectDisagreeingNodes(input: unknown): AiDoctrineViolation[] {\n if (!isRecord(input) || typeof input['rootId'] !== 'string' || !isRecord(input['nodes'])) return []\n const rootId = input['rootId']\n const nodes = input['nodes']\n if (!isRecord(nodes[rootId])) return []\n const childrenOf = (id: string): string[] => {\n const node = nodes[id]\n const listed = isRecord(node) ? node['nodes'] : undefined\n return Array.isArray(listed) ? listed.filter((child): child is string => typeof child === 'string') : []\n }\n const reached = new Set<string>([rootId])\n const missing = new Map<string, string[]>()\n const queue = [rootId]\n while (queue.length) {\n const id = queue.shift() as string\n for (const child of childrenOf(id)) {\n if (!isRecord(nodes[child])) {\n missing.set(id, [...(missing.get(id) ?? []), child])\n continue\n }\n if (reached.has(child)) continue\n reached.add(child)\n queue.push(child)\n }\n }\n const orphans = Object.keys(nodes).filter((id) => !reached.has(id) && isRecord(nodes[id]))\n const violations: AiDoctrineViolation[] = []\n if (missing.size) {\n const named = unique([...missing.values()].flat())\n violations.push({\n rule: null,\n code: 'missing-child',\n message:\n 'This holds elements that were never written, so the answer could not be read. Write each one, or take its name out of the list of what this holds.',\n detail: `Listed under \"nodes\" and missing from the answer: ${named.map((id) => `\"${id}\"`).join(', ')}.`,\n nodeIds: [...missing.keys()],\n })\n }\n if (orphans.length) {\n violations.push({\n rule: 16,\n code: 'orphan-node',\n message:\n 'This element was written, but nothing holds it, so none of it reaches the page. List it under the element it belongs in, or take it out.',\n nodeIds: orphans,\n })\n }\n return violations\n}\n\nexport interface AiDoctrineTreeReport {\n ok: boolean\n /** The palette validator's result: the tree to store, its repairs and its id map. */\n tree: Extract<AiNodeTreeResult, { ok: true }> | null\n violations: AiDoctrineViolation[]\n score: AiOutputScore | null\n load: AiLoadEstimate | null\n}\n\n/**\n * The whole check on one emitted tree: the palette validator first, then\n * every tree rule, then the budget. `otherPages` are the trees generated\n * beside this one, for the across-pages half of rule 1.\n */\nexport function validateAiDoctrineTree(\n input: unknown,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext = {},\n otherPages: readonly AiDoctrineTree[] = [],\n): AiDoctrineTreeReport {\n const publish = detectPublishIntent(input)\n // Asked of the answer as written, because the palette validator drops an\n // element nobody lists and refuses a name nobody wrote in words no re-ask\n // can act on (AGL-3143).\n const disagreeing = detectDisagreeingNodes(input)\n if (disagreeing.length) {\n return { ok: false, tree: null, violations: [...disagreeing, ...publish], score: null, load: null }\n }\n const validated = validateAiNodeTree(input, AI_OUTPUT_SURFACE[outputKind], context)\n if (validated.ok === false) {\n return {\n ok: false,\n tree: null,\n violations: [\n {\n rule: null,\n code: `tree-${validated.code}`,\n message: `The answer could not be used as a ${outputKind}.`,\n detail: validated.error,\n },\n ...publish,\n ],\n score: null,\n load: null,\n }\n }\n const tree: AiDoctrineTree = {\n rootId: validated.rootId,\n nodes: validated.nodes as unknown as Record<string, AiDoctrineNode>,\n }\n // The validator's repairs name the nodes as they were written; every finding names the minted ids.\n const minted = new Map(Object.entries(validated.sourceIds).map(([id, source]) => [source, id]))\n const written = isRecord(input) && isRecord(input['nodes']) ? input['nodes'] : {}\n // What the model wrote of a node, by its minted id: the answer this check was\n // given, or what the caller says was written of a tree it stored first.\n const writtenOf = (id: string): unknown => {\n const source = validated.sourceIds[id] ?? id\n return context.writtenNode ? context.writtenNode(source) : written[source]\n }\n // A node as this check was given it, by its minted id: for a page as stored, what the page carries.\n const storedOf = (id: string): unknown => written[validated.sourceIds[id] ?? id]\n const violations = [\n ...publish,\n ...detectRepeatedSubtrees(tree, otherPages, context),\n ...detectLayoutRegions(tree, outputKind),\n ...detectInlineForms(tree, outputKind, context),\n ...detectLiteralStyles(tree, outputKind),\n ...detectInvisibleLinks(tree, outputKind),\n ...detectOffBrandEmail(tree, outputKind, context.brand),\n ...detectTypedData(tree),\n ...detectUnfilledInstances(tree, context),\n ...detectImageSources(tree, context),\n ...detectUnrelatedScreenLinks(tree, outputKind, context),\n ...detectLinksWithoutDestination(tree, outputKind, context, writtenOf, storedOf),\n ...detectDocumentStructure(tree, outputKind),\n ...detectAdHocWidths(tree, outputKind),\n ...detectUnresponsiveGrids(tree, outputKind, writtenOf),\n ...detectOffVoiceCopy(aiTreeCopy(tree, context), context.framing),\n ...detectCutLines(validated.repairs, written, (id) => minted.get(id) ?? id),\n ...detectDanglingWords(tree),\n ...detectHeavyDocument(tree, outputKind, context),\n ...detectEmptyItems(tree),\n ]\n const score = scoreAiOutput(tree, outputKind, context)\n violations.push(...detectOverBudget(score, outputKind, tree, context))\n return {\n ok: violations.length === 0,\n tree: validated,\n violations,\n score,\n load: estimateAiOutputLoad(score, outputKind),\n }\n}\n\n// ── Plans ────────────────────────────────────────────────────────────────\n\ntype RecordKind =\n | 'component'\n | 'layout'\n | 'template'\n | 'form'\n | 'dataset'\n | 'collection'\n | 'screen'\n\nconst NAME_STOPWORDS = new Set([\n 'a',\n 'an',\n 'and',\n 'the',\n 'of',\n 'for',\n 'to',\n 'our',\n 'your',\n 'my',\n 'us',\n 'we',\n 'page',\n 'pages',\n 'section',\n 'new',\n 'site',\n 'block',\n 'main',\n])\n\nfunction nameTokens(value: string): string[] {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, ' ')\n .split(' ')\n .filter(Boolean)\n .map((word) =>\n word.length > 3 && word.endsWith('s') && !word.endsWith('ss') ? word.slice(0, -1) : word,\n )\n .filter((word) => !NAME_STOPWORDS.has(word))\n}\n\n/**\n * Whether two names name the same thing: the same words once filler is\n * dropped, or every word of a name of two or more words inside the other.\n */\nexport function aiNamesMatch(left: string, right: string): boolean {\n const a = new Set(nameTokens(left))\n const b = new Set(nameTokens(right))\n if (!a.size || !b.size) return false\n const [small, large] = a.size <= b.size ? [a, b] : [b, a]\n return (\n [...small].every((word) => large.has(word)) &&\n (small.size === large.size || small.size >= 2)\n )\n}\n\nfunction inventoryKinds(inventory: AiSiteInventory | null): Map<string, RecordKind> {\n const kinds = new Map<string, RecordKind>()\n if (!inventory) return kinds\n const add = (rows: Array<{ id: string }>, kind: RecordKind) => {\n for (const row of rows) kinds.set(row.id, kind)\n }\n add(inventory.components, 'component')\n add(inventory.layouts, 'layout')\n add(inventory.templates, 'template')\n add(inventory.forms, 'form')\n add(inventory.datasets, 'dataset')\n add(inventory.collections, 'collection')\n add(inventory.screens, 'screen')\n return kinds\n}\n\n/** What a plan reference resolves to: an inventory record's kind, or a creation's. */\nfunction refKind(\n ref: string | null,\n plan: AiBuildPlan,\n kinds: Map<string, RecordKind>,\n): RecordKind | AiBuildPlanCreateKind | null {\n if (!ref) return null\n if (isAiPlanNewRef(ref)) return aiPlanCreateFor(plan, ref)?.kind ?? null\n return kinds.get(ref) ?? null\n}\n\nfunction sectionPaths(plan: AiBuildPlan) {\n return plan.screens.flatMap((screen, screenIndex) =>\n screen.sections.map((section, sectionIndex) => ({\n screen,\n screenIndex,\n section,\n path: `screens[${screenIndex}].sections[${sectionIndex}]`,\n })),\n )\n}\n\nconst LAYOUT_REGION_NAME =\n /\\b(?:site header|header|nav(?:igation)?|nav ?bar|footer|announcement(?: bar)?|cookie(?: notice| banner| consent)?|top ?bar)\\b/i\nconst FORM_SECTION_NAME =\n /\\bform\\b|\\bsign[- ]?up\\b|\\bsubscribe\\b|\\bnewsletter\\b|\\bcontact us\\b|\\b(?:get|request) a quote\\b|\\bregist(?:er|ration)\\b|\\b(?:en|in)quiry\\b/i\n\n/**\n * Rule 1 (plan): repeated items place a component, and a section two screens\n * share is one. A workspace that keeps no reusable components draws them in\n * their sections instead (AGL-3030), and nothing is refused.\n */\nexport function detectPlanRepeats(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n if (capabilities?.reusableComponents === false) return []\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const placesComponent = (uses: string[]) =>\n uses.some((ref) => refKind(ref, plan, kinds) === 'component')\n const bound = (uses: string[]) =>\n uses.some((ref) => ['dataset', 'collection'].includes(String(refKind(ref, plan, kinds))))\n const repeated = sectionPaths(plan).filter(\n ({ section }) =>\n section.items >= AI_REPEAT_MIN_COUNT && !placesComponent(section.uses) && !bound(section.uses),\n )\n if (repeated.length) {\n violations.push({\n rule: 1,\n code: 'plan-repeated-items',\n message:\n 'A section repeats items without a component. Plan one reusable component for the item, reuse one the site has, or bind the items to data.',\n paths: repeated.map((entry) => entry.path),\n })\n }\n const byName = new Map<string, ReturnType<typeof sectionPaths>>()\n for (const entry of sectionPaths(plan)) {\n const key = nameTokens(entry.section.name).join(' ')\n if (!key || LAYOUT_REGION_NAME.test(entry.section.name)) continue\n byName.set(key, [...(byName.get(key) ?? []), entry])\n }\n for (const entries of byName.values()) {\n const screens = new Set(entries.map((entry) => entry.screenIndex))\n if (screens.size < 2) continue\n const shared = entries\n .map((entry) => entry.section.uses.filter((ref) => refKind(ref, plan, kinds) === 'component'))\n .reduce((common, refs) => common.filter((ref) => refs.includes(ref)))\n if (shared.length) continue\n violations.push({\n rule: 1,\n code: 'plan-section-across-screens',\n message: `The \"${entries[0].section.name}\" section is planned on ${screens.size} screens. Plan it as one reusable component and place it on each.`,\n paths: entries.map((entry) => entry.path),\n })\n }\n return violations\n}\n\n/** The fewest sections of one item, side by side and of one kind, that are one list split apart. */\nexport const AI_SPLIT_LIST_MIN_SECTIONS = 2\n\n/** A section name's label: what comes before a colon or a spaced dash, as \"practice area\" in \"practice area: family law\". */\nconst SECTION_LABEL = /^(.+?)\\s*(?::|\\s[-–—])\\s*\\S/\n\n/** A name for many of what a name names one of. */\nfunction pluralOf(name: string): string {\n const words = name.trim()\n if (/s$/i.test(words)) return words\n return /[^aeiou]y$/i.test(words) ? `${words.slice(0, -1)}ies` : `${words}s`\n}\n\n/**\n * What kind of item a section of one item shows, for telling a list split\n * into sections apart from sections that each show one different thing: the\n * components it places, else the label its name gives the item. `null` when\n * neither says, or when the section binds its item to data.\n */\nfunction sectionItemKind(\n section: AiBuildPlanSection,\n plan: AiBuildPlan,\n kinds: Map<string, RecordKind>,\n inventory: AiSiteInventory | null,\n): { key: string; name: string; components: string[] } | null {\n if (section.uses.some((ref) => ['dataset', 'collection'].includes(String(refKind(ref, plan, kinds))))) return null\n const label = SECTION_LABEL.exec(section.name)?.[1]?.trim() ?? ''\n const components = section.uses.filter((ref) => refKind(ref, plan, kinds) === 'component')\n if (components.length) {\n const [first] = components\n const named = isAiPlanNewRef(first)\n ? aiPlanCreateFor(plan, first)?.name\n : inventory?.components.find((row) => row.id === first)?.name\n return {\n key: `component:${components.map((ref) => ref.toLowerCase()).sort().join('|')}`,\n name: pluralOf(label || named || first),\n components,\n }\n }\n const words = nameTokens(label).join(' ')\n return words ? { key: `label:${words}`, name: pluralOf(label), components: [] } : null\n}\n\n/**\n * Rule 1 (plan): a list is one section whose items repeat (AGL-3071). A\n * section's `items` counts what it repeats, so two or more sections side by\n * side that each show one item of the same kind — the same component, or a\n * name that labels the same kind of item — are one list split apart. A live\n * Free About page planned \"the four areas we practice\" as four sections of one\n * item: none was drawn from the one written-once item a repeated section is\n * built from, and the four came out in three different shapes. The re-ask\n * names the sections and gives the one section to plan instead. Where the\n * workspace keeps reusable components, a list long enough for rule 1 places\n * one for its item, so the section it gives places one too.\n *\n * Sections of several items are never joined: two lists that share a card\n * are two lists, and rule 8 counts each within its own section (AGL-3061).\n */\nexport function detectPlanSplitLists(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n plan.screens.forEach((screen, screenIndex) => {\n let run: Array<{ index: number; kind: NonNullable<ReturnType<typeof sectionItemKind>> }> = []\n const close = () => {\n if (run.length >= AI_SPLIT_LIST_MIN_SECTIONS) {\n const names = run.map(({ index }) => `\"${screen.sections[index].name}\"`)\n const listed = `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`\n const [{ kind }] = run\n // Rule 1 asks a list this long on a workspace that keeps components to place one for its item.\n const component =\n !kind.components.length && capabilities?.reusableComponents !== false && run.length >= AI_REPEAT_MIN_COUNT\n const section = { name: kind.name, uses: component ? ['new:<name>'] : kind.components, items: run.length }\n const instead = component\n ? `, placing one reusable component for the item: reuse one the site has by its id, or declare one in create and place it as new:<name>, as in ${JSON.stringify(section)}.`\n : `: ${JSON.stringify(section)}.`\n violations.push({\n rule: 1,\n code: 'plan-split-list',\n message: `The sections ${listed} each show one item of the same kind, so they are one list split apart. Plan them as one section whose ${run.length} items repeat${instead}`,\n paths: run.map(({ index }) => `screens[${screenIndex}].sections[${index}]`),\n })\n }\n run = []\n }\n screen.sections.forEach((section, index) => {\n const kind = section.items === 1 ? sectionItemKind(section, plan, kinds, inventory) : null\n if (!kind || (run.length && run[0].kind.key !== kind.key)) close()\n if (kind) run.push({ index, kind })\n })\n close()\n })\n return violations\n}\n\n/** Where the plan's sections place a record of one kind, as `screens[0].sections[1].uses[0]`. */\nfunction placementsOf(\n plan: AiBuildPlan,\n kinds: Map<string, RecordKind>,\n kind: RecordKind,\n): string[] {\n return sectionPaths(plan).flatMap(({ section, path }) =>\n section.uses.flatMap((ref, index) =>\n refKind(ref, plan, kinds) === kind ? [`${path}.uses[${index}]`] : [],\n ),\n )\n}\n\n/**\n * Rule 2 (plan): every screen declares a layout, no section is a copy of a\n * layout region, and no section places a layout, which frames a whole screen\n * (AGL-3040). A site with no layout, where this job may not create one\n * (AGL-3030), has nothing to declare: its screens name none, and a screen\n * that names none is not refused there. A screen whose layout is a `new:`\n * reference the plan never creates is refused here, and only here.\n */\nexport function detectPlanLayoutRegions(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const mayCreateLayout = !capabilities || capabilities.create.layout.allowed\n const noLayoutToName = !mayCreateLayout && !(inventory?.layouts.length ?? 0)\n const unlaid = plan.screens\n .map((screen, index) => ({ screen, index }))\n .filter(\n ({ screen }) =>\n refKind(screen.layout, plan, kinds) !== 'layout' &&\n !(noLayoutToName && screen.layout === null),\n )\n if (unlaid.length) {\n violations.push({\n rule: 2,\n code: 'plan-screen-without-layout',\n message: noLayoutToName\n ? 'A screen names a layout the site does not have, and this job may not create one. Leave the layout empty.'\n : mayCreateLayout\n ? \"A screen names no layout the site has or the plan creates. Put every screen in the site's layout, or plan one.\"\n : 'A screen names no layout the site has, and this job may not create one. Put every screen in a layout the site has.',\n paths: unlaid.map(({ index }) => `screens[${index}].layout`),\n })\n }\n const regions = sectionPaths(plan).filter(({ section }) =>\n LAYOUT_REGION_NAME.test(section.name),\n )\n if (regions.length) {\n violations.push({\n rule: 2,\n code: 'plan-layout-region-section',\n message:\n 'A screen plans its own header, navigation or footer. Those live in the layout; take the section off the screen.',\n paths: regions.map((entry) => entry.path),\n })\n }\n const placed = placementsOf(plan, kinds, 'layout')\n if (placed.length) {\n violations.push({\n rule: 2,\n code: 'plan-layout-in-section',\n message:\n \"A section places a layout. A layout frames a whole screen and is never placed inside one: name it as the screen's layout, and take it out of the section's uses.\",\n paths: placed,\n })\n }\n return violations\n}\n\n/**\n * Rule 3 (plan): a section that collects answers places a form from the Forms\n * page. A workspace that keeps no saved forms draws the form on the page\n * (AGL-3030), and nothing is refused.\n */\nexport function detectPlanInlineForms(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n if (capabilities?.reusableComponents === false) return []\n const kinds = inventoryKinds(inventory)\n const unbound = sectionPaths(plan).filter(\n ({ section }) =>\n FORM_SECTION_NAME.test(section.name) &&\n !section.uses.some((ref) => refKind(ref, plan, kinds) === 'form'),\n )\n return unbound.length\n ? [\n {\n rule: 3,\n code: 'plan-form-not-placed',\n message:\n 'A section collects answers without a form. Reuse a form from the Forms page, or plan one there, and place it by id.',\n paths: unbound.map((entry) => entry.path),\n },\n ]\n : []\n}\n\n/** Pages sharing one shape this many times are a template applied. */\nexport const AI_SIMILAR_PAGES_MIN = 3\n\n/**\n * Rule 4 (plan): three or more screens with the same sections share one\n * template, and a template is what a screen applies, never what one of its\n * sections places (AGL-3040).\n */\nexport function detectUntemplatedSimilarPages(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null = null,\n): AiDoctrineViolation[] {\n const groups = new Map<string, number[]>()\n plan.screens.forEach((screen, index) => {\n if (screen.sections.length < 2) return\n const signature = screen.sections\n .map((section) => nameTokens(section.name).join(' '))\n .join('|')\n groups.set(signature, [...(groups.get(signature) ?? []), index])\n })\n const violations: AiDoctrineViolation[] = []\n for (const indexes of groups.values()) {\n if (indexes.length < AI_SIMILAR_PAGES_MIN) continue\n const templates = new Set(indexes.map((index) => plan.screens[index].template))\n if (templates.size === 1 && !templates.has(null)) continue\n violations.push({\n rule: 4,\n code: 'plan-similar-pages',\n message: `${indexes.length} screens share one shape. Plan one template and apply it ${indexes.length} times with each page's copy, or bind it to a collection.`,\n paths: indexes.map((index) => `screens[${index}].template`),\n })\n }\n const placed = placementsOf(plan, inventoryKinds(inventory), 'template')\n if (placed.length) {\n violations.push({\n rule: 4,\n code: 'plan-template-in-section',\n message:\n \"A section places a template. A template is applied to a whole screen and is never placed inside one: take it out of the section's uses, and name it as the screen's template only when the whole screen is built from it.\",\n paths: placed,\n })\n }\n return violations\n}\n\n/** Rule 5 (plan): a color value belongs only in a theme change. */\nexport function detectPlanLiteralColors(plan: AiBuildPlan): AiDoctrineViolation[] {\n const paths: string[] = []\n plan.create.forEach((entry, index) => {\n if (entry.kind === 'theme-change') return\n if (hasLiteralColor(entry.why) || entry.fields.some(hasLiteralColor)) {\n paths.push(`create[${index}]`)\n }\n })\n for (const { section, path } of sectionPaths(plan)) {\n if (hasLiteralColor(section.name)) paths.push(path)\n }\n return paths.length\n ? [\n {\n rule: 5,\n code: 'plan-literal-color',\n message:\n 'The plan writes a color by value outside a theme change. Name theme tokens, and plan a theme change for a color the theme lacks.',\n paths,\n },\n ]\n : []\n}\n\nconst REUSE_BEFORE_CREATE_KINDS: ReadonlySet<AiBuildPlanCreateKind> = new Set([\n 'component',\n 'layout',\n 'form',\n 'dataset',\n])\n\n/** Rule 7 (plan): reuse names real records, and a creation is an exception that says why. */\nexport function detectCreateBeforeReuse(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const unknown = plan.reuse\n .map((entry, index) => ({ entry, index }))\n .filter(({ entry }) => entry.kind !== 'theme' && kinds.get(entry.id) !== entry.kind)\n if (unknown.length) {\n violations.push({\n rule: 7,\n code: 'plan-reuse-unknown',\n message:\n 'The plan reuses something the site does not have. Reuse only what the site inventory lists.',\n paths: unknown.map(({ index }) => `reuse[${index}]`),\n })\n }\n const unexplained = plan.create\n .map((entry, index) => ({ entry, index }))\n .filter(({ entry }) => !entry.why.trim())\n if (unexplained.length) {\n violations.push({\n rule: 7,\n code: 'plan-create-without-why',\n message: 'The plan creates something without saying why nothing the site has will do.',\n paths: unexplained.map(({ index }) => `create[${index}].why`),\n })\n }\n const rows: Record<string, Array<{ id: string; name: string }>> = {\n component: inventory?.components ?? [],\n layout: inventory?.layouts ?? [],\n form: inventory?.forms ?? [],\n dataset: inventory?.datasets ?? [],\n }\n plan.create.forEach((entry, index) => {\n if (!REUSE_BEFORE_CREATE_KINDS.has(entry.kind) || entry.duplicateOf) return\n const existing = rows[entry.kind].find((row) => aiNamesMatch(row.name, entry.name))\n if (!existing) return\n violations.push({\n rule: 7,\n code: 'plan-duplicates-existing',\n message: `The site already has a ${entry.kind} named \"${existing.name}\". Reuse it, or propose extending it, instead of creating \"${entry.name}\".`,\n paths: [`create[${index}]`],\n })\n })\n return violations\n}\n\n/**\n * Rule 7 (plan): a plan creates only what the request says this job may\n * create on this site (AGL-3030) — what the workspace's plan includes, what\n * the site has room for, and what the job builds itself. One violation a\n * creation, each saying why and what to do instead.\n */\nexport function detectPlanUncreatable(\n plan: AiBuildPlan,\n capabilities: AiPlanCapabilities | null,\n): AiDoctrineViolation[] {\n if (!capabilities) return []\n return aiPlanUncreatable(plan, capabilities).map((entry) => ({\n rule: 7,\n code: 'plan-create-not-allowed',\n message: entry.message,\n paths: [entry.path],\n }))\n}\n\n/**\n * What a section most likely meant by a creation it places and the plan never\n * declares, so the refusal can name the way out: a form where the reference\n * or its section reads as one and the section places no form yet, otherwise\n * a component. Only the message reads it; the reference is refused whatever\n * it was meant to be.\n */\nfunction undeclaredPlacementKind(\n name: string,\n section: AiBuildPlanSection,\n plan: AiBuildPlan,\n kinds: Map<string, RecordKind>,\n): 'form' | 'component' {\n if (FORM_SECTION_NAME.test(name)) return 'form'\n const placesForm = section.uses.some((ref) => refKind(ref, plan, kinds) === 'form')\n return FORM_SECTION_NAME.test(section.name) && !placesForm ? 'form' : 'component'\n}\n\n/**\n * Rule 7 (plan): what a plan places, it reuses or it creates (AGL-3040). The\n * doctrine has a plan refer to what it creates as new:<name>, so a reference\n * that names no entry of the create list is a creation nothing builds. A page\n * kept with one stops at its first pass, sending the member to make that\n * creation by hand, which a workspace that cannot make it never can. Each is\n * refused with the one re-ask, once a name however often it is placed, and\n * says what to do on THIS workspace: declare the creation where the job may\n * make one more of that kind, and otherwise build the page without it, drawn\n * on the page or placed from what the site has. A screen's layout is rule\n * 2's (`plan-screen-without-layout`), and is not reported twice.\n */\nexport function detectPlanUndeclaredCreations(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const byName = new Map<string, AiPlanUndeclaredRef[]>()\n for (const ref of aiPlanUndeclaredRefs(plan)) {\n if (ref.field === 'layout') continue\n const key = ref.name.toLowerCase()\n byName.set(key, [...(byName.get(key) ?? []), ref])\n }\n return [...byName.values()].map((refs): AiDoctrineViolation => {\n const [first] = refs\n const screen = plan.screens[first.screenIndex]\n const section = first.field === 'uses' ? screen.sections[first.sectionIndex] : null\n const kind: AiBuildPlanCreateKind = section\n ? undeclaredPlacementKind(first.name, section, plan, kinds)\n : 'template'\n const refused = capabilities ? aiPlanUncreatableKind(plan, kind, capabilities) : null\n const where = section\n ? `${section.name ? `The \"${section.name}\" section` : 'A section'} places a creation named \"${first.name}\", but the plan never creates it`\n : `${screen.title ? `The screen \"${screen.title}\"` : 'A screen'} applies a template named \"${first.name}\", but the plan never creates it`\n let message: string\n if (!refused) {\n const otherwise = section\n ? `place ${aiCreationNoun(kind)} the site already has by its id`\n : \"leave the screen's template empty\"\n message = `${where}. Declare it in create as ${aiCreationNoun(kind)}, with why nothing the site has will do, or ${otherwise}.`\n } else if (section) {\n message = `${where}, and ${refused.reason}. ${refused.instead} Take it out of the section's uses.`\n } else {\n message = `${where}, and ${refused.reason}. Leave the screen's template empty, or apply a template the site already has.`\n }\n return { rule: 7, code: 'plan-creation-undeclared', message, paths: refs.map((ref) => ref.path) }\n })\n}\n\n/**\n * Rule 8 (plan): long lists are bound, and a list the site already holds is\n * bound to it. Where this job may not create a dataset (AGL-3030), the way\n * out the refusal names is a shorter list rather than a dataset it would\n * only refuse next.\n */\nexport function detectPlanTypedData(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const data = [...(inventory?.datasets ?? []), ...(inventory?.collections ?? [])]\n const typed: string[] = []\n const unbound: Array<{ path: string; name: string }> = []\n for (const { section, path } of sectionPaths(plan)) {\n const bindsData = section.uses.some((ref) =>\n ['dataset', 'collection'].includes(String(refKind(ref, plan, kinds))),\n )\n if (bindsData) continue\n if (section.items >= AI_TYPED_LIST_MIN_ITEMS) typed.push(path)\n const match = data.find((row) => aiNamesMatch(row.name, section.name))\n if (match) unbound.push({ path, name: match.name })\n }\n if (typed.length) {\n violations.push({\n rule: 8,\n code: 'plan-typed-list',\n message:\n capabilities && !capabilities.create.dataset.allowed\n ? `A section plans a long list of typed-out items. Bind it to a dataset or collection the site has, or plan fewer than ${AI_TYPED_LIST_MIN_ITEMS} items.`\n : 'A section plans a long list of typed-out items. Bind it to a dataset or collection, or plan a dataset for data the site does not have yet.',\n paths: typed,\n })\n }\n if (unbound.length) {\n violations.push({\n rule: 8,\n code: 'plan-existing-data-unbound',\n message: `The site already holds \"${unbound[0].name}\" as data. Bind the section to it instead of copying it into the page.`,\n paths: unbound.map((entry) => entry.path),\n })\n }\n return violations\n}\n\nconst SLUG = /^\\/?[a-z0-9]+(?:-[a-z0-9]+)*(?:\\/[a-z0-9]+(?:-[a-z0-9]+)*)*\\/?$|^\\/$/\nexport const AI_SEO_TITLE_MAX = 70\nexport const AI_SEO_DESCRIPTION_MAX = 170\n\nfunction slugKey(slug: string): string {\n return slug.trim().toLowerCase().replace(/^\\/+|\\/+$/g, '')\n}\n\n/** Rule 10 (plan): every screen has a free, well-formed slug, an SEO title and description. */\nexport function detectMissingNavAndSeo(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n): AiDoctrineViolation[] {\n const violations: AiDoctrineViolation[] = []\n const taken = new Map(\n (inventory?.screens ?? []).map((screen) => [slugKey(screen.slug), screen.name]),\n )\n const seen = new Set<string>()\n const badSlugs: string[] = []\n const collisions: string[] = []\n const seo: string[] = []\n plan.screens.forEach((screen, index) => {\n const key = slugKey(screen.slug)\n if (!screen.slug.trim() || !SLUG.test(screen.slug.trim())) {\n badSlugs.push(`screens[${index}].slug`)\n } else if (seen.has(key) || taken.has(key)) {\n collisions.push(`screens[${index}].slug`)\n }\n seen.add(key)\n if (!screen.seoTitle || screen.seoTitle.length > AI_SEO_TITLE_MAX) {\n seo.push(`screens[${index}].seoTitle`)\n }\n if (!screen.seoDescription || screen.seoDescription.length > AI_SEO_DESCRIPTION_MAX) {\n seo.push(`screens[${index}].seoDescription`)\n }\n })\n if (badSlugs.length) {\n violations.push({\n rule: 10,\n code: 'plan-slug',\n message:\n 'A screen has no usable address. Give each one a slug of lowercase words joined by hyphens.',\n paths: badSlugs,\n })\n }\n if (collisions.length) {\n violations.push({\n rule: 10,\n code: 'plan-slug-taken',\n message:\n 'A screen reuses an address the site or the plan already uses. Give each screen its own slug.',\n paths: collisions,\n })\n }\n if (seo.length) {\n violations.push({\n rule: 10,\n code: 'plan-seo',\n message: `A screen is missing its search title or description, or runs past ${AI_SEO_TITLE_MAX} and ${AI_SEO_DESCRIPTION_MAX} characters. Write both for every screen.`,\n paths: seo,\n })\n }\n return violations\n}\n\n/** Every piece of copy a plan carries, with its path. */\nexport function aiPlanCopy(plan: AiBuildPlan): AiCopySample[] {\n const samples: AiCopySample[] = []\n plan.screens.forEach((screen, index) => {\n samples.push({ at: `screens[${index}].title`, text: screen.title })\n samples.push({ at: `screens[${index}].seoTitle`, text: screen.seoTitle })\n samples.push({ at: `screens[${index}].seoDescription`, text: screen.seoDescription })\n })\n plan.create.forEach((entry, index) => {\n samples.push({ at: `create[${index}].name`, text: entry.name })\n })\n return samples\n}\n\n/** Rule 15 (plan): a screen or template like one the site has starts as its duplicate. */\nexport function detectMissedDuplicate(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const unresolved: string[] = []\n plan.screens.forEach((screen, index) => {\n if (screen.duplicateOf) {\n if (kinds.get(screen.duplicateOf) !== 'screen') {\n unresolved.push(`screens[${index}].duplicateOf`)\n }\n return\n }\n const nearest = (inventory?.screens ?? []).find(\n (existing) => !existing.template && aiNamesMatch(existing.name, screen.title),\n )\n if (nearest) {\n violations.push({\n rule: 15,\n code: 'plan-missed-duplicate',\n message: `The site already has \"${nearest.name}\". Start the new screen from a duplicate of it, which keeps its bindings and SEO, and edit that.`,\n paths: [`screens[${index}].duplicateOf`],\n })\n }\n })\n plan.create.forEach((entry, index) => {\n if (entry.duplicateOf) {\n const kind = kinds.get(entry.duplicateOf)\n if (!kind || (kind !== entry.kind && !(entry.kind === 'template' && kind === 'screen'))) {\n unresolved.push(`create[${index}].duplicateOf`)\n }\n return\n }\n if (entry.kind !== 'template') return\n const nearest = (inventory?.templates ?? []).find((existing) =>\n aiNamesMatch(existing.name, entry.name),\n )\n if (nearest) {\n violations.push({\n rule: 15,\n code: 'plan-missed-duplicate',\n message: `The site already has the \"${nearest.name}\" template. Start from a duplicate of it and edit that.`,\n paths: [`create[${index}].duplicateOf`],\n })\n }\n })\n if (unresolved.length) {\n violations.push({\n rule: 15,\n code: 'plan-duplicate-unknown',\n message:\n 'The plan duplicates something the site does not have. Duplicate only what the site inventory lists.',\n paths: unresolved,\n })\n }\n return violations\n}\n\n/** What each exchange of a Free page job comes to at its worst, in credits. */\nexport interface AiFreePageWorstCase {\n /** The page plan. */\n plan: number\n /** The one layout a Free plan includes, built first on a site with none (AGL-3031). */\n layout: number\n /** The first section pass, which writes the cached prefix. */\n firstSection: number\n /** Each later section pass, which reads it. */\n laterSection: number\n /** A page's listing. */\n listing: number\n}\n\n/**\n * The Free taste's wall at its worst (AGL-3030, AGL-3070): each exchange of a\n * Free page job in credits, every answer at its ceiling, as\n * `jobs/ai-job-free-page.spec.ts` derives them from the page plan and the\n * layout generation measured live and the requests as they stand. The spec\n * fails when a figure it derives moves and this does not, so the section cap\n * below cannot drift from the proof.\n */\nexport const AI_FREE_PAGE_WORST_CASE_CREDITS: Readonly<AiFreePageWorstCase> = {\n plan: 83,\n layout: 64,\n firstSection: 44,\n laterSection: 20,\n listing: 3,\n}\n\n/**\n * The most sections a Free job fits in `FREE_AI_TASTE_CREDITS_PER_MONTH` at\n * its worst: the plan, the layouts it builds first, a listing for each page\n * and the first section's pass, then as many later passes as the rest pays\n * for; none when that is already past the wall. A component or a form is never\n * a Free creation, since rule 7 refuses both on a workspace that keeps no\n * reusable components, so the wall's proof measures neither.\n */\nexport function aiFreePageSectionsWithin(\n creations: { layouts: number; pages?: number },\n credits: Readonly<AiFreePageWorstCase> = AI_FREE_PAGE_WORST_CASE_CREDITS,\n): number {\n const before =\n credits.plan + creations.layouts * credits.layout + (creations.pages ?? 1) * credits.listing + credits.firstSection\n if (before > FREE_AI_TASTE_CREDITS_PER_MONTH) return 0\n return 1 + Math.floor((FREE_AI_TASTE_CREDITS_PER_MONTH - before) / credits.laterSection)\n}\n\n/**\n * The layouts a Free plan's job builds before its sections: the ones it\n * creates that the workspace may make, and on a site with no layout where it\n * may make one, the one rule 2 asks the plan to create.\n */\nfunction freePlanLayouts(plan: AiBuildPlan, inventory: AiSiteInventory | null, capabilities: AiPlanCapabilities): number {\n const refused = aiPlanUncreatable(plan, capabilities).filter((entry) => entry.kind === 'layout').length\n const creates = plan.create.filter((entry) => entry.kind === 'layout').length - refused\n const needs = !(inventory?.layouts.length ?? 0) && capabilities.create.layout.allowed ? 1 : 0\n return Math.max(creates, needs)\n}\n\n/**\n * The Free wall (plan): a plan asks for no more sections than the Free taste\n * pays for at its worst beside what the job builds first (AGL-3070). A live\n * Free plan asked for eight sections beside its layout, where the wall's worst\n * case pays for six, and fit only because every exchange ran under its\n * ceiling; one that does not runs out of credits with its page half built. The\n * cap only lowers what a plan may ask for, from the same figures the wall is\n * proven with, so no plan the proof admits is refused. It is no building rule,\n * so it names none.\n */\nexport function detectPlanOverFreeWall(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null,\n): AiDoctrineViolation[] {\n if (!capabilities?.freeTaste) return []\n const asked = plan.screens.reduce((sum, screen) => sum + screen.sections.length, 0)\n const layouts = freePlanLayouts(plan, inventory, capabilities)\n const pages = Math.max(plan.screens.length, 1)\n const fits = aiFreePageSectionsWithin({ layouts, pages })\n if (asked <= fits) return []\n const job = pages > 1 ? `a Free plan of ${pages} pages` : 'a Free page'\n const beside = layouts ? ` that creates ${layouts > 1 ? `${layouts} layouts` : 'its layout'}` : ''\n return [\n {\n rule: null,\n code: 'plan-over-free-wall',\n message: `This plan asks for ${asked} sections, and ${job}${beside} fits ${fits} in the ${FREE_AI_TASTE_CREDITS_PER_MONTH} AI credits a Free workspace has a month. Plan at most ${fits}: draw a list's repeated items in one section, and leave out a section the brief does not ask for.`,\n paths: plan.screens.map((_, index) => `screens[${index}].sections`),\n },\n ]\n}\n\n/**\n * Rule 2 (plan): a layout the plan creates lists the regions it has, and\n * every one is a region this platform builds (AGL-3024).\n *\n * A layout has no properties, so its `fields` are its REGIONS — the promise\n * the build is later held to. A word the vocabulary does not hold is refused\n * HERE, on the plan, where the re-ask costs a sentence: a promise nothing can\n * look for would otherwise reach the build as a commitment no check can\n * settle, and a build that cannot settle its own plan stops for a person\n * instead of reporting itself done.\n */\nexport function detectPlanUnreadableRegions(plan: AiBuildPlan): AiDoctrineViolation[] {\n const unreadable: Array<{ word: string; path: string }> = []\n plan.create.forEach((entry, index) => {\n if (entry.kind !== 'layout') return\n entry.fields.forEach((field, fieldIndex) => {\n if (!aiLayoutRegionOf(field)) {\n unreadable.push({ word: field, path: `create[${index}].fields[${fieldIndex}]` })\n }\n })\n })\n if (!unreadable.length) return []\n const one = unreadable.length === 1\n return [\n {\n rule: 2,\n code: 'plan-layout-region-unknown',\n message: `A layout lists ${unreadable\n .map((entry) => `\"${entry.word}\"`)\n .join(', ')} among its regions, and a layout is built out of ${AI_LAYOUT_REGION_NAMES.join(\n ', ',\n )}. Name ${one ? 'it' : 'them'} with one of those, or leave ${one ? 'it' : 'them'} off the layout.`,\n paths: unreadable.map((entry) => entry.path),\n },\n ]\n}\n\n/**\n * Every plan rule, against the site inventory the plan was made from and,\n * where the job read them, what it may create there (AGL-3030). `null`\n * capabilities restrict nothing: the doctrine applies whole.\n */\nexport function validateAiBuildPlan(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n framing: AiCopyFraming = null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n return [\n ...detectPlanRepeats(plan, inventory, capabilities),\n ...detectPlanSplitLists(plan, inventory, capabilities),\n ...detectPlanOverFreeWall(plan, inventory, capabilities),\n ...detectPlanLayoutRegions(plan, inventory, capabilities),\n ...detectPlanUnreadableRegions(plan),\n ...detectPlanInlineForms(plan, inventory, capabilities),\n ...detectUntemplatedSimilarPages(plan, inventory),\n ...detectPlanLiteralColors(plan),\n ...detectCreateBeforeReuse(plan, inventory),\n ...detectPlanUncreatable(plan, capabilities),\n ...detectPlanUndeclaredCreations(plan, inventory, capabilities),\n ...detectPlanTypedData(plan, inventory, capabilities),\n ...detectMissingNavAndSeo(plan, inventory),\n ...detectOffVoiceCopy(aiPlanCopy(plan), framing),\n ...detectMissedDuplicate(plan, inventory),\n ]\n}\n"],"names":["sanitizeAuthorHtml","formatBytes","measureNodeMap","nodeMapBytes","MEDIA_CDN_VARIANT_WIDTHS","parseMediaRef","ESTIMATED_PAGE_TRANSFER_BYTES","FREE_AI_TASTE_CREDITS_PER_MONTH","REUSABLE_INSTANCE_COMPONENT_ID","REUSABLE_INSTANCE_PROP_VALUES_KEY","parseBreakpointSpan","renderEmailHtml","aiPlanCreateFor","aiPlanUndeclaredRefs","isAiPlanNewRef","aiCreationNoun","aiPlanUncreatable","aiPlanUncreatableKind","AI_INSTANCE_REF_PROP","validateAiNodeTree","AI_PAGE_SCROLL_TO_PROP","aiPageLinkTarget","aiStoredScrollTargets","AI_EMAIL_CLIP_BYTES","AI_OUTPUT_BUDGETS","AI_OUTPUT_SURFACE","isHeadlineVariant","AI_PALETTE","AI_SX_TOKENS","AI_DOCTRINE_RULES","AI_DOCTRINE_RULE_NUMBERS","Object","keys","map","Number","aiDoctrineViolationText","violation","rule","message","isRecord","value","Array","isArray","walkTree","tree","visits","seen","Set","stack","id","rootId","depth","ancestors","length","node","pop","nodes","has","add","push","children","index","displayName","componentId","elementOf","props","hasAncestor","visit","test","some","unique","values","listNames","ids","names","join","slice","AI_REPEAT_MIN_NODES","AI_REPEAT_MIN_COUNT","AI_REPEAT_ACROSS_PAGES_MIN_NODES","AI_TYPED_LIST_MIN_ITEMS","indexShapes","shapeOf","Map","sizeOf","schema","propsSchema","properties","sort","key","declared","structural","Boolean","enum","type","String","filter","child","set","get","reduce","sum","repeatedByData","repeatedShapes","minNodes","minCount","groupOf","byShape","shape","JSON","stringify","repeated","entries","repeatedIds","flatMap","ancestorsOf","every","ancestor","detectRepeatedSubtrees","otherPages","context","reusableComponents","violations","name","code","nodeIds","elsewhere","other","otherIndex","shared","sharedIds","outermost","aiRepeatedItemCount","most","count","aiBindsRepeatedItems","REGION_ELEMENTS","REGION_WORDS","header","footer","nav","AI_LAYOUT_REGIONS","elements","componentIds","sidebar","main","AI_LAYOUT_REGION_NAMES","LAYOUT_REGION_ALIASES","masthead","navigation","menu","aside","drawer","rail","slot","content","aiLayoutRegionOf","word","read","cleaned","split","replace","toLowerCase","trim","includes","aiTreeLayoutRegions","found","element","region","where","detectLayoutRegions","outputKind","regions","entry","detectInlineForms","inline","loose","unbound","shadowed","empty","bound","inner","COLOR_SX_KEYS","COLOR_IN_VALUE_SX_KEYS","SPACING_SX_KEYS","TYPE_SX_KEYS","COLOR_KEYWORDS","LITERAL_COLOR","LENGTH_WITH_UNIT","paletteTokens","palette","hasLiteralColor","parts","part","sxValues","detectLiteralStyles","colors","lengths","raw","sx","normalizeHex","hex","detectOffBrandEmail","brand","allowed","fonts","font","offBrand","candidates","family","candidate","detectTypedData","sectionOf","reverse","find","byComponent","childId","ref","detectUnfilledInstances","first","componentProps","unfilled","filled","one","mediaValues","out","roles","propRoles","refId","detectImageSources","hotlinked","missingAlt","alt","decorative","aiHeadingLevel","match","exec","detectDocumentStructure","headings","mains","slots","rootElement","slotElement","chosenAway","level","h1s","heading","page","skipped","previous","WIDTH_SX_KEYS","detectAdHocWidths","fixed","GRID","GRID_CONTAINER_PROPS","GRID_ROW_PROPS","GRID_ROW_DIRECTIONS","GRID_COLUMN_DIRECTION","GRID_ITEM_WRAPPERS","GRID_GAP_SX_KEYS","GRID_DEFAULT_COLUMNS","GRID_QUOTED_MAX_CHARS","writtenValueText","text","cut","gridColumns","columns","isInteger","gridItemSpan","size","span","phoneFull","steps","undefined","base","xs","breakpoint","gridItemSizeFor","items","across","Math","min","max","md","floor","sm","detectUnresponsiveGrids","written","shapes","childrenOf","isGrid","isContainer","isSized","writtenProp","unreadContainer","wrapsItems","writtenColumn","direction","setsOutRow","refused","rows","stacks","outside","texts","unsized","suggested","gapped","parentId","grandparentId","parent","sized","wrappedItem","holdsSized","isItem","setsContainerProps","within","column","offending","item","gap","spacing","LINK_COLOR_FAMILIES","LINK_COMPONENTS","isAiLinkElement","PAPER_COMPONENTS","FAMILY_TOKEN","familyOf","bandOf","background","token","color","linkWordsFamily","own","styledAsButton","detectInvisibleLinks","hidden","band","HOME_WORDS","detectUnrelatedScreenLinks","home","homeScreenIds","sent","screenId","linksHome","label","inNavigation","isFilled","detectLinksWithoutDestination","stored","sections","pageSections","targets","scrollTargetIds","dead","fragments","unknown","target","kind","via","inForm","wordsOf","listed","toSection","instead","PUBLISH_KEYS","detectPublishIntent","answer","paths","path","forEach","here","BRACKETED_FACT","aiBracketedFacts","facts","matchAll","fact","FILLER_COPY","JUDGMENT","detectOffVoiceCopy","samples","framing","filler","sample","judged","at","list","aiTreeCopy","LINE_PROPS","muiTypography","muiListItemText","muiCardHeader","muiAccordionSummary","emailText","LABEL_VARIANTS","DANGLING_WORDS","OPENING_WORDS","CLOSED_LINE","aiDanglingWord","line","lower","before","lineTail","words","detectDanglingWords","LABEL_PROPS","muiButton","muiScreenLink","emailButton","CUT_REPAIR","lineHead","detectCutLines","repairs","idOf","repair","nodeId","limit","shown","PURE_CONTAINERS","EMBED_COMPONENTS","DUPLICATE_SX_MIN_KEYS","DUPLICATE_SX_MIN_NODES","detectHeavyDocument","wrappers","eager","video","embeds","sxSeen","images","ownProps","boundForm","acceptsChildren","allowEmbeds","duplicatedSx","flat","ITEM_NOUNS","muiListItem","muiCard","FRAME_COMPONENTS","WORD_PROPS","muiList","muiInlineText","showsOwn","detectEmptyItems","noun","nouns","EMAIL_COLUMN_PX","MEDIA_IMAGE_PROPS","image","emailImage","collectionEntryAuthor","contentAuthorProfile","servedVariantWidth","slotWidth","widest","width","pixels","parsed","parseFloat","isFinite","imageRequests","requests","named","startsWith","assets","mediaId","sizeBytes","bytes","variant","ratio","round","scoreAiOutput","families","emailHtmlBytes","html","sanitize","TextEncoder","encode","imageBytes","imagesUnmeasured","fontFamilies","METRIC_LABELS","figure","metric","toLocaleString","heaviest","largest","a","b","BUDGET_METRICS","detectOverBudget","score","budget","offenders","estimateAiOutputLoad","pageBytes","documentBytes","totalBytes","detectDisagreeingNodes","input","reached","missing","queue","shift","orphans","detail","validateAiDoctrineTree","publish","disagreeing","ok","load","validated","error","minted","sourceIds","source","writtenOf","writtenNode","storedOf","NAME_STOPWORDS","nameTokens","endsWith","aiNamesMatch","left","right","small","large","inventoryKinds","inventory","kinds","row","components","layouts","templates","forms","datasets","collections","screens","refKind","plan","sectionPaths","screen","screenIndex","section","sectionIndex","LAYOUT_REGION_NAME","FORM_SECTION_NAME","detectPlanRepeats","capabilities","placesComponent","uses","byName","common","refs","AI_SPLIT_LIST_MIN_SECTIONS","SECTION_LABEL","pluralOf","sectionItemKind","detectPlanSplitLists","run","close","component","placementsOf","detectPlanLayoutRegions","mayCreateLayout","create","layout","noLayoutToName","unlaid","placed","detectPlanInlineForms","AI_SIMILAR_PAGES_MIN","detectUntemplatedSimilarPages","groups","signature","indexes","template","detectPlanLiteralColors","why","fields","REUSE_BEFORE_CREATE_KINDS","detectCreateBeforeReuse","reuse","unexplained","form","dataset","duplicateOf","existing","detectPlanUncreatable","undeclaredPlacementKind","placesForm","detectPlanUndeclaredCreations","field","title","otherwise","reason","detectPlanTypedData","data","typed","bindsData","SLUG","AI_SEO_TITLE_MAX","AI_SEO_DESCRIPTION_MAX","slugKey","slug","detectMissingNavAndSeo","taken","badSlugs","collisions","seo","seoTitle","seoDescription","aiPlanCopy","detectMissedDuplicate","unresolved","nearest","AI_FREE_PAGE_WORST_CASE_CREDITS","firstSection","laterSection","listing","aiFreePageSectionsWithin","creations","credits","pages","freePlanLayouts","creates","needs","detectPlanOverFreeWall","freeTaste","asked","fits","job","beside","_","detectPlanUnreadableRegions","unreadable","fieldIndex","validateAiBuildPlan"],"mappings":"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"}