<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Monogram</title>
    <description>The latest articles on DEV Community by Monogram (madebymonogram).</description>
    <link>https://dev.to/madebymonogram</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F14358%2F353e396c-518d-4508-9953-dab07bfe2b6c.png</url>
      <title>DEV Community: Monogram</title>
      <link>https://dev.to/madebymonogram</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/madebymonogram"/>
    <language>en</language>
    <item>
      <title>Make AI Generated Code Traceable with Requirement IDs</title>
      <dc:creator>Israel Vásquez</dc:creator>
      <pubDate>Mon, 12 Oct 2026 17:03:33 +0000</pubDate>
      <link>https://dev.to/madebymonogram/make-ai-generated-code-traceable-with-requirement-ids-2pc3</link>
      <guid>https://dev.to/madebymonogram/make-ai-generated-code-traceable-with-requirement-ids-2pc3</guid>
      <description>&lt;p&gt;A numbered requirement can connect a product decision to the task, test, and code that implement it. In our spec driven workflow, IDs such as &lt;code&gt;1.1&lt;/code&gt; and &lt;code&gt;1.3&lt;/code&gt; give engineers and AI agents a durable path from a feature’s intent to its implementation.&lt;/p&gt;

&lt;p&gt;That link matters because an AI coding session can leave behind code without the reasoning that produced it. When requirements and decisions live only in a prompt or an agent’s temporary plan, future changes have to reconstruct the original intent from the implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put feature intent in the repository
&lt;/h2&gt;

&lt;p&gt;For non trivial features, we write a specification before implementation. It lives in a dedicated &lt;code&gt;specs/&lt;/code&gt; folder, usually as Markdown, and describes expected behavior, relevant interactions, edge cases, technical decisions, and how to verify the result.&lt;/p&gt;

&lt;p&gt;The spec is a shared source of truth for the team and the agent. It is not documentation added after the work, or a place to collect every engineering convention. The goal is to make feature intent available while the work is being designed, tested, and changed.&lt;/p&gt;

&lt;p&gt;This approach is especially useful when a brief leaves product behavior unresolved. For example, free tier limits require decisions about what happens when a user reaches a storage limit, attempts an upload, or upgrades. Turning those scenarios into testable requirements gives the agent something more precise to follow than a broad request to “add limits.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Use IDs to connect intent to code
&lt;/h2&gt;

&lt;p&gt;Each requirement receives an identifier, such as &lt;code&gt;1.1&lt;/code&gt;. That same ID can appear in the task list, tests, implementation comments, and relevant code paths. A developer who encounters a behavior later can follow the reference back to the spec instead of inferring its purpose from code alone.&lt;/p&gt;

&lt;p&gt;IDs also help keep tests tied to expected behavior. In the workflow, the agent reads the approved spec, writes tests first, and implements until they pass. The tests are grounded in identified requirements, so they can express which behavior they verify rather than merely showing that a particular implementation runs.&lt;/p&gt;

&lt;p&gt;Keep the references lightweight. The ID points to the explanation; it does not need to carry the whole requirement into every comment or test name. That keeps code readable while preserving a route back to the decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Approve decisions before implementation
&lt;/h2&gt;

&lt;p&gt;The process has four phases: requirements, design, tasks, and implementation. A person approves each phase before the next begins.&lt;/p&gt;

&lt;p&gt;Requirements turn the feature brief into acceptance criteria. Design makes technical choices explicit, including API shape, database design, data model changes, product behavior, and architectural constraints. Tasks break the approved plan into implementation steps. Only then does implementation start.&lt;/p&gt;

&lt;p&gt;This sequence gives an agent reviewed context before it changes code. It also creates checkpoints where a person can correct a misunderstanding before it spreads into design, tasks, tests, and implementation. After implementation, automated reviewers such as Gemini or Cursor Bug Bot can review the code before local testing.&lt;/p&gt;

&lt;p&gt;The workflow is still evolving. In particular, tasks can drift or become harder to keep aligned as features grow. Mapping each task to a commit can make the connection between the spec, work performed, and code history cleaner, but teams should watch whether their task structure stays useful over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep feature specs separate from repo rules
&lt;/h2&gt;

&lt;p&gt;A feature spec should describe that feature’s behavior and decisions. General engineering conventions belong elsewhere, such as repository instruction files, agent rules, or skills. Templates can keep requirements, design, and task files consistent.&lt;/p&gt;

&lt;p&gt;This boundary prevents every new spec from repeating coding preferences or carrying unrelated architectural policy. It also helps an agent find the right context: feature behavior in the spec, durable project conventions in repository rules, and repeatable procedures in skills.&lt;/p&gt;

&lt;p&gt;Broader architecture changes need the same care. A notifications feature, for instance, raises questions about delivery timing, triggering events, persistence, and channels. Those are feature decisions to resolve. Introducing a message queue or a new data store is a broader architectural shift, and may require repo level rules or skills rather than being smuggled into one feature spec.&lt;/p&gt;

&lt;p&gt;A practical starting point is to create one spec for a feature with several meaningful edge cases. Number the acceptance criteria, reference them in tasks and tests, and keep the implementation tied to the approved design. Then review whether someone joining later can trace a behavior back to the requirement that explains it.&lt;/p&gt;

&lt;p&gt;Specs should ship with the code because future engineers and agents need the intent alongside the implementation.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>software</category>
      <category>testing</category>
      <category>productivity</category>
    </item>
    <item>
      <title>What shipping Sanity projects taught us about content models that survive redesigns</title>
      <dc:creator>Israel Vásquez</dc:creator>
      <pubDate>Thu, 24 Sep 2026 22:18:01 +0000</pubDate>
      <link>https://dev.to/madebymonogram/what-shipping-sanity-projects-taught-us-about-content-models-that-survive-redesigns-2j83</link>
      <guid>https://dev.to/madebymonogram/what-shipping-sanity-projects-taught-us-about-content-models-that-survive-redesigns-2j83</guid>
      <description>&lt;p&gt;Across our Sanity projects, the most reusable technical decision was not a clever GROQ query. It was defining the content before defining the pages.&lt;/p&gt;

&lt;p&gt;For Kasada, Orb, Contextual AI, Zenity, Hy-Vee, Newfront, and our own M8 site, the schema determined whether content could be filtered, cross-linked, migrated, previewed, and rendered beyond one page template. The patterns below come from our documented &lt;a href="https://monogram.io/technology/sanity" rel="noopener noreferrer"&gt;Sanity implementations&lt;/a&gt;, where the same platform supported marketing sites, internal tools, legacy migrations, and multi-site content operations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frr56sgnukyrsn660cvmf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frr56sgnukyrsn660cvmf.png" alt=" " width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Model entities, not URLs
&lt;/h2&gt;

&lt;p&gt;Structured content stores meaning and relationships independently from its final presentation. A case study remains a case study whether it appears as a card, a hero, or an entry in a filtered index.&lt;/p&gt;

&lt;p&gt;That distinction sounds small, but it changes how a system responds to redesigns. A schema named after a URL or page layout tends to inherit assumptions from that interface. When the layout changes, the schema often has to change with it.&lt;/p&gt;

&lt;p&gt;We instead model stable entities. Authors, clients, technologies, and sectors become documents rather than repeated strings. Other content references those documents. This makes filtering, cross-linking, and resurfacing possible without adding another manually maintained field for every new use.&lt;/p&gt;

&lt;p&gt;Editors still need control, but not necessarily control over every visual property. We use a fixed set of design system blocks so editors can determine sequence and emphasis while the application owns spacing, color, and responsive behavior. On &lt;a href="https://monogram.io/work/m8" rel="noopener noreferrer"&gt;M8&lt;/a&gt;, modular sections can be reordered and recombined while preserving the exposed grid and visual system.&lt;/p&gt;

&lt;p&gt;The tradeoff is intentional. Editors cannot construct arbitrary layouts inside the Studio, but the pages they publish remain inside the tested design system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Map a migration before moving content
&lt;/h2&gt;

&lt;p&gt;A CMS migration is primarily a mapping problem.&lt;/p&gt;

&lt;p&gt;Our process begins with an audit of the legacy archive. We decide what should carry over, what needs rewriting, and what should be retired. Only after those decisions are reflected in the target content model do we move the content.&lt;/p&gt;

&lt;p&gt;For Contextual AI, this meant leaving the legacy system with the existing content intact while introducing a model capable of supporting what came next. The archive survived, but the limitations of its previous representation did not have to become permanent features of the new schema.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2g30ern6o7kbfdwjgez7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2g30ern6o7kbfdwjgez7.png" alt=" " width="799" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Starting with an export reverses that sequence. It encourages the team to reproduce the source CMS inside Sanity, including page-shaped records, duplicated strings, and fields that existed only to satisfy an old template.&lt;/p&gt;

&lt;p&gt;A useful migration plan therefore describes both sides of every mapping: what the legacy field represented and which new document, reference, or structured field should own that meaning. The migration script should implement an already settled model, not become the place where the model is improvised.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let query complexity expose modeling problems
&lt;/h2&gt;

&lt;p&gt;Sanity uses GROQ to query and transform structured content. GROQ is expressive enough to compensate for many schema problems, which is exactly why query complexity deserves attention.&lt;/p&gt;

&lt;p&gt;Our rule of thumb is concrete: if rendering one card requires 3 nested joins, inspect the schema before tuning the query. The issue may be that data used together is modeled too far apart, or that presentation concerns have leaked into the content structure.&lt;/p&gt;

&lt;p&gt;Portable Text follows the same principle. We treat it as structured rich text, not stored HTML. The application decides how the structure should render on a web page, in a feed, or for a machine reader. That avoids maintaining separate copies of the same body for each surface.&lt;/p&gt;

&lt;p&gt;This becomes increasingly important when content serves both people and machines. On Kasada, structured content, explicit references, and machine-readable markup supported enterprise buyers and automated consumers from the same model. The structure was part of the architecture, not something added later through a plugin.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feyuxvq0gkbp96nh06bfz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feyuxvq0gkbp96nh06bfz.png" alt=" " width="800" height="596"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On M8, we also use Sanity Typegen to generate TypeScript types from GROQ queries. This keeps the relationship between the content model, query result, and application code visible to the type system instead of relying on manually maintained interfaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat the editor workflow as an application
&lt;/h2&gt;

&lt;p&gt;A customized Sanity Studio is a frontend application for a specific group of users. Its information architecture, input components, previews, and validation deserve the same attention as the public interface.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://monogram.io/work/hy-vee" rel="noopener noreferrer"&gt;Hy-Vee KidsFit implementation&lt;/a&gt; is a useful example. Editors add a YouTube URL in Sanity, and the integration retrieves the video thumbnail, title, and description through the YouTube API. GROQ also powers dynamic resource filters on the site.&lt;/p&gt;

&lt;p&gt;That input does more than store a URL. It turns a repeated editorial task into a consistent integration point. Editors spend less time transferring metadata manually, and the public interface receives a predictable content shape.&lt;/p&gt;

&lt;p&gt;For &lt;a href="https://monogram.io/work/zenity" rel="noopener noreferrer"&gt;Zenity&lt;/a&gt;, the structured model gave the marketing team enough flexibility to update content and create pages without developer support. Sanity's collaborative editing also allowed multiple team members to work simultaneously.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fznakv9xfb4tfoefyweda.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fznakv9xfb4tfoefyweda.png" alt=" " width="800" height="566"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Live previews on M8 complete the feedback loop by showing creators how changes will appear before publication. If an editor regularly needs a developer to interpret a field or publish a routine page, we treat that as a modeling or Studio design problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Balance publishing speed with maintenance
&lt;/h2&gt;

