{
  "version": "v1",
  "format": "flax-model-patch-recipe-index",
  "siteDataModelSchema": "https://flaxsites.com/schemas/flax/v1/site-data-model.schema.json",
  "modelUpdatePlanSchema": "https://flaxsites.com/schemas/flax/v1/model-update-plan.schema.json",
  "purpose": "Examples for creating content records, repairing content JSON, adding their UI sections, and configuring section presentation.",
  "applyOrder": [
    "Read the live model and its schema first.",
    "Use stable, unique IDs. Never replace an unrelated record or section.",
    "Create or update the content record before adding its ui.sections entry.",
    "Copy a concrete palette from an enabled section and use a templateId supported for the new section type.",
    "Validate the resulting model, then submit the generic operations for owner review."
  ],
  "modelInvariants": [
    "A visible section has two coordinated parts: canonical content at a model root such as model.products, model.events, or model.faqs, and presentation metadata in an entry in model.ui.sections.",
    "ArticleItem.published defaults to true. Set published: false only when the user explicitly wants an article kept out of the generated site.",
    "ArticleItem.cta is optional. Omit it, or leave its title, intro, and media empty with both buttons disabled, to render no article-specific CTA; configured CTA content renders as a normal CTA section immediately after the article detail.",
    "To add a new visible section, create or update the canonical model.* content first, then add a model.ui.sections entry with id, type, templateId, palette, and enabled. Creating only one side is incomplete.",
    "model.ui.sections stores section presentation, layout, navigation, and visibility metadata. Do not put collection records or section copy under model.ui.sections.",
    "Articles are stored at model.articles[sectionId].articles. An empty articles array is a valid, ready-to-use state; do not look for an items array and do not remove and recreate an enabled Articles section just because it has no article records.",
    "Child pages are compiled from canonical CMS records and enabled UI sections. Do not create child-page records under model.ui: use childPageStyles or childPageTemplates only to override a generated page's presentation.",
    "A child-page style override is keyed as model.ui.childPageStyles[pageId][sectionId]. The page ID identifies the generated page type and the section ID identifies a section actually rendered on that page.",
    "Removing a UI section does not automatically mean deleting its canonical model.* data. Use enabled: false to hide a section reversibly; delete canonical data only after explicit confirmation and after checking whether it is shared or section-keyed."
  ],
  "authorization": {
    "thirdPartyAgentApi": "The public agent API lets an agent propose validated generic updates to any known SiteDataModel path. Agents cannot publish directly; the site owner reviews and approves every draft.",
    "recipes": "Recipes explain canonical model structure and validation workflows. They guide the agent but do not replace schema validation or owner review."
  },
  "agentImageUpload": {
    "purpose": "Exact protocol for an agent-local image. Use this only when the agent has local-file access; use flax_upload_image with sourceUrl for a public HTTPS image.",
    "noClientSideChunking": true,
    "steps": [
      "Convert the source to one WebP file no wider than 1920px. Use that exact WebP for every remaining step; it must be 25 MB or smaller and contain no more than 16,000,000 pixels.",
      "Inspect the WebP, then call flax_begin_image_upload with its name, exact totalBytes, and lowercase sha256.",
      "Make exactly one raw binary PUT to upload.url. Send every upload.headers field including AgentUploadTicket and set Content-Length to totalBytes. Send the unchanged WebP bytes: no base64, multipart form, JSON wrapper, re-encoding, or agent-managed chunks.",
      "A 2xx PUT response contains the permanent attachment. Use that attachment directly in flax_validate_model_update or flax_propose_model_update; never put a storage path in the site model."
    ],
    "recovery": "If the WebP, byte count, or checksum changes, or the 15-minute ticket expires, create a fresh WebP and start a new upload. Do not reuse an old ticket.",
    "finalization": "The direct PUT verifies the authorized WebP and its maximum 1920px width, creates real 320, 640, 960, 1280, and 1920 pixel WebP variants on Flax's server, and returns the permanent attachment. There is no completion tool and no temporary image object."
  },
  "shared": {
    "copyPalette": "const palette = structuredClone(model.ui.sections.find((section) => section.enabled && section.palette)?.palette); if (!palette) throw new Error('A concrete existing section palette is required');",
    "sectionRule": "To add a new visible section, create the canonical data at model.<root> (for example model.products, model.events, or model.faqs) and add a separate entry to model.ui.sections. The UISection must have id, type, templateId, palette, and enabled. Reuse the content record ID as the UI section ID when the renderer is keyed by ID; never put collection content under model.ui.sections.",
    "buttonRule": "Buttons use { type: 'content' | 'external-link', value?, displayText?, enabled? }. Content targets use existing internal targets such as 'contact' or a flax://content path already used by the site.",
    "imageRule": "Keep model image src values logical (for example /images/product.webp). New local uploads must set local: true; publish clears that flag and rendered images use a sized variant."
  },
  "recipeFormat": "flax-model-patch-recipe",
  "recipes": [
    {
      "id": "remove-section",
      "feature": "sections",
      "summary": "Remove an existing UI section while preserving its canonical content by default.",
      "url": "https://flaxsites.com/.well-known/flax-agent-recipes.v1/remove-section.json"
    },
    {
      "id": "configure-product-grid",
      "feature": "products",
      "summary": "Configure an existing products section's grid display and shopper controls.",
      "url": "https://flaxsites.com/.well-known/flax-agent-recipes.v1/configure-product-grid.json"
    },
    {
      "id": "add-product-catalogue",
      "feature": "products",
      "summary": "Create the products collection, add one product, and render it on the homepage.",
      "url": "https://flaxsites.com/.well-known/flax-agent-recipes.v1/add-product-catalogue.json"
    },
    {
      "id": "add-event-listing",
      "feature": "events",
      "summary": "Create an events collection, add an event, and show an events listing.",
      "url": "https://flaxsites.com/.well-known/flax-agent-recipes.v1/add-event-listing.json"
    },
    {
      "id": "add-event-examples",
      "feature": "events",
      "summary": "Add examples covering every named event type and several recurring schedule patterns.",
      "url": "https://flaxsites.com/.well-known/flax-agent-recipes.v1/add-event-examples.json"
    },
    {
      "id": "add-service-booking",
      "feature": "bookings",
      "summary": "Add a bookable service and the booking data and section needed to offer appointments.",
      "url": "https://flaxsites.com/.well-known/flax-agent-recipes.v1/add-service-booking.json"
    },
    {
      "id": "add-call-to-action",
      "feature": "call-to-action",
      "summary": "Add a reusable CTA record and render it with a matching section ID.",
      "url": "https://flaxsites.com/.well-known/flax-agent-recipes.v1/add-call-to-action.json"
    },
    {
      "id": "add-faq-section",
      "feature": "faqs",
      "summary": "Add a keyed FAQ collection and the homepage section that displays it.",
      "url": "https://flaxsites.com/.well-known/flax-agent-recipes.v1/add-faq-section.json"
    },
    {
      "id": "upsert-article",
      "feature": "articles",
      "summary": "Create or update an article in an existing enabled Articles section, including generic JSON repair when the empty article array is missing.",
      "url": "https://flaxsites.com/.well-known/flax-agent-recipes.v1/upsert-article.json"
    },
    {
      "id": "override-generated-child-page-template",
      "feature": "generated-child-pages",
      "summary": "Select a different supported template for an already generated child-page type.",
      "url": "https://flaxsites.com/.well-known/flax-agent-recipes.v1/override-generated-child-page-template.json"
    },
    {
      "id": "style-generated-child-page-section",
      "feature": "generated-child-pages",
      "summary": "Override the presentation of a section on one generated child-page type without changing its CMS content or homepage presentation.",
      "url": "https://flaxsites.com/.well-known/flax-agent-recipes.v1/style-generated-child-page-section.json"
    },
    {
      "id": "contribute-section-to-generated-child-pages",
      "feature": "generated-child-pages",
      "summary": "Append an existing eligible section to selected generated child-page types.",
      "url": "https://flaxsites.com/.well-known/flax-agent-recipes.v1/contribute-section-to-generated-child-pages.json"
    }
  ]
}
