<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 920 320" font-family="Consolas, 'Courier New', monospace">
  <defs>
    <marker id="ah" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0L10 5L0 10z" fill="#888"/></marker>
    <marker id="ahg" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0L10 5L0 10z" fill="#98c379"/></marker>
    <marker id="ahr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0L10 5L0 10z" fill="#e06c75"/></marker>
  </defs>

  <text x="20" y="22" fill="#d4d4d4" font-size="12" font-weight="bold">Incremental cook decisions</text>
  <text x="184" y="22" fill="#666" font-size="10">validate first, only process when the cache cannot prove the output is current</text>

  <rect x="52" y="54" width="190" height="56" rx="5" fill="#1a3050" stroke="#4a8fd4" stroke-width="1.1"/>
  <text x="147" y="78" fill="#d4d4d4" font-size="10" text-anchor="middle">Source + metadata</text>
  <text x="147" y="94" fill="#7ab0e0" font-size="8" text-anchor="middle">processor + dependencies</text>

  <rect x="355" y="54" width="210" height="56" rx="5" fill="#2a1a40" stroke="#9a6be8" stroke-width="1.1"/>
  <text x="460" y="78" fill="#d4d4d4" font-size="10" text-anchor="middle">DataCache validation</text>
  <text x="460" y="94" fill="#b88ae8" font-size="8" text-anchor="middle">dates → hashes when needed</text>
  <path d="M244 82 L350 82" stroke="#888" stroke-width="1.2" fill="none" marker-end="url(#ah)"/>

  <rect x="690" y="42" width="180" height="44" rx="4" fill="#1e3323" stroke="#98c379" stroke-width="1.1"/>
  <text x="780" y="61" fill="#d4d4d4" font-size="10" text-anchor="middle">Data up to date</text>
  <text x="780" y="75" fill="#98c379" font-size="8" text-anchor="middle">do nothing</text>
  <path d="M567 67 L685 64" stroke="#98c379" stroke-width="1.2" fill="none" marker-end="url(#ahg)"/>
  <text x="622" y="56" fill="#98c379" font-size="8" text-anchor="middle">output matches</text>

  <rect x="690" y="112" width="180" height="44" rx="4" fill="#40301a" stroke="#e8a46b" stroke-width="1.1"/>
  <text x="780" y="131" fill="#d4d4d4" font-size="10" text-anchor="middle">Cache copy required</text>
  <text x="780" y="145" fill="#d4a46b" font-size="8" text-anchor="middle">restore payload + header</text>
  <path d="M567 88 L685 130" stroke="#e8a46b" stroke-width="1.2" fill="none" marker-end="url(#ah)"/>
  <text x="618" y="122" fill="#e8a46b" font-size="8" text-anchor="middle">cache valid, Data stale</text>

  <rect x="350" y="205" width="220" height="52" rx="5" fill="#4a2020" stroke="#e06c75" stroke-width="1.2"/>
  <text x="460" y="227" fill="#d4d4d4" font-size="10" text-anchor="middle">Data cook required</text>
  <text x="460" y="243" fill="#e06c75" font-size="8" text-anchor="middle">run the processor again</text>
  <path d="M460 112 L460 200" stroke="#e06c75" stroke-width="1.2" fill="none" marker-end="url(#ahr)"/>
  <text x="485" y="166" fill="#e06c75" font-size="8">input or cache changed</text>

  <rect x="690" y="208" width="180" height="44" rx="4" fill="#1e3323" stroke="#98c379" stroke-width="1.1"/>
  <text x="780" y="227" fill="#d4d4d4" font-size="10" text-anchor="middle">Write cache + Data</text>
  <text x="780" y="241" fill="#98c379" font-size="8" text-anchor="middle">payload hash recorded</text>
  <path d="M572 231 L685 231" stroke="#98c379" stroke-width="1.2" fill="none" marker-end="url(#ahg)"/>

  <text x="460" y="294" fill="#555" font-size="9" text-anchor="middle">Transient assets always take the cook-required path and never create a permanent cache record.</text>
</svg>