&lt;p&gt;Our Sanity sites commonly use Next.js on Vercel. Server Components read from Sanity directly, and publication triggers on-demand revalidation. Editors see updates without waiting for a full rebuild, while readers receive static performance.&lt;/p&gt;

&lt;p&gt;That architecture separates publishing from deployment, but it does not eliminate maintenance. A customized Sanity Studio has dependencies, upgrades, custom components, and its own release surface. Teams choosing Sanity should account for that application alongside the public site.&lt;/p&gt;

&lt;p&gt;This leads to a practical selection criterion. Sanity fits when the content contains stable entities and relationships worth preserving, editors benefit from a purpose-built workflow, and the team can maintain the Studio as software. If the main requirement is a hosted editing interface with nothing to customize or upgrade, a simpler CMS may be a better fit.&lt;/p&gt;

&lt;p&gt;When those conditions do hold, the durable asset is not any individual page. It is a content model that can survive the next layout, integration, publishing workflow, and consuming application.&lt;/p&gt;

</description>
      <category>sanity</category>
      <category>nextjs</category>
      <category>cms</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What two Contentful builds taught us about content models and publishing boundaries</title>
      <dc:creator>Israel Vásquez</dc:creator>
      <pubDate>Wed, 23 Sep 2026 22:56:51 +0000</pubDate>
      <link>https://dev.to/madebymonogram/what-two-contentful-builds-taught-us-about-content-models-and-publishing-boundaries-1in0</link>
      <guid>https://dev.to/madebymonogram/what-two-contentful-builds-taught-us-about-content-models-and-publishing-boundaries-1in0</guid>
      <description>&lt;p&gt;For Addiction Education Society (AES), we modeled resources, stories, and core pages in Contentful so staff could update the public site without developer support. The team now publishes changes in minutes rather than days. For CrewAI, we mapped reusable page components to Contentful models, then built a separate handoff that turns published Ghost articles into Contentful drafts. Both projects used the same content management system (CMS). The useful engineering decision was where to place editorial control, rendering rules, and the final publication gate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8vvxowwktkjdjgd8bm3g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8vvxowwktkjdjgd8bm3g.png" alt=" " width="800" height="552"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A headless CMS stores structured content separately from the code that renders it. That separation helps only when the content model reflects what editors need to create and what engineers need to keep consistent. These projects exposed 3 questions worth answering before migrating a page: What is reusable content? Which system owns each step of publication? Which existing systems should stay in place?&lt;/p&gt;

&lt;h2&gt;
  
  
  Model the things editors actually manage
&lt;/h2&gt;

&lt;p&gt;At AES, the main requirement was editorial independence. Staff needed to maintain information as the nonprofit's education and outreach work grew. We created Contentful models for resources, stories, and core pages. Those categories gave the team structured material to build and update pages independently, including for time-sensitive initiatives. The &lt;a href="//mngr.am/aes"&gt;AES case study&lt;/a&gt; reports that updates which took days can now be published in minutes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwbydrcqlvg7o50fingej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwbydrcqlvg7o50fingej.png" alt=" " width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CrewAI needed a different level of composition. Its previous CMS could no longer support the website it needed. We designed reusable components in Figma, including hero layouts, pricing sections, feature grids, statistics modules, and tabbed content. Each component mapped to a structured Contentful model. Marketing could assemble pages from those blocks, while developers rendered the layouts through GraphQL with strong type safety. In the &lt;a href="//mngr.am/crew-ai"&gt;CrewAI case study&lt;/a&gt;, the shift from individual templates to reusable sections is the mechanism behind that division of work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4gf58a0lklqaf22ithpr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4gf58a0lklqaf22ithpr.png" alt=" " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The model therefore served as a contract. An editor could choose and populate a supported section; engineering owned how that section rendered and how it fit with analytics, search optimization, and integrations. Contentful's reference based type system makes these relationships possible, but the types still have to be designed. A collection of loosely related entries would give editors fields to fill without giving the site a dependable composition system. That is the modeling cost we account for up front.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy0pssxpps3lo9ym63a4s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy0pssxpps3lo9ym63a4s.png" alt=" " width="799" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Draw the migration boundary around the work
&lt;/h2&gt;

&lt;p&gt;AES also shows why a CMS migration does not have to mean replacing every application under a domain. Its WordPress learning system supported active educational programs. Rebuilding that system along with the marketing site would have risked downtime or lost functionality. We launched a new marketing platform using Astro and Contentful alongside the existing learning system. Public pages, articles, and donation flows were modernized while the programs continued. Visitors still had an experience under one domain, and AES retained a path to migrate more functionality later.&lt;/p&gt;

&lt;p&gt;That boundary mattered operationally. Staff gained control of public content without waiting for the learning platform to be rebuilt. The Contentful work solved a publishing problem; the surrounding architecture kept an existing program available. The project also used Contentful's pro bono program, which made the platform accessible to this qualifying nonprofit. Pricing was part of the platform decision, even though the implementation followed the same content modeling discipline as a larger site.&lt;/p&gt;

&lt;p&gt;CrewAI crossed a different boundary. We moved its site away from page specific templates toward structured sections in Contentful, but kept Ghost for article writing. Treating every existing tool as something to replace would have disrupted a workflow the editorial team already valued. The two projects suggest a practical migration exercise: list the tasks people perform in each system, then move only the tasks the new architecture is meant to improve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the publication gate explicit
&lt;/h2&gt;

&lt;p&gt;CrewAI's writers publish articles in Ghost. An automated workflow converts each published Ghost article into a &lt;strong&gt;draft&lt;/strong&gt; in Contentful. It stops there deliberately. Marketing then reviews the content, adds metadata, adjusts page composition, schedules it, and publishes it to the public site. Ghost owns the writing experience; Contentful owns the website release decision.&lt;/p&gt;

&lt;p&gt;The draft state is the critical part of that integration. If the handoff went straight to public publication, the team would lose the documented review and enrichment step. If writers had to repeat their work manually in Contentful, the handoff would become another editorial bottleneck. The &lt;a href="//mngr.am/contentful"&gt;Contentful project page&lt;/a&gt; describes this pipeline as the integration point; the case study shows the specific roles on each side of it.&lt;/p&gt;

&lt;p&gt;This is a useful question for any CMS integration: does an upstream “published” event mean ready for the public website, or ready for the next team to review? In CrewAI's workflow, those are separate states. Naming them in the architecture gives both teams a clear handoff and lets each keep the tool suited to its work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose the platform with its constraints visible
&lt;/h2&gt;

&lt;p&gt;Contentful gave AES structured content and staff publishing control; it gave CrewAI reusable page composition and a controlled handoff from Ghost. Neither outcome came from installing a CMS alone. We had to define content types, decide which existing systems would remain, and specify the point where a draft becomes public.&lt;/p&gt;

&lt;p&gt;The platform also has costs. Its type system rewards careful modeling, and the &lt;a href="//mngr.am/contentful"&gt;Contentful project page&lt;/a&gt; notes both the budget impact and the absence of a built-in visual canvas for page building. For a small team with simple pages, that may be more structure than the work requires. For a site where several teams need to assemble pages and govern releases, the structure has a clear job. Start the architecture discussion with the editorial handoffs and the content that must be reused; they reveal whether the CMS belongs at the center, alongside another tool, or only on one part of the site.&lt;/p&gt;

</description>
      <category>contentful</category>
      <category>cms</category>
      <category>webdev</category>
      <category>architecture</category>
    </item>
    <item>
      <title>What a Next.js and Vercel rebuild has to solve beyond deployment</title>
      <dc:creator>Israel Vásquez</dc:creator>
      <pubDate>Tue, 22 Sep 2026 18:53:22 +0000</pubDate>
      <link>https://dev.to/madebymonogram/what-a-nextjs-and-vercel-rebuild-has-to-solve-beyond-deployment-4n26</link>
      <guid>https://dev.to/madebymonogram/what-a-nextjs-and-vercel-rebuild-has-to-solve-beyond-deployment-4n26</guid>
      <description>&lt;p&gt;On Contextual AI’s website rebuild, we defined Sanity schemas before moving content out of WordPress. The schemas had to represent blog posts, research articles, and use cases while the new Next.js site was still taking shape. That sequence made the migration possible alongside development, but it also exposed a practical limit: content from the old site did not always fit the new layouts. Scripts could carry structure and metadata across; people still had to review and adapt the result.&lt;/p&gt;

&lt;p&gt;That is a useful way to think about a Next.js and Vercel implementation. The framework and hosting platform matter, but the project’s value depends on how content, review, design, and integrations work together after launch. Our work on Contextual AI, Zenity, and Orb shows where those decisions become concrete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model the content before moving it
&lt;/h2&gt;

&lt;p&gt;Contextual AI needed a new visual identity and a site that could accommodate changing content needs. We started development with an intensive pass on the Sanity schema, refining it for the different types of data that would come from WordPress. Once the schemas were ready, migration began while the Next.js architecture and new sections were still being built. Most of the import used automated scripts to preserve structure and metadata; manual review caught content issues and helped adapt material to layouts that did not match the old site one to one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpgvqji4blzpevq6xn56e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpgvqji4blzpevq6xn56e.png" alt=" " width="799" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The distinction matters in a rebuild. A script can transfer fields, but a new design may change what each field is supposed to communicate. If a research article, use case, and blog post all have different editorial jobs, treating them as interchangeable pages can leave editors with awkward workarounds. Contextual AI’s documented approach began with those content types, then combined automation with review where the new experience called for judgment.&lt;/p&gt;

&lt;p&gt;We also added real-time content previews to make publishing more intuitive. That connected the content model to the publishing experience. A technically correct import is only part of the job if the team cannot confidently maintain the site afterward. The &lt;a href="https://monogram.io/work/contextual-ai" rel="noopener noreferrer"&gt;Contextual AI project&lt;/a&gt; documents the migration and the continued work after its launch deadline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make review part of the deployment workflow
&lt;/h2&gt;

&lt;p&gt;On Zenity’s site, Vercel Preview Deployments gave product, marketing, and leadership teams a place to review work directly on staging links. Built-in comments let them point to the interface they were discussing. In the &lt;a href="https://monogram.io/work/zenity" rel="noopener noreferrer"&gt;Zenity project&lt;/a&gt;, we describe shorter feedback loops, fewer meetings, and faster progress toward launch from that workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgprebv85idx5g59wnw7v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgprebv85idx5g59wnw7v.png" alt=" " width="800" height="616"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is an operational use of deployment previews, beyond checking that a build runs. A design review is more useful when the reviewer can see the page in a browser and attach feedback to the actual state of the interface. It also gives engineers a concrete reference for a requested change. The decision to include nonengineering stakeholders in preview review affects how a team ships, even though it does not change the application’s runtime architecture.&lt;/p&gt;

&lt;p&gt;Zenity’s content workflow used Sanity for a related reason. Its structured model let the team update and create pages without developer support, while collaborative editing allowed multiple people to work in the CMS. Preview links and editable content served different parts of the same publishing process: one supported review of the implementation; the other supported ongoing changes to the site.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the interface connected to the systems behind it
&lt;/h2&gt;

