syntaxai/tdd.md · main · public / sama-layers.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 600" width="1200" height="600">
<rect width="1200" height="600" fill="#0a0a0a"/>
<!-- Header — the Law is the main message, scaled up -->
<g font-family="ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace">
<text x="120" y="46" font-size="20" font-weight="600" fill="#909090">The four canonical layers</text>
<text x="120" y="92" font-size="38" font-weight="700" fill="#e8e8e8">Imports only flow downward.</text>
<text x="120" y="122" font-size="16" fill="#7a7a7a">never upward · never sideways · never cyclic — SAMA v2 §1.2 the Law</text>
</g>
<!-- Layer 3 · Entry (top — warm/volatile) -->
<rect x="120" y="148" width="960" height="80" fill="#1a1a1a" stroke="#2a2a2a" stroke-width="1.5" rx="6"/>
<rect x="120" y="148" width="8" height="80" fill="#c89a3a" rx="3"/>
<g font-family="ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace">
<text x="160" y="182" font-size="24" font-weight="600" fill="#e8e8e8">Layer 3 · Entry</text>
<text x="160" y="210" font-size="15" fill="#8a8a8a">outermost shell — main · CLI handler · HTTP route · UI mount · job entry</text>
<text x="1060" y="195" text-anchor="end" font-size="17" font-style="italic" fill="#c89a3a">POST /checkout</text>
</g>
<text x="600" y="246" text-anchor="middle" font-family="ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace" font-size="13" fill="#6a6a6a">↓ uses</text>
<!-- Layer 2 · Adapter (boundary — warm) -->
<rect x="120" y="253" width="960" height="80" fill="#1a1a1a" stroke="#2a2a2a" stroke-width="1.5" rx="6"/>
<rect x="120" y="253" width="8" height="80" fill="#b8794a" rx="3"/>
<g font-family="ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace">
<text x="160" y="287" font-size="24" font-weight="600" fill="#e8e8e8">Layer 2 · Adapter</text>
<text x="160" y="315" font-size="15" fill="#8a8a8a">the boundary — DB · network · filesystem · framework bindings · external input parsed here</text>
<text x="1060" y="300" text-anchor="end" font-size="17" font-style="italic" fill="#b8794a">Stripe.charges.create()</text>
</g>
<text x="600" y="351" text-anchor="middle" font-family="ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace" font-size="13" fill="#6a6a6a">↓ uses</text>
<!-- Layer 1 · Core (cool — stable) -->
<rect x="120" y="358" width="960" height="80" fill="#1a1a1a" stroke="#2a2a2a" stroke-width="1.5" rx="6"/>
<rect x="120" y="358" width="8" height="80" fill="#4a8a8a" rx="3"/>
<g font-family="ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace">
<text x="160" y="392" font-size="24" font-weight="600" fill="#e8e8e8">Layer 1 · Core</text>
<text x="160" y="420" font-size="15" fill="#8a8a8a">domain decisions — business logic · policies · pure render — no network, disk, clock, framework</text>
<text x="1060" y="405" text-anchor="end" font-size="17" font-style="italic" fill="#4a8a8a">applyPaymentRules()</text>
</g>
<text x="600" y="456" text-anchor="middle" font-family="ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace" font-size="13" fill="#6a6a6a">↓ uses</text>
<!-- Layer 0 · Pure (bottom — coolest, mathematical foundation) -->
<rect x="120" y="463" width="960" height="80" fill="#1a1a1a" stroke="#2a2a2a" stroke-width="1.5" rx="6"/>
<rect x="120" y="463" width="8" height="80" fill="#4a9a5a" rx="3"/>
<g font-family="ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace">
<text x="160" y="497" font-size="24" font-weight="600" fill="#e8e8e8">Layer 0 · Pure</text>
<text x="160" y="525" font-size="15" fill="#8a8a8a">deterministic primitives — types · constants · pure functions — no I/O, no side effects</text>
<text x="1060" y="510" text-anchor="end" font-size="17" font-style="italic" fill="#4a9a5a">Money(amount, currency)</text>
</g>
<!-- Worked-example caption -->
<text x="120" y="582" font-family="ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace" font-size="13" fill="#6a6a6a">
Worked example, threaded through a checkout flow — each italic line shows what that layer would actually do.
</text>
</svg>