&lt;p&gt;Zenity also needed forms that matched its interface while sending submissions into HubSpot. We built custom forms using HubSpot’s forms API, connecting the site’s presentation layer to the client’s customer relationship management system. That work is easy to overlook in a discussion of Next.js performance, yet it determines whether a polished page can support the team’s follow-up workflow. The case study describes the integration and its intended lead capture flow; it does not publish conversion results.&lt;/p&gt;

&lt;p&gt;For Orb, the maintenance question appeared in the content model. Sanity organizes pages, modules, and messaging as reusable blocks, giving the team a way to update campaigns and product messaging without asking a developer to edit every page. Relume helped explore layouts and content hierarchy early, before final design. We then used Next.js and Tailwind CSS for the site, with Vercel handling deployment and global delivery. The &lt;a href="https://monogram.io/work/orb" rel="noopener noreferrer"&gt;Orb project&lt;/a&gt; describes hybrid rendering as part of the approach to keeping content fast while retaining flexibility.&lt;/p&gt;

&lt;p&gt;Orb’s visual requirements added another layer. We integrated Unicorn Studio for shader effects and interactive motion using WebGL. That choice shows why performance work cannot be reduced to selecting a framework: visual assets and interaction techniques are also part of what the browser must render. The project describes the motion and the site’s performance qualitatively, without publishing a measurement that would let us isolate the effect of the animation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffbjr7xs5eh1xkc1mgcyi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffbjr7xs5eh1xkc1mgcyi.png" alt=" " width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat the stack as responsibilities, not a checklist
&lt;/h2&gt;

&lt;p&gt;Across these projects, Next.js provides the site architecture; Vercel provides deployment and preview workflows; Sanity gives editors structured content. Those names describe different responsibilities. Their value comes from the seams between them: schema design before migration, content previews during editing, deployment previews during review, and API integrations where the website has to support business operations.&lt;/p&gt;

&lt;p&gt;That is also a practical way to scope a rebuild. Identify the content types and who will maintain them. Decide how old content will be mapped and reviewed. Put the people who approve the interface into a preview workflow. List the external systems a page must send data to or receive data from. Then make rendering and media choices in the context of the actual experience being built. Our &lt;a href="https://monogram.io/next-js-vercel-development" rel="noopener noreferrer"&gt;Next.js and Vercel development page&lt;/a&gt; names the broader services; these project decisions show what that work looks like in practice.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>vercel</category>
      <category>webdev</category>
      <category>cms</category>
    </item>
    <item>
      <title>Designing a Transactional Voice Agent for Latency, Safety, and Human Handoff</title>
      <dc:creator>Israel Vásquez</dc:creator>
      <pubDate>Thu, 17 Sep 2026 19:51:24 +0000</pubDate>
      <link>https://dev.to/madebymonogram/designing-a-transactional-voice-agent-for-latency-safety-and-human-handoff-2fac</link>
      <guid>https://dev.to/madebymonogram/designing-a-transactional-voice-agent-for-latency-safety-and-human-handoff-2fac</guid>
      <description>&lt;p&gt;A production voice agent has to do more than understand a request. It must respond within the rhythm of a phone conversation, coordinate live APIs, protect sensitive data, and transfer the caller without losing context when automation reaches its limit. In our travel booking implementation, that meant completing the full shop, select, pay, book, and confirm workflow through an existing Amazon Connect environment. The system reached a 92% successful end-to-end transaction rate using live APIs and saved 10 to 15 minutes per successful automated booking.&lt;/p&gt;

&lt;p&gt;The useful lesson was not simply that a large language model could handle a booking. The result depended on decisions around the model: how work was divided, how latency was masked, where sensitive operations stopped, and when a person took over.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add AI as a path through the existing system
&lt;/h2&gt;

&lt;p&gt;The client already had Amazon Connect and the APIs required to complete a reservation. We added conversational AI as a new path inside that environment instead of replacing the contact center or recreating its transactional systems.&lt;/p&gt;

&lt;p&gt;Amazon Lex transcribes the caller's freeform request and identifies the basic intent. Claude Haiku handles quick classification, while Claude Sonnet performs the deeper reasoning required to compare options and run the booking APIs. The agent can search live inventory, discuss alternatives, adjust to caller preferences, send a secure payment link by text, confirm the reservation through the client's Payment API, and trigger the confirmation email while the caller remains on the line.&lt;/p&gt;

&lt;p&gt;This approach keeps the AI layer focused on conversation and coordination. Existing systems remain responsible for the operations they already perform. For teams working with mature contact center infrastructure, that is a useful boundary: first identify the smallest new path that can orchestrate the current systems, then replace infrastructure only when the existing components block the required workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat latency as an end-to-end budget
&lt;/h2&gt;

&lt;p&gt;Voice exposes delays that would be less disruptive in a text interface. Our end-to-end response latency target was less than 2 seconds, but transcription and text-to-speech already consumed 1 to 2 seconds before the model had much room to respond. The implemented response time was 2 to 3 seconds.&lt;/p&gt;

&lt;p&gt;True streaming was not ready for this implementation, so we used a practical workaround. The model streamed its reply into DynamoDB. Amazon Lex checked the stored output every few hundred milliseconds and began speaking once it found complete sentences. This was not true streaming, but it reduced the silence the caller experienced and allowed speech to sound natural.&lt;/p&gt;

&lt;p&gt;The transferable principle is to budget latency across the whole turn, not just model inference. Measure speech recognition, orchestration, API calls, model generation, buffering, and speech synthesis as one user experience. When a platform capability is missing, optimize the part the caller perceives. Here, sentence-level delivery mattered more than waiting for a technically ideal streaming path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose orchestration and models by workload
&lt;/h2&gt;

&lt;p&gt;We began with LangChain because it handled tool calling and context well. When AWS introduced Bedrock AgentCore as part of the Strands framework, we moved the orchestration into that stack. Its built-in memory management simplified session handling, and tighter integration with Amazon Connect, AWS Lambda, and DynamoDB reduced the infrastructure the team had to maintain. Keeping orchestration within AWS also matched the client's requirement that the system stay in its AWS environment.&lt;/p&gt;

&lt;p&gt;Model selection followed the same workload-specific reasoning. We tested newer AWS models for speed and integration, but they did not provide the quality required for complex, multistep booking logic. Claude Haiku remained the fast classifier, and Claude Sonnet handled option selection and API execution.&lt;/p&gt;

&lt;p&gt;This split is more useful than choosing one model for every turn. Classification and transactional reasoning have different latency and quality requirements. Test them as separate workloads, then assign each to the least expensive or fastest model that still meets its acceptance criteria. A newer model or a tighter platform integration is not an upgrade if it weakens the critical path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep sensitive operations outside the AI boundary
&lt;/h2&gt;

&lt;p&gt;The agent creates a payment link, but it never handles payment data. Customer identity is verified through the client's own lookup system, and payment remains behind the existing secure Payment API. Prompt guardrails prevent the model from storing or repeating sensitive details beyond the current call. Conversation state is stored in DynamoDB, while policies and rules are retrieved from a Bedrock Knowledge Base.&lt;/p&gt;

&lt;p&gt;That separation narrows what the model can expose or mishandle. The model can guide the transaction and invoke approved operations without becoming the system of record for identity or payment. For transactional agents, define this boundary before refining prompts: list what the model may interpret, what it may initiate, and what must remain entirely inside trusted systems.&lt;/p&gt;

&lt;p&gt;Automation also needs a designed exit. If the agent could not resolve a request within 2 turns, it transferred the call to a human agent with the conversation context and identified customer account intact. The caller did not have to repeat the request.&lt;/p&gt;

&lt;p&gt;This makes escalation part of the architecture rather than an exception. A useful handoff policy needs a trigger, the context to transfer, and a destination capable of continuing the workflow. Together, those pieces let routine calls stay automated while disputes, irregular operations, and distressed customers reach people equipped to help.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>aws</category>
      <category>architecture</category>
    </item>
    <item>
      <title>How to Engineer a Multi-Agent Pipeline for Production Reliability</title>
      <dc:creator>Israel Vásquez</dc:creator>
      <pubDate>Mon, 14 Sep 2026 21:08:21 +0000</pubDate>
      <link>https://dev.to/madebymonogram/how-to-engineer-a-multi-agent-pipeline-for-production-reliability-1n2p</link>
      <guid>https://dev.to/madebymonogram/how-to-engineer-a-multi-agent-pipeline-for-production-reliability-1n2p</guid>
      <description>&lt;p&gt;We built a nine-agent pipeline that turns a natural language use case into working code, an interactive preview, and an implementation guide in under 4 minutes. It serves roughly 800 to 1,000 users per day, but its first production version consumed about 30,000 tokens and made 15 to 20 Pro-tier model calls per request. The useful lesson from this &lt;a href="https://monogram.io/work/multi-agent-ai-solution-generator-for-a-developer-platform" rel="noopener noreferrer"&gt;multi-agent AI implementation&lt;/a&gt; is not simply that more agents can solve a larger problem. It is that production reliability comes from deciding which work belongs to a model, what context must be mandatory, and where strict contracts should replace freeform generation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decompose work around failure boundaries
&lt;/h2&gt;

&lt;p&gt;The system needed to analyze a requested use case, find relevant APIs, generate visual configuration, write code, inspect that code, repair defects, and produce implementation documentation. Putting all of those responsibilities into one prompt would have created an oversized context, less predictable output, and no clean place to isolate failures.&lt;/p&gt;

&lt;p&gt;We divided the workflow into nine agents. A root agent manages session state, routing, and runtime instruction composition. Specialized agents handle analysis, styling, code generation, evaluation, refinement, and documentation. Each receives a narrow responsibility, an explicit input, and an expected output.&lt;/p&gt;

&lt;p&gt;That separation matters because it creates operational boundaries. A style configuration can be validated without rerunning code generation. An evaluator can reject unsafe code without rewriting unrelated sections. Each stage can be tested, tuned, and assigned a model based on the work it performs.&lt;/p&gt;

&lt;p&gt;Decomposition also carries a cost. Every boundary introduces orchestration, state transfer, and another potential failure point. The architecture was appropriate because the workflow already contained distinct tasks with different validation rules. Splitting an arbitrary prompt into several agents would only distribute the ambiguity.&lt;/p&gt;

&lt;p&gt;A practical criterion is to look for independently testable failure modes. If a task can be given a clear contract and evaluated without judging the entire result, it may deserve its own stage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use deterministic code when probability adds no value
&lt;/h2&gt;

&lt;p&gt;Two stages, the Schema Validator and Documentation Builder, make no large language model calls.&lt;/p&gt;

&lt;p&gt;The Schema Validator performs deterministic checks on generated configuration. The Documentation Builder detects APIs in the final code and maps them to documentation URLs from a canonical registry. Neither task benefits from linguistic creativity. Implementing them programmatically removes 2 possible sources of hallucination and reduces token consumption for those stages to zero.&lt;/p&gt;

&lt;p&gt;The same principle shaped the boundaries between code generation, evaluation, and refinement. Asking one agent to generate code and then approve its own output creates a weak feedback loop. We separated the evaluator from the refiner. The evaluator applies strict rules and security scanning; the refiner receives specific findings and makes targeted corrections.&lt;/p&gt;

&lt;p&gt;Every agent that generates code or configuration must also satisfy a structured output schema. This prevents freeform commentary from leaking into machine-consumed output, reduces unnecessary tokens, and gives downstream agents parseable input without an extraction step. More importantly, each handoff becomes independently validatable.&lt;/p&gt;

&lt;p&gt;Models are useful where interpretation or synthesis is required. Validation, lookup, and contract enforcement should remain ordinary software when their rules can be expressed directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make critical context mandatory
&lt;/h2&gt;

&lt;p&gt;The Model Context Protocol, or MCP, gives the analysis, code generation, and code evaluation agents access to live API documentation through an indexed knowledge base. Query results are capped to control context growth, and the MCP server runs as an isolated service so documentation retrieval does not compete with model calls for API quota.&lt;/p&gt;

&lt;p&gt;This keeps knowledge separate from agent code. Documentation can change without requiring the agents to be redeployed.&lt;/p&gt;

&lt;p&gt;Retrieval alone did not solve the correctness problem. MCP tool calls are initiated by the agent, so a confident model can decide that it already knows an API and skip the lookup. That creates a path to plausible but invalid code.&lt;/p&gt;

&lt;p&gt;We addressed that gap with dynamic instruction injection. The analysis stage identifies which APIs a request needs. Canonical examples for those APIs are then inserted directly into downstream instructions. Open-ended questions still use MCP retrieval, while required implementation patterns arrive as mandatory context.&lt;/p&gt;

&lt;p&gt;This distinction is broadly useful. Use optional retrieval for information the model may need to explore. Inject context directly when correctness depends on the model seeing it. After moving from static examples in every prompt to relevant examples selected at runtime, the system reduced per-request token consumption by 73%.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimize from production evidence
&lt;/h2&gt;

&lt;p&gt;The first release used Gemini 2.5 Pro for code generation, evaluation, and refinement. It worked, but using the most capable model throughout the pipeline made both cost and latency unsustainable at production volume.&lt;/p&gt;

&lt;p&gt;The system evolved through five engineering phases. Dynamic instruction injection removed irrelevant prompt material. Model tiering assigned work according to task requirements and made evaluation cycles roughly 70% faster, with no measured loss of quality. Caching and budget controls reduced repeated work, while BigQuery telemetry and structured observability made the effects measurable.&lt;/p&gt;

&lt;p&gt;Reliability work extended beyond average latency. The pipeline includes security auto-fix loops, graceful fallback to the previous valid output, and three-layer retry behavior. Its environments are managed with Terraform across development, staging, and production, with automated CI/CD gates and Google Cloud services including Vertex AI Agent Engine, Cloud Run, Secret Manager, and Cloud Logging.&lt;/p&gt;

&lt;p&gt;The transferable method is to begin with explicit stage contracts, observe production behavior, and optimize the stages that evidence identifies. Model choice, prompt context, retries, caching, and deterministic code are all controls within the same system. Treating them that way turns an agent demo into a service that can deliver consistent results at daily production volume.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>architecture</category>
      <category>googlecloud</category>
    </item>
    <item>
      <title>How we made 2,000 customer conversations queryable in a few hours</title>
      <dc:creator>Israel Vásquez</dc:creator>
      <pubDate>Tue, 08 Sep 2026 20:32:43 +0000</pubDate>
      <link>https://dev.to/madebymonogram/how-we-made-2000-customer-conversations-queryable-in-a-few-hours-a8j</link>
      <guid>https://dev.to/madebymonogram/how-we-made-2000-customer-conversations-queryable-in-a-few-hours-a8j</guid>
      <description>&lt;p&gt;A scheduled run processed roughly 2,000 airline support conversations in a few hours. Once processing finished, leadership could ask questions in plain language and receive answers in seconds without rerunning the analysis.&lt;/p&gt;

&lt;p&gt;That separation between evaluation and retrieval was the central architectural decision.&lt;/p&gt;

&lt;p&gt;In this &lt;a href="https://monogram.io/work/agentic-ai-for-customer-journey-intelligence" rel="noopener noreferrer"&gt;customer journey intelligence project&lt;/a&gt;, we were working with chat logs, voice recordings, routing events, conversation attributes, and agent interaction logs. The data covered the same customer journeys, but it lived in different systems and did not share a reliable schema.&lt;/p&gt;

&lt;h2&gt;
  
  
  Normalize the journey before evaluating it
&lt;/h2&gt;

&lt;p&gt;The model could not evaluate a conversation until the system knew which records belonged together.&lt;/p&gt;

&lt;p&gt;Each environment used a different name for the shared conversation identifier. Timestamps did not always align, and voice and chat records arrived at different levels of detail. We built a normalization layer that mapped each environment into one journey model, then ordered every message, transfer, hold, and resolution chronologically.&lt;/p&gt;

&lt;p&gt;This work was programmatic. The LLM received a coherent customer journey rather than being asked to infer relationships between disconnected records.&lt;/p&gt;

&lt;p&gt;That distinction matters. A capable model can still produce a confident assessment of incomplete evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate analysis from querying
&lt;/h2&gt;

&lt;p&gt;The platform has 2 execution paths.&lt;/p&gt;

&lt;p&gt;The scheduled path joins the source data, transcribes voice with Amazon Transcribe, removes personally identifiable information, and sends the reconstructed journey to Claude Sonnet for evaluation. The results are then stored for later use.&lt;/p&gt;

&lt;p&gt;The interactive path reads those stored results. The dashboard, data explorer, and conversational agent can search and synthesize the analysis, but they do not rescore the original conversations.&lt;/p&gt;

&lt;p&gt;This design fits reporting, incident investigation, and trend analysis, where per-second processing is unnecessary. Batch execution also makes compute usage and LLM costs easier to predict. A team can scope a run to a 50-conversation incident review or a 2,000-conversation monthly analysis.&lt;/p&gt;

&lt;p&gt;Real-time processing would introduce more infrastructure and cost without improving these workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep evaluation criteria outside the model
&lt;/h2&gt;

&lt;p&gt;The system evaluates intent, sentiment, urgency, resolution, compliance, and specialist performance using the client's existing quality rubrics.&lt;/p&gt;

&lt;p&gt;We considered the rubrics part of the application configuration. When the quality team changes a criterion, it can update the prompt instead of collecting new training data and fine-tuning another model.&lt;/p&gt;

&lt;p&gt;Claude Sonnet was selected after smaller models lost accuracy on nuanced criteria, including sentiment across multi-turn conversations and whether an escalation was appropriate. The cheaper model was not cheaper if analysts could not trust its judgments.&lt;/p&gt;

&lt;p&gt;This approach keeps the evaluation process adjustable, but it also requires prompt governance. Rubric changes should be versioned and tested because they change the meaning of every score produced afterward.&lt;/p&gt;

&lt;h2&gt;
  
  
  Remove PII before inference
&lt;/h2&gt;

&lt;p&gt;Redaction runs after journey assembly and before the model receives any content.&lt;/p&gt;

&lt;p&gt;The redaction step is deterministic, applies to every conversation, and consumes no model tokens. Sensitive information does not enter the prompt or appear in stored evaluation results.&lt;/p&gt;

&lt;p&gt;Post-processing model output would have been too late. By that point, the sensitive data would already have crossed the inference boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calibrate against human decisions
&lt;/h2&gt;

&lt;p&gt;An LLM evaluator needs a reference set. We compared its output with conversations the client's analysts had already scored and refined the rubrics where the two diverged.&lt;/p&gt;

&lt;p&gt;Exact agreement reached about 85%. Agreement exceeded 90% when scores within 1 point on the 1-to-10 scales counted as matches.&lt;/p&gt;

&lt;p&gt;Both measurements are useful. Exact agreement reveals consistency, while the tolerance measurement shows whether disagreements are materially different or simply adjacent values on a subjective scale. The acceptable tolerance should be defined before evaluating the model, not chosen afterward to improve the result.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to carry into your own system
&lt;/h2&gt;

&lt;p&gt;For similar analysis platforms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reconstruct the complete domain object before sending it to an LLM.&lt;/li&gt;
&lt;li&gt;Use deterministic code for joins, ordering, validation, and redaction.&lt;/li&gt;
&lt;li&gt;Separate expensive evaluation from latency-sensitive retrieval.&lt;/li&gt;
&lt;li&gt;Keep changing business criteria in versioned rubrics.&lt;/li&gt;
&lt;li&gt;Test model quality against examples scored by domain experts.&lt;/li&gt;
&lt;li&gt;Choose batch or real-time execution from the user workflow, not from the novelty of the architecture.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The conversational agent is the visible part of the product. Its reliability comes from the normalized, redacted, calibrated evidence underneath it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>aws</category>
      <category>llm</category>
    </item>
    <item>
      <title>We ship the AI layer with the code</title>
      <dc:creator>Claudio Fofiu</dc:creator>
      <pubDate>Fri, 04 Sep 2026 18:35:41 +0000</pubDate>
      <link>https://dev.to/madebymonogram/we-ship-the-ai-layer-with-the-code-14pm</link>
      <guid>https://dev.to/madebymonogram/we-ship-the-ai-layer-with-the-code-14pm</guid>
      <description>&lt;p&gt;&lt;em&gt;Every repo we hand back carries instruction files, specs, skills, a DESIGN.md, and an MCP server. What each one is for, and how our people and the agents split the work of building them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When we finish a project, the client keeps the code. That used to be the whole list. Now the layer that drafted the code has to come with it, or the client's own team cannot extend the system the way we did. This is what we leave in the repo, in the order we hand it over.&lt;/p&gt;

&lt;h2&gt;
  
  
  The instruction files
&lt;/h2&gt;

&lt;p&gt;At the root of every repo we hand back sits an AGENTS.md. It says how the system is built, what the pull request gates are, which data may never appear in a prompt, and where the runbooks live. It is the first thing an agent reads and the first thing a new engineer reads, and it is the same file. That is the point.&lt;/p&gt;

&lt;h2&gt;
  
  
  The specs
&lt;/h2&gt;

&lt;p&gt;Requirements that live in chat history die with the session. We keep them in the repo with &lt;a href="https://openspec.dev" rel="noopener noreferrer"&gt;OpenSpec&lt;/a&gt;, an open source spec driven development tool that works with Claude Code, Cursor, Copilot, and most other coding agents. Two folders. openspec/specs holds the current truth about how the system behaves. openspec/changes holds each proposed change as a small folder: a proposal, a design, a task list, and the delta to the specs. The agent works the task list, a person reviews the proposal, and when the change ships the delta folds back into the specs and the folder is archived with a date on it. That archive is where a new engineer goes to learn why the system behaves the way it does.&lt;/p&gt;

&lt;h2&gt;
  
  
  The skills
&lt;/h2&gt;

&lt;p&gt;A skill is a folder of instructions an agent loads when a task calls for it: how to write a migration for this database, how this framework wants a route structured, how to score a support call against the client's own quality rubric.&lt;/p&gt;

&lt;p&gt;Most of a modern stack already has one. Frameworks and databases ship them, or the community maintains them, and they install with one command. When a maintained skill exists for Next.js or &lt;a href="https://www.skills.sh/supabase/agent-skills/supabase" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt; or the agent framework we picked, we use it and stop there. Maintaining our own copy of someone else's knowledge is a way to fall behind.&lt;/p&gt;

&lt;p&gt;When nothing fits, we write our own. The ones we write most often are for the client's own process, because nobody else can: the integration playbook, the rubric a support team uses to grade its own calls, the escalation rules a voice agent has to follow before it hands a caller to a person. Those live in the repo next to the code and change in the same pull requests. An engineer who joins next year and asks the agent to onboard a new data source gets the answer the team agreed on, not the answer the model guessed.&lt;/p&gt;

&lt;h2&gt;
  
  
  DESIGN.md
&lt;/h2&gt;

&lt;p&gt;Design systems used to live in Figma and in the heads of the designers who made them. That worked while people built every screen. Now agents build screens too, and an agent that has never seen your design system produces the internet's average: default spacing, default blue, a card that looks like every other card.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/google-labs-code/design.md" rel="noopener noreferrer"&gt;DESIGN.md&lt;/a&gt; is the fix. It is a plain markdown file at the root of the repo, a format Google Stitch introduced, that gives an agent the design system in the form it can use: tokens with their real values, the type ramp, the spacing habits, the component rules, and the reasoning behind them. When we deliver a design system, the Figma library gets a DESIGN.md twin and the file ships with the code.&lt;/p&gt;

&lt;p&gt;The result is simple to state. A feature the client's team builds with AI six months after we leave looks like it belongs.&lt;/p&gt;

&lt;p&gt;Two cautions we give every client. The file goes stale unless it is versioned with the product, so it changes in the same pull requests as the components. And it does not replace review. Generated UI is still work someone signs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The MCP server
&lt;/h2&gt;

&lt;p&gt;On a customer journey platform we built for a US airline, leadership used to wait two weeks for an analyst to score a handful of calls by hand. Now they ask a conversational agent a question in plain language and get an answer the same day, grounded in every conversation rather than a sample. The agent reads results that were already analyzed and scored. It searches and synthesizes. It never runs the analysis again, which is why the answer comes back in seconds.&lt;/p&gt;

&lt;p&gt;That is the pattern we hand over whenever the data warrants it: an MCP server on the system's APIs, so a person who is not an engineer can connect Claude or ChatGPT and ask for the number instead of hunting for it.&lt;/p&gt;

&lt;p&gt;Picture a VP building a board update. Instead of five dashboards, three filters each, and a screenshot, she asks for last quarter's figures and gets them from the system of record, with the query logged. Signed in, role scoped, logged like any other call. Turning it off is a gateway rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the first draft gets made
&lt;/h2&gt;

&lt;p&gt;The same pattern runs through the whole cycle, and in every stage a person is doing the work. The agent holds the pen for the first pass. In discovery, we still run the interviews and sit with the stakeholders. What changes is that an agent turns the transcripts, the existing documentation, and our notes into a first draft of the glossary and the requirements, with a source cited on every line, and we spend our time arguing with the draft instead of typing it. In design, our designers set the direction and make the calls; agents fan out the variations, the alternate flows, the content, and the edge cases so there is more to choose from, and DESIGN.md keeps all of it on brand. In engineering, the engineer decides the architecture, writes the parts that matter, and hands the agent the scaffolding, the tests, the documentation, and the boring half of debugging. In QA, our people define what has to be true; agents widen the coverage, propose edge cases, run accessibility and responsive checks, and diff the approved design system against what shipped.&lt;/p&gt;

&lt;p&gt;The drafts are wrong in predictable ways. An agent reads a nullable column as required, or names a field by its comment instead of its use. That is why every draft cites its source and every change goes through a reviewed pull request with the same CI gates, whoever wrote it.&lt;/p&gt;

&lt;p&gt;Two habits from our agent work carry over. The evaluator is never the generator, because a model grading its own homework is generous. And anything deterministic gets code, not a model: schema validation, PII redaction, ID mapping. On a nine agent pipeline we built for a developer platform, two of the nine agents make no model calls at all, and those two are the ones that cannot hallucinate.&lt;/p&gt;

&lt;p&gt;Architecture, security, production code, and the final deliverable stay under human review and ownership. AI moves the hours. It does not remove the people who sign.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rules that do not move
&lt;/h2&gt;

&lt;p&gt;No sensitive data goes into a prompt. On the airline platform, PII is stripped before anything reaches the model, deterministically, on every conversation, at zero tokens. On a voice booking agent we built on Amazon Connect, the model creates the payment link and never sees the payment data.&lt;/p&gt;

&lt;p&gt;Nothing generated reaches main without a named reviewer.&lt;/p&gt;

&lt;p&gt;The tooling runs under the client's security, privacy, data governance, and IP requirements, inside boundaries they approve, and nothing about their data trains a model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The handoff has a test
&lt;/h2&gt;

&lt;p&gt;The client names the engineers who will own the system in the first phase, and those engineers get the repos, the instruction files, and the skills in week one. One of them works inside the first build. By the second build, their engineers drive and we review.&lt;/p&gt;

&lt;p&gt;The exit test is simple: their team onboards a full source, or ships a full feature, with us in review only. We write that into acceptance so it is a gate, not a hope. If a team can only do this with us in the room, we did not finish.&lt;/p&gt;

&lt;p&gt;After the last phase, support is pull request review and office hours for the first couple of solo runs. After that it is the phone number, which every client already has.&lt;/p&gt;




&lt;h3&gt;
  
  
  About Monogram
&lt;/h3&gt;

&lt;p&gt;Monogram is an applied AI agency in Atlanta. We design and build production AI systems and the products around them, then hand the whole thing to the client's team. The projects mentioned above are written up on our site:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://monogram.io/work/agentic-ai-for-customer-journey-intelligence" rel="noopener noreferrer"&gt;Agentic AI for customer journey intelligence&lt;/a&gt;, the airline platform&lt;/li&gt;
&lt;li&gt;&lt;a href="https://monogram.io/work/multi-agent-ai-solution-generator-for-a-developer-platform" rel="noopener noreferrer"&gt;A pipeline of nine agents for a developer platform&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;From the team at &lt;a href="https://monogram.io/" rel="noopener noreferrer"&gt;Monogram&lt;/a&gt;, an applied AI agency in Atlanta. This post first ran on our own blog.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;More at &lt;a href="https://monogram.io" rel="noopener noreferrer"&gt;monogram.io&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>development</category>
      <category>architecture</category>
      <category>devops</category>
    </item>
    <item>
      <title>How to Build a Website for Browsers and AI Agents From a Shared Content Model</title>
      <dc:creator>Israel Vásquez</dc:creator>
      <pubDate>Wed, 02 Sep 2026 20:08:22 +0000</pubDate>
      <link>https://dev.to/madebymonogram/how-to-build-a-website-for-browsers-and-ai-agents-from-a-shared-content-model-5dnc</link>
      <guid>https://dev.to/madebymonogram/how-to-build-a-website-for-browsers-and-ai-agents-from-a-shared-content-model-5dnc</guid>
      <description>&lt;p&gt;The &lt;a href="https://monogram.io/work/walden-robotics" rel="noopener noreferrer"&gt;Walden Robotics website&lt;/a&gt; uses 19 reusable content components and publishes 6 discovery surfaces for automated clients. Both start with the same architectural decision: content is modeled once, then delivered in the form each client needs.&lt;/p&gt;

&lt;p&gt;We built the platform with Prismic and the Next.js App Router. Editors assemble pages from structured components, visitors receive generated HTML, and clients that prefer structured text can request Markdown. Discovery endpoints tell automated systems where to find APIs, authorization metadata, agent documentation, and news content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjcnyr12u8nqxxvt973hx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjcnyr12u8nqxxvt973hx.png" alt=" " width="800" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This architecture connects content modeling, delivery, and discovery. HTML and Markdown remain tied to the same records, while the discovery layer identifies the resources available to automated clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the content model before the delivery formats
&lt;/h2&gt;

&lt;p&gt;Every page on the Walden Robotics site is assembled from structured content in Prismic. We created 19 Slice Machine components covering hero sections, calls to action, lead forms, content blocks, navigation, announcements, and supporting layouts.&lt;/p&gt;

&lt;p&gt;A slice defines the fields editors control, while the application controls how those fields render. Editors can combine sections into new pages without changing the component code. Developers retain control over rendering, accessibility, search optimization, and visual consistency.&lt;/p&gt;

&lt;p&gt;The platform also separates page content from shared records. Navigation, footer content, SEO defaults, and global announcements each have a single source of truth. A change to a global announcement is made once in Prismic and reflected wherever the application renders that record.&lt;/p&gt;

&lt;p&gt;That distinction gives the content model clear ownership:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Page content:&lt;/strong&gt; Sections editors arrange within an individual page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global content:&lt;/strong&gt; Navigation, defaults, and announcements shared across routes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Behavioral configuration:&lt;/strong&gt; Form definitions and messages that affect application behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These categories can live in the same CMS, but they do not carry the same risk. Changing a headline affects presentation. Changing a validation rule affects how the application accepts input.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep publication and performance in the same workflow
&lt;/h2&gt;

&lt;p&gt;The site uses the Next.js App Router with static generation, caching, and automatic revalidation when content changes in Prismic. Visitors receive generated pages, while editors can publish updates without requesting a manual rebuild.&lt;/p&gt;

&lt;p&gt;Draft Mode provides a separate path for unpublished work. Authorized editors can preview a page before publication without changing how public traffic is served. Preview remains an editorial state, and the public site keeps the performance characteristics of static delivery.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F19fn8kok9xgdllntrkqr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F19fn8kok9xgdllntrkqr.png" alt=" " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Static generation makes cache freshness an explicit part of publishing. The platform connects Prismic content changes to revalidation, so editors work in the CMS while the application updates its generated output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat CMS-configured forms as untrusted input
&lt;/h2&gt;

&lt;p&gt;Walden's marketing team defines forms in Prismic, including field types, validation rules, placeholder text, and success messages. The same system supports contact forms, campaign landing pages, and promotional experiences.&lt;/p&gt;

&lt;p&gt;Once CMS data controls application behavior, the browser becomes an untrusted boundary. Browser validation improves the user experience, but a user or script can modify a request before submission. The platform signs every form field definition with HMAC before the form reaches the browser and validates the submitted data on the server.&lt;/p&gt;

&lt;p&gt;HMAC, or hash-based message authentication code, uses a secret key to produce a signature for a message. The server can recompute that signature to determine whether the field definition changed after it was issued. HMAC verifies integrity and authenticity; it does not encrypt the definition.&lt;/p&gt;

&lt;p&gt;The form pipeline also accepts requests only from approved Basin endpoints. Honeypot fields, request timeouts, and redirect controls provide additional protection against automated abuse and malicious requests. Each control addresses a separate failure mode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgcyrobj35f6qthnlx7lu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgcyrobj35f6qthnlx7lu.png" alt=" " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The reusable pattern is a trust boundary around behavioral configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sign configuration that crosses an untrusted client.&lt;/li&gt;
&lt;li&gt;Validate submitted data again on the server.&lt;/li&gt;
&lt;li&gt;Restrict the services and destinations that may receive requests.&lt;/li&gt;
&lt;li&gt;Bound external interactions with timeout and redirect controls.&lt;/li&gt;
&lt;li&gt;Combine abuse detection with validation and endpoint restrictions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Editorial flexibility expands what a marketing team can configure; server-side enforcement keeps that flexibility inside defined limits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep operational data in its operating system
&lt;/h2&gt;

&lt;p&gt;The same ownership principle applies to career listings. Available positions come from Rippling's public applicant tracking system, where recruiters already manage openings. The Careers section stays current without requiring marketing or engineering to copy each role into Prismic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr7wxhik0a2qmoqbbk3b9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr7wxhik0a2qmoqbbk3b9.png" alt=" " width="800" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Prismic remains authoritative for the editorial experience around those listings. Rippling remains authoritative for recruiting data. Next.js combines both sources in the rendered page, preserving the workflow of the team responsible for each type of information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Serve HTML and Markdown from the same records
&lt;/h2&gt;

&lt;p&gt;The platform supports HTTP content negotiation, allowing a client to request Markdown when structured text is preferable to HTML. News articles, CMS pages, and supporting content are also available through familiar &lt;code&gt;.md&lt;/code&gt; URLs.&lt;/p&gt;

&lt;p&gt;HTTP content negotiation allows a client and server to select a representation of a resource. On Walden's platform, human visitors can receive the full website experience, while automated clients can receive Markdown generated from the same underlying content.&lt;/p&gt;

&lt;p&gt;Markdown does not replace HTML. HTML carries document semantics, links, interface behavior, and presentation for browsers. Markdown gives clients that primarily need headings, paragraphs, and lists a direct representation of the content. Generating both from Prismic avoids a second editorial repository and keeps the representations tied to the same source records.&lt;/p&gt;

&lt;h2&gt;
  
  
  How will automated clients find the content?
&lt;/h2&gt;

&lt;p&gt;A clean representation has limited value if software has to guess where it lives. Walden's platform publishes 6 discovery surfaces:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;/.well-known/api-catalog&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/.well-known/mcp/server-card.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/.well-known/agent-skills/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/.well-known/oauth-authorization-server&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sitemap.md&lt;/code&gt; with Link headers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/api/news/articles&lt;/code&gt; with an OpenAPI 3.1 description&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Discovery and representation solve different problems. Markdown provides content in a form an automated client can process. Catalogs, descriptions, and Link headers help that client locate the available resources and understand how to use them.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/.well-known/&lt;/code&gt; prefix has a specific role. &lt;a href="https://www.rfc-editor.org/info/rfc8615/" rel="noopener noreferrer"&gt;RFC 8615&lt;/a&gt; defines it as the path prefix for registered well-known locations. Walden's &lt;code&gt;/.well-known/api-catalog&lt;/code&gt; endpoint follows &lt;a href="https://www.rfc-editor.org/rfc/rfc9727.html" rel="noopener noreferrer"&gt;RFC 9727&lt;/a&gt;, which defines a discoverable location and link relation for an API catalog.&lt;/p&gt;

&lt;p&gt;The news API uses &lt;a href="https://spec.openapis.org/oas/v3.1.0.html" rel="noopener noreferrer"&gt;OpenAPI 3.1&lt;/a&gt;, a language-agnostic interface description for HTTP APIs. It allows people and software to understand a service without inspecting its source code or observing network traffic.&lt;/p&gt;

&lt;p&gt;Other resources in the list, including the MCP server card and agent skill documentation, should be described according to the implementation or convention they follow. Placing a resource under &lt;code&gt;/.well-known/&lt;/code&gt; does not automatically make its contents an official standard.&lt;/p&gt;

&lt;h2&gt;
  
  
  What other teams can reuse
&lt;/h2&gt;

&lt;p&gt;The Walden Robotics platform establishes 4 principles that apply beyond this project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keep ownership explicit:&lt;/strong&gt; Store each type of information in the system where the responsible team maintains it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate representations from shared records:&lt;/strong&gt; Use structured content to produce HTML, Markdown, or other formats without duplicating editorial work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apply trust at behavioral boundaries:&lt;/strong&gt; Sign configuration, validate requests on the server, and restrict external interactions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separate delivery from discovery:&lt;/strong&gt; Provide useful representations, then publish the catalogs, descriptions, and links that make them findable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At Monogram, we treat these as parts of the same platform architecture. Content ownership determines what the system can render, validation determines which instructions it can trust, and discovery determines which clients can use the result.&lt;/p&gt;

&lt;p&gt;Use formal standards where they exist, document the remaining surfaces precisely, and keep every representation tied to its authoritative source.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>ai</category>
      <category>architecture</category>
    </item>
    <item>
      <title>AEO for developers: treat content as infrastructure</title>
      <dc:creator>Israel Vásquez</dc:creator>
      <pubDate>Wed, 02 Sep 2026 19:36:40 +0000</pubDate>
      <link>https://dev.to/madebymonogram/aeo-for-developers-treat-content-as-infrastructure-fkj</link>
      <guid>https://dev.to/madebymonogram/aeo-for-developers-treat-content-as-infrastructure-fkj</guid>
      <description>&lt;p&gt;A 2025 Pew Research Center study found that users clicked traditional results in 8% of Google visits with an AI summary, compared with 15% when no summary appeared. Links cited inside those summaries received clicks in only 1% of visits.&lt;/p&gt;

&lt;p&gt;That changes what visibility means. A page can influence a decision without receiving the visit and developers increasingly control whether its information can be found, interpreted, and cited correctly.&lt;/p&gt;

&lt;p&gt;AEO is not a replacement for SEO; it is an additional requirement on the publishing system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the retrieval path
&lt;/h2&gt;

&lt;p&gt;Google says its generative search features still depend on core Search ranking systems and indexed web pages. It also says there are no special technical requirements, machine-readable files, or schema types required for inclusion.&lt;/p&gt;

&lt;p&gt;The familiar foundation still matters: crawlable URLs, accessible text, internal links, canonical tags, accurate metadata, and structured data that matches the visible page. AI Mode and AI Overviews may issue several related searches before assembling a response, so a single prompt can produce multiple retrieval paths through a site.&lt;/p&gt;

&lt;p&gt;For developers, the first AEO audit is straightforward: verify that important information can be reached and rendered without relying on blocked scripts, private APIs, or ambiguous redirects. &lt;a href="https://developers.google.com/search/docs/appearance/ai-features" rel="noopener noreferrer"&gt;Google documents the requirements for AI features in Search&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model facts before adding markup
&lt;/h2&gt;

&lt;p&gt;Schema can help search engines interpret a page, but it cannot repair inconsistent source content.&lt;/p&gt;

&lt;p&gt;Product specifications, authors, publication dates, locations, prices, and availability should be governed fields in the CMS—not details copied independently into page content, metadata, JSON-LD, feeds, and APIs. A shared content model lets each delivery layer draw from the same source.&lt;/p&gt;

&lt;p&gt;This architecture reduces a common failure mode: the page says one thing, the structured data says another, and an external profile contains an older value. AI systems can retrieve every version; they cannot resolve an inconsistency the platform created.&lt;/p&gt;

&lt;p&gt;The practical pattern is simple: model a fact once, validate it, then publish it through the formats that need it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make crawler access an explicit policy
&lt;/h2&gt;

&lt;p&gt;AI platforms use different user agents for different purposes. Search retrieval, user-requested access, and model training should not be treated as a single permission.&lt;/p&gt;

&lt;p&gt;OpenAI, for example, distinguishes &lt;code&gt;OAI-SearchBot&lt;/code&gt;, which supports discovery in ChatGPT search, from &lt;code&gt;GPTBot&lt;/code&gt;, which publishers can block when excluding pages from potential model training. Perplexity separately documents &lt;code&gt;PerplexityBot&lt;/code&gt; for search results and &lt;code&gt;Perplexity-User&lt;/code&gt; for user-triggered access. (&lt;a href="https://help.openai.com/en/articles/12627856-publishers-and-developers-faq" rel="noopener noreferrer"&gt;OpenAI publisher guidance&lt;/a&gt;, &lt;a href="https://docs.perplexity.ai/docs/resources/perplexity-crawlers" rel="noopener noreferrer"&gt;Perplexity crawler documentation&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Encode those decisions across &lt;code&gt;robots.txt&lt;/code&gt;, CDN rules, firewalls, and page-level controls. Then check server logs. A policy file describes the intended behavior; request logs show whether the intended crawler can reach the intended content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measure representation, not only traffic
&lt;/h2&gt;

&lt;p&gt;Rankings and referral sessions remain useful, but they do not show whether an AI-generated response represented the organization accurately.&lt;/p&gt;

&lt;p&gt;Bing Webmaster Tools now reports citations, cited pages, grounding queries, and visibility trends across supported AI experiences. Google has also introduced dedicated generative AI performance reports for a subset of Search Console properties. (&lt;a href="https://blogs.bing.com/webmaster/February-2026/Introducing-AI-Performance-in-Bing-Webmaster-Tools-Public-Preview" rel="noopener noreferrer"&gt;Bing AI Performance&lt;/a&gt;, &lt;a href="https://developers.google.com/search/blog/2026/06/gen-ai-performance-reports" rel="noopener noreferrer"&gt;Google Search Console announcement&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Pair those platform reports with a controlled prompt set. Track which pages are cited, whether important entities and specifications remain accurate, and where responses repeatedly retrieve outdated or incomplete information.&lt;/p&gt;

&lt;p&gt;AEO becomes manageable when it is treated like the rest of the platform: structured inputs, explicit access rules, observable outputs, and regular verification.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>seo</category>
      <category>aeo</category>
      <category>ai</category>
    </item>
    <item>
      <title>Keeping a Next.js Marketing Site Fast Without Slowing Down Marketing</title>
      <dc:creator>Israel Vásquez</dc:creator>
      <pubDate>Mon, 31 Aug 2026 16:19:04 +0000</pubDate>
      <link>https://dev.to/madebymonogram/keeping-a-nextjs-marketing-site-fast-without-slowing-down-marketing-3d8l</link>
      <guid>https://dev.to/madebymonogram/keeping-a-nextjs-marketing-site-fast-without-slowing-down-marketing-3d8l</guid>
      <description>&lt;p&gt;A fast marketing site is relatively easy to build when very little is happening on it.&lt;/p&gt;

&lt;p&gt;The harder version has large hero media, analytics, advertising tools, CRM forms, a headless CMS, content previews, and a marketing team that needs to publish without waiting for an engineer.&lt;/p&gt;

&lt;p&gt;That was part of the challenge when Monogram built Kasada's new website.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff328t6j7o8w5ugffsysz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff328t6j7o8w5ugffsysz.png" alt=" " width="800" height="616"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kasada is a cybersecurity company, so the platform also needed to communicate technical credibility. But performance could not come at the cost of the workflows required to actually run the website.&lt;/p&gt;

&lt;p&gt;The interesting engineering problem became: &lt;strong&gt;how do you protect frontend performance without turning performance into a restriction for marketing?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance is an architectural problem
&lt;/h2&gt;

&lt;p&gt;It is easy to treat web performance as an optimization phase.&lt;/p&gt;

&lt;p&gt;Compress some images. Lazy load a few resources. Run Lighthouse. Fix the obvious problems.&lt;/p&gt;

&lt;p&gt;That approach becomes fragile on a marketing platform because the website keeps changing.&lt;/p&gt;

&lt;p&gt;New campaigns appear. Analytics tools are added. Advertising scripts change. Editors replace media. Landing pages are assembled differently. Forms appear in new places.&lt;/p&gt;

&lt;p&gt;Performance therefore cannot depend entirely on engineers manually reviewing every page.&lt;/p&gt;

&lt;p&gt;For Kasada, Monogram built the site with the Next.js App Router and created caching and revalidation strategies around its content heavy architecture. Published pages could benefit from static generation and optimized asset delivery, while editors still had draft and live preview workflows inside Sanity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyqmvleszvty29nk52737.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyqmvleszvty29nk52737.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The important distinction is that &lt;strong&gt;editorial flexibility and production rendering do not have to follow the same execution model.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An editor needs current draft content.&lt;/p&gt;

&lt;p&gt;A visitor usually needs the latest published version, delivered as efficiently as possible.&lt;/p&gt;

&lt;p&gt;Treating those as separate requirements gives the application more room to optimize both.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rich media needs guardrails too
&lt;/h2&gt;

&lt;p&gt;Scripts are not the only source of performance problems on marketing sites.&lt;/p&gt;

&lt;p&gt;Hero sections are particularly dangerous because they combine two competing goals. They are usually the most visually important content on the page, but they can also contain some of its heaviest assets.&lt;/p&gt;

&lt;p&gt;Kasada's implementation included specific performance work around hero media rather than treating media optimization as a generic concern.&lt;/p&gt;

&lt;p&gt;That suggests a useful design system principle:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance constraints should live as close as possible to the components capable of creating performance problems.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If every editor can independently decide how a large hero asset is loaded, performance becomes dependent on individual publishing decisions.&lt;/p&gt;

&lt;p&gt;If the component owns the important delivery behavior, editors can change content without also needing to become performance engineers.&lt;/p&gt;

&lt;p&gt;This is one of the less visible advantages of connecting a CMS to a controlled component system.&lt;/p&gt;

&lt;p&gt;The CMS provides flexibility over content.&lt;/p&gt;

&lt;p&gt;The component defines the technical boundaries around how that content reaches the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Third party scripts are part of your performance budget
&lt;/h2&gt;

&lt;p&gt;Marketing platforms rarely control every resource they execute.&lt;/p&gt;

&lt;p&gt;Analytics and advertising tools introduce JavaScript from systems outside the application's core bundle. Those tools may be necessary for attribution, campaign measurement, or other business requirements, so simply removing them is often not a realistic engineering recommendation.&lt;/p&gt;

&lt;p&gt;Kasada had this exact constraint.&lt;/p&gt;

&lt;p&gt;Monogram implemented audit aware loading for production analytics and advertising integrations, specifically to prevent those tools from unnecessarily degrading performance measurements and Core Web Vitals.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9kym0750qzp4vf9qrpht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9kym0750qzp4vf9qrpht.png" alt=" " width="800" height="602"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The broader lesson is more important than the specific implementation.&lt;/p&gt;

&lt;p&gt;A third party script should not become invisible to the architecture simply because your team does not own its code.&lt;/p&gt;

&lt;p&gt;It still consumes browser resources.&lt;/p&gt;

&lt;p&gt;It can still compete with rendering work.&lt;/p&gt;

&lt;p&gt;It can still affect Core Web Vitals.&lt;/p&gt;

&lt;p&gt;And it can still change independently of your application.&lt;/p&gt;

&lt;p&gt;That means third party integrations deserve the same architectural questions as other dependencies:&lt;/p&gt;

&lt;p&gt;What does this script need to do? When does it need to execute? Which pages actually require it? What happens to the user experience when it becomes expensive?&lt;/p&gt;

&lt;p&gt;Performance engineering on a marketing website is partly dependency management.&lt;/p&gt;

&lt;h2&gt;
  
  
  Marketing capabilities should reuse infrastructure
&lt;/h2&gt;

&lt;p&gt;Protecting performance does not mean preventing marketing from adding functionality.&lt;/p&gt;

&lt;p&gt;The better approach is to make common capabilities reusable.&lt;/p&gt;

&lt;p&gt;Kasada's HubSpot integration demonstrates this on the lead generation side. Forms were incorporated into the reusable content section library instead of being implemented independently across landing pages and campaigns. Form validation and visual behavior could therefore remain aligned with the rest of the platform while submissions flowed into Kasada's CRM.&lt;/p&gt;

&lt;p&gt;This is useful beyond forms.&lt;/p&gt;

&lt;p&gt;If a capability will appear repeatedly across a website, implementing it as shared infrastructure creates a place where engineering constraints can be enforced once.&lt;/p&gt;

&lt;p&gt;That might include rendering behavior, validation, accessibility, script loading, or integration logic.&lt;/p&gt;

&lt;p&gt;The alternative is allowing each page to solve the same problem independently.&lt;/p&gt;

&lt;p&gt;That gives teams flexibility quickly, but it also creates multiple places where performance and maintainability can deteriorate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimize the system, not just the launch
&lt;/h2&gt;

&lt;p&gt;The most important performance decision in a large marketing project often happens before anyone opens a performance profiler.&lt;/p&gt;

&lt;p&gt;It is deciding who controls what.&lt;/p&gt;

&lt;p&gt;On Kasada's website, Sanity gives marketers control over structured content and page composition. The component system gives engineering control over rendering behavior and design consistency. Next.js provides the production rendering, caching, and revalidation layer. External marketing systems remain integrated without being allowed to define the architecture of the application.&lt;/p&gt;

&lt;p&gt;That division of responsibility matters because the website is not frozen after launch.&lt;/p&gt;

&lt;p&gt;Editors will publish.&lt;/p&gt;

&lt;p&gt;Campaigns will change.&lt;/p&gt;

&lt;p&gt;New integrations will appear.&lt;/p&gt;

&lt;p&gt;Media will be replaced.&lt;/p&gt;

&lt;p&gt;If performance depends on everything remaining exactly as it was on launch day, the architecture has already failed.&lt;/p&gt;

&lt;p&gt;A more durable approach is to build performance expectations into the places where future changes will happen.&lt;/p&gt;

&lt;p&gt;For a CMS driven Next.js site, that means thinking beyond Lighthouse scores and asking:&lt;/p&gt;

&lt;p&gt;Which content can be delivered statically?&lt;br&gt;
What actually needs revalidation?&lt;br&gt;
How will editors preview unpublished changes?&lt;br&gt;
Which components can introduce expensive media?&lt;br&gt;
Which external scripts can affect rendering?&lt;br&gt;
Which recurring marketing capabilities should become shared infrastructure?&lt;/p&gt;

&lt;p&gt;Those questions are less exciting than choosing a new framework.&lt;/p&gt;

&lt;p&gt;They are also much more likely to determine whether the site is still fast six months after launch.&lt;/p&gt;

&lt;p&gt;That was the useful lesson from Kasada: &lt;strong&gt;performance works better as a constraint of the platform than as a cleanup task for individual pages.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>webperf</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Designing a Website for Humans and AI</title>
      <dc:creator>Israel Vásquez</dc:creator>
      <pubDate>Thu, 27 Aug 2026 14:45:02 +0000</pubDate>
      <link>https://dev.to/madebymonogram/designing-a-website-for-humans-and-ai-1b5g</link>
      <guid>https://dev.to/madebymonogram/designing-a-website-for-humans-and-ai-1b5g</guid>
      <description>&lt;p&gt;CrewAI's website had to do something that traditional marketing sites rarely need to do: serve several very different consumers from the same digital platform.&lt;/p&gt;

&lt;p&gt;An executive might be evaluating CrewAI as an enterprise AI platform. A developer might be looking for documentation or an integration example. A content team needs to publish and manage pages. An AI assistant needs structured information it can retrieve without parsing a visual interface.&lt;/p&gt;

&lt;p&gt;That changed the architectural problem.&lt;/p&gt;

&lt;p&gt;The project included 7 dedicated discovery surfaces for AI systems, a Contentful based content architecture, an automated publishing pipeline from Ghost to Contentful, centralized HubSpot form infrastructure, Markdown content delivery, OpenAPI documentation, OAuth discovery, and a Model Context Protocol (MCP) implementation.&lt;/p&gt;

&lt;p&gt;The important lesson was not simply to add AI features to a website. It was to make the underlying content and application architecture usable by both people and machines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the content model, not the page
&lt;/h2&gt;

&lt;p&gt;One of the easiest ways for a large website to become difficult to maintain is to model the system around pages.&lt;/p&gt;

&lt;p&gt;A page based architecture often leads to individual templates, custom layouts, and content embedded directly into those layouts. As the number of content types grows, the system becomes harder for marketing teams to operate and harder for engineers to change safely.&lt;/p&gt;

&lt;p&gt;For CrewAI, the approach was different.&lt;/p&gt;

&lt;p&gt;The experience began in Figma as a design system, rather than as a collection of individual page designs. The resulting component library included hero layouts, platform diagrams, pricing sections, feature grids, statistics modules, tabbed content, media blocks, and technical documentation.&lt;/p&gt;

&lt;p&gt;Those components were then connected to structured models in Contentful.&lt;/p&gt;

&lt;p&gt;That relationship matters:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Design component → structured content model → application rendering&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of treating the CMS as a place to store finished pages, the CMS became part of the application's content architecture.&lt;/p&gt;

&lt;p&gt;Marketing could compose pages from reusable sections, while engineering retained control over how those sections were rendered, integrated, measured, and maintained.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh95a8eap7cbj3nktqm8f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh95a8eap7cbj3nktqm8f.png" alt=" " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The application used GraphQL and TypeScript to retrieve and render the structured content.&lt;/p&gt;

&lt;p&gt;This is a useful distinction when designing a modern CMS architecture. A component library is more valuable when its content representation is designed at the same time as its visual representation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The CMS does not have to be the writing tool
&lt;/h2&gt;

&lt;p&gt;There was another architectural constraint: the editorial team already used Ghost for writing.&lt;/p&gt;

&lt;p&gt;Replacing that workflow simply because the public website used Contentful would have solved an engineering problem by creating a content problem.&lt;/p&gt;

&lt;p&gt;Instead, the project connected the two systems.&lt;/p&gt;

&lt;p&gt;When an article is published in Ghost, an automated workflow converts it into a draft in Contentful.&lt;/p&gt;

&lt;p&gt;The important detail is where the automation stops.&lt;/p&gt;

&lt;p&gt;Ghost remains the writing environment.&lt;/p&gt;

&lt;p&gt;Contentful becomes the controlled publishing environment.&lt;/p&gt;

&lt;p&gt;That means the workflow looks roughly like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Writer → Ghost → automated content transfer → Contentful draft → review and enrichment → publication&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The system deliberately does not automatically publish the article from Ghost.&lt;/p&gt;

&lt;p&gt;That creates a useful boundary between authoring and publishing.&lt;/p&gt;

&lt;p&gt;The editorial team can continue using the tool optimized for writing, while marketing can manage metadata, SEO, page composition, scheduling, and other publishing concerns in the system responsible for the public website.&lt;/p&gt;

&lt;p&gt;This is a broader architectural lesson: when two systems have different strengths, integration can be better than forcing one system to perform both jobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic forms should be treated as infrastructure
&lt;/h2&gt;

&lt;p&gt;Lead generation introduced another integration problem.&lt;/p&gt;

&lt;p&gt;Rather than creating isolated forms for different parts of the website, the platform centralized its HubSpot integration.&lt;/p&gt;

&lt;p&gt;Forms retrieve their structure directly from the HubSpot Marketing Forms API during page rendering. Submissions are validated with Zod before they reach HubSpot.&lt;/p&gt;

&lt;p&gt;The validation layer also enforces a business email requirement by blocking more than 40 consumer email providers, including Gmail, Yahoo, and Outlook.&lt;/p&gt;

&lt;p&gt;The same infrastructure handles attribution using HubSpot cookies, referral information, and page context.&lt;/p&gt;

&lt;p&gt;It also supports different confirmation behaviors, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inline success messages&lt;/li&gt;
&lt;li&gt;Redirects&lt;/li&gt;
&lt;li&gt;Embedded Calendly scheduling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This matters because a form is rarely just a collection of input fields in an enterprise website.&lt;/p&gt;

&lt;p&gt;It is part of a larger data flow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Form definition → validation → attribution → CRM submission → confirmation experience&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Centralizing that flow reduces the chance that different forms implement business rules differently.&lt;/p&gt;

&lt;p&gt;It also means new forms can reuse the same integration and validation infrastructure instead of introducing another custom path to the CRM.&lt;/p&gt;

&lt;h2&gt;
  
  
  The website became a structured knowledge source
&lt;/h2&gt;

&lt;p&gt;The most unusual part of the project was treating the website as something that AI systems should be able to consume directly.&lt;/p&gt;

&lt;p&gt;A conventional website is primarily optimized around human navigation.&lt;/p&gt;

&lt;p&gt;Information is organized into visual layouts, navigation menus, HTML documents, and interactive interfaces. A person can interpret those layers together.&lt;/p&gt;

&lt;p&gt;An AI system does not necessarily need those layers.&lt;/p&gt;

&lt;p&gt;It benefits from clear, structured representations of the same underlying information.&lt;/p&gt;

&lt;p&gt;The CrewAI platform therefore supports Markdown content delivery. Blog posts, documentation, webinars, case studies, events, and CMS pages can be requested as structured Markdown through dedicated routes or .md URLs.&lt;/p&gt;

&lt;p&gt;That creates an additional representation of the content without requiring an AI system to reverse engineer the rendered page.&lt;/p&gt;

&lt;p&gt;The architectural principle is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do not make every consumer understand the presentation layer when the underlying content can be exposed directly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Markdown is useful for this because it provides a lightweight, structured representation of content that can be consumed by developer tools, automation systems, and AI applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Discovery is a separate architectural problem
&lt;/h2&gt;

&lt;p&gt;Providing structured content solves only part of the problem.&lt;/p&gt;

&lt;p&gt;A machine still needs to discover what exists.&lt;/p&gt;

&lt;p&gt;The CrewAI platform exposes 7 documented discovery surfaces:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;llms.txt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;llms-full.txt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;openapi.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/.well-known/mcp/server-card.json&lt;/code&gt;
5.&lt;code&gt;/.well-known/oauth-authorization-server&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sitemap.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/brand/knowledge-graph&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These surfaces serve different purposes.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;llms.txt&lt;/code&gt; and &lt;code&gt;llms-full.txt&lt;/code&gt; resources provide AI oriented descriptions of the site's capabilities and resources.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;openapi.json&lt;/code&gt; exposes an API description using OpenAPI 3.1.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.well-known&lt;/code&gt; resources provide machine discoverable information related to MCP and OAuth authorization.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sitemap.md&lt;/code&gt; provides a structured representation of site content.&lt;/p&gt;

&lt;p&gt;The brand knowledge graph provides another machine readable representation of the organization's information.&lt;/p&gt;

&lt;p&gt;The important architectural point is that these are not seven copies of the same content.&lt;/p&gt;

&lt;p&gt;They are different interfaces into the same digital system.&lt;/p&gt;

&lt;p&gt;That distinction becomes increasingly important as websites are consumed by more types of software.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP turns APIs into agent accessible capabilities
&lt;/h2&gt;

&lt;p&gt;The project also implemented the &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;MCP is an open protocol for connecting AI applications with external data sources and tools. Its specification defines mechanisms through which servers can expose resources, prompts, and tools to clients.&lt;/p&gt;

&lt;p&gt;For CrewAI, the implementation mirrors public REST APIs through a consistent collection of tools.&lt;/p&gt;

&lt;p&gt;Agents can discover capabilities, authenticate using OAuth, and retrieve resources such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blog posts&lt;/li&gt;
&lt;li&gt;Webinars&lt;/li&gt;
&lt;li&gt;Events&lt;/li&gt;
&lt;li&gt;Case studies&lt;/li&gt;
&lt;li&gt;Developer resources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is different from simply making a website "AI searchable."&lt;/p&gt;

&lt;p&gt;Search gives an AI system information about a website.&lt;/p&gt;

&lt;p&gt;An API gives software a defined way to retrieve information.&lt;/p&gt;

&lt;p&gt;A protocol such as MCP provides a standardized interface through which compatible AI applications can discover and interact with capabilities.&lt;/p&gt;

&lt;p&gt;That difference matters when deciding how much of a platform should be exposed to intelligent systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why OAuth matters here
&lt;/h2&gt;

&lt;p&gt;Once an application exposes capabilities to external software, discovery alone is not enough.&lt;/p&gt;

&lt;p&gt;The system also needs a way to establish who is authorized to access protected capabilities.&lt;/p&gt;

&lt;p&gt;That is why OAuth discovery is part of the architecture.&lt;/p&gt;

&lt;p&gt;The platform exposes an OAuth authorization server discovery endpoint alongside its MCP implementation.&lt;/p&gt;

&lt;p&gt;The result is a more complete machine interaction model:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Discover → authenticate → access capabilities → retrieve structured content&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The exact authentication requirements depend on the capability being exposed, but the architectural principle is broadly useful: machine readable discovery and authorization should be designed together rather than treated as unrelated features.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebMCP adds another interaction surface
&lt;/h2&gt;

&lt;p&gt;The platform also supports WebMCP when the browser supports it.&lt;/p&gt;

&lt;p&gt;This allows AI interactions to occur directly within the page rather than requiring every interaction to be performed through a separate server request.&lt;/p&gt;

&lt;p&gt;That introduces an interesting distinction between two types of AI integration.&lt;/p&gt;

&lt;p&gt;The first is &lt;strong&gt;server side access&lt;/strong&gt;, where an external agent discovers and calls APIs or MCP tools.&lt;/p&gt;

&lt;p&gt;The second is &lt;strong&gt;in page interaction&lt;/strong&gt;, where an AI capable browser can interact with capabilities exposed by the page itself.&lt;/p&gt;

&lt;p&gt;The two approaches solve different problems.&lt;/p&gt;

&lt;p&gt;A developer building an integration may want API or MCP access.&lt;/p&gt;

&lt;p&gt;A user interacting with an AI enabled browser may benefit from capabilities exposed directly by the web experience.&lt;/p&gt;

&lt;p&gt;Designing for both means the website becomes more than a destination. It becomes an interface that different classes of clients can use.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real architecture is the combination
&lt;/h2&gt;

&lt;p&gt;None of these individual technologies is particularly useful as a standalone checklist.&lt;/p&gt;

&lt;p&gt;Contentful does not automatically make a website AI ready.&lt;/p&gt;

&lt;p&gt;Markdown does not automatically create a useful AI interface.&lt;/p&gt;

&lt;p&gt;An OpenAPI document does not automatically create a good developer experience.&lt;/p&gt;

&lt;p&gt;MCP does not replace a well structured content architecture.&lt;/p&gt;

&lt;p&gt;The value comes from connecting them.&lt;/p&gt;

&lt;p&gt;The resulting architecture can be understood as several layers:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr71ker9cfwm5kbxc1334.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr71ker9cfwm5kbxc1334.png" alt=" " width="800" height="761"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The exact implementation is more complex than this simplified model, but the principle is important.&lt;/p&gt;

&lt;p&gt;There is a shared application and content foundation, with different interfaces optimized for different consumers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this architecture teaches
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Model content as structured data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If content is represented as reusable structured entities, it can support more than one presentation layer.&lt;/p&gt;

&lt;p&gt;That benefits traditional web development first. AI consumption becomes an additional advantage rather than the sole reason for structuring content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Separate authoring from publishing when workflows require it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Ghost and Contentful integration demonstrates that a CMS migration does not have to mean replacing every existing editorial tool.&lt;/p&gt;

&lt;p&gt;The better question is:&lt;/p&gt;

&lt;p&gt;Which system should own each part of the workflow?&lt;/p&gt;

&lt;p&gt;In this case, Ghost owns writing, while Contentful owns structured website publishing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Build integrations as shared infrastructure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The HubSpot implementation centralizes validation, attribution, form configuration, and confirmation behavior.&lt;/p&gt;

&lt;p&gt;That is more maintainable than allowing every form to develop its own integration logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Expose information in the representation the consumer needs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Humans benefit from visual interfaces.&lt;/p&gt;

&lt;p&gt;Developers benefit from APIs and documentation.&lt;/p&gt;

&lt;p&gt;AI systems benefit from structured content, explicit discovery mechanisms, and machine accessible capabilities.&lt;/p&gt;

&lt;p&gt;There is no requirement for all of those consumers to use exactly the same representation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Treat AI readiness as an architectural concern&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Adding an AI chatbot to an existing website is one possible AI feature.&lt;/p&gt;

&lt;p&gt;Making the underlying content, APIs, discovery mechanisms, authentication, and application capabilities accessible to intelligent systems is a much broader architectural decision.&lt;/p&gt;

&lt;p&gt;The CrewAI project demonstrates the latter approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  When this architecture makes sense
&lt;/h2&gt;

&lt;p&gt;This approach is not necessary for every website.&lt;/p&gt;

&lt;p&gt;A small marketing site with a handful of static pages probably does not need a CMS integration spanning multiple editorial systems, an OpenAPI description, MCP capabilities, or multiple machine discovery surfaces.&lt;/p&gt;

&lt;p&gt;The complexity becomes more justified when a platform has several audiences and several systems that need to consume the same information.&lt;/p&gt;

&lt;p&gt;That includes enterprise AI companies, developer platforms, documentation heavy products, SaaS companies with extensive APIs, and organizations expecting their content to be consumed by increasingly autonomous software.&lt;/p&gt;

&lt;p&gt;The key is to start with the consumption model.&lt;/p&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Who needs to consume this content?&lt;/li&gt;
&lt;li&gt;Which parts need to be structured?&lt;/li&gt;
&lt;li&gt;Which capabilities should be exposed as APIs?&lt;/li&gt;
&lt;li&gt;How will external systems discover them?&lt;/li&gt;
&lt;li&gt;Which capabilities require authentication?&lt;/li&gt;
&lt;li&gt;Which workflows should remain controlled by humans?&lt;/li&gt;
&lt;li&gt;Which systems should own authoring, publishing, and data validation?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those questions produce better architecture than starting with a technology shopping list.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bigger lesson
&lt;/h2&gt;

&lt;p&gt;The most interesting part of the CrewAI project was not that the website used Next.js, Contentful, GraphQL, Vercel, OpenAPI, OAuth, or MCP.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgtci44t8ie9j1ov6e9ko.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgtci44t8ie9j1ov6e9ko.png" alt=" " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was that those technologies were connected around a common idea: the website should be useful to whatever is consuming it.&lt;/p&gt;

&lt;p&gt;For humans, that means a coherent design system and an intentional digital experience.&lt;/p&gt;

&lt;p&gt;For content teams, it means structured publishing workflows with appropriate editorial control.&lt;/p&gt;

&lt;p&gt;For developers, it means APIs, documentation, and predictable interfaces.&lt;/p&gt;

&lt;p&gt;For AI systems, it means machine readable content, explicit discovery, authentication, and protocol based access to capabilities.&lt;/p&gt;

&lt;p&gt;That is a more useful definition of an AI ready website.&lt;/p&gt;

&lt;p&gt;It is not a page with an AI feature attached to it.&lt;/p&gt;

&lt;p&gt;It is a digital platform whose architecture gives both people and intelligent systems clear ways to understand, navigate, and interact with the information and capabilities it provides.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>architecture</category>
      <category>nextjs</category>
    </item>
  </channel>
</rss>
