Skip to content

Commit d6a9f08

Browse files
committed
site: code blocks become generated-snippet placeholders
Fifteen hand-written code blocks across three pages become `<pre class="example-code" data-snippet="<id>"></pre>`, filled at deploy time from the payload the MetaObjects repo builds and gates. Eleven on index.html, two on requirements.html, two on the prompts article — exactly the fifteen ids in that repo's snippet registry, which is where they were read from rather than typed. DO NOT PUSH YET. The deploy step that fills them does not exist until the next task, so these pages would go live with fifteen empty blocks. Two blocks on index.html stay hand-written, correctly: the assess.md prompt is something the reader pastes, and the CLI-commands block is shell. That second one did carry a real error, now fixed — `meta migrate --db … --slug …` under a comment claiming it diffs the live DB. Without `--from-db` it diffs the committed snapshot, so the comment described a run the flags did not make; it is now the CLI's own documented greenfield example. Prose that the real snippets invalidated: - The five-language section's per-language labels each promised more than the block shows — one file is not the whole generated set. Each now names the file and says what else the same run emits. - "Spring REST + DTO + JPA" for Java, in the Codegen pillar card and the example intro. codegen-spring emits DTOs, controllers and repository interfaces; there is no `@Entity` and no jakarta.persistence anywhere in the module, and the site's own llms.txt already said "the persistence impl is consumer-supplied". - "The metamodel goes deep" ran on a fictional `blog` package. It is `acme::learn` from examples/advanced-modeling now, so Post becomes Program and AuthorSummary becomes ProgramSummary. The marked source region is Author and its validators, so the label says that rather than promising a projection the block does not contain. - requirements.html's ledger entry was `arena::Bot.status`, introduced as "a real entry from a live product, and it is wrong". The block is now the showcase's own entry, which resolves and is gated — so it can demonstrate "resolved, not trusted" instead of asserting it. The live-product finding is the strongest thing on the page and is kept, told as what it now is: a near-identical entry that passed every structural check and was still wrong. That is the sharper argument anyway — the check is necessary and not sufficient. - The generated test stub lands beside "what you get, and what you build", where the page says a stub is a place to put a proof and not a proof. It carries the TypeScript-only caveat next to it. Palette: `.example-code .ok/.err` for terminal blocks (transcripts would have shipped unstyled), and `.example-details` for the expander the injector appends — new markup this site has never carried, so the browser default was the only thing styling it. The per-page `tok-*` rules are dropped where their only users were the blocks now injected; `requirements.html` keeps `.tok-err`, which is still used in prose outside any `<pre>`. llms.txt and llms-full.txt are re-copied wholesale from the monorepo's docs/llms/, which is what they mirror. They carried the fifth pillar and were also four minor lines stale — still describing generators as package imports rather than the scaffold-and-own copies getting-started.html now documents.
1 parent 3e9a234 commit d6a9f08

6 files changed

Lines changed: 139 additions & 289 deletions

File tree

www/articles/prompts-are-code.html

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,6 @@
4545
padding: 1.25rem 1.4rem; overflow-x: auto; font-family: var(--font-mono);
4646
font-size: 0.86rem; line-height: 1.6; margin: 0 0 1.6rem; box-shadow: var(--shadow); }
4747
.article pre code { background: none; color: inherit; padding: 0; font-size: inherit; }
48-
.article .tok-key { color: #8FB7E8; }
49-
.article .tok-val { color: #A7E0C0; }
50-
.article .tok-cmt { color: #7A8AA8; }
51-
.article .tok-err { color: #F0A0A0; }
52-
.article .tok-ok { color: #A7E0C0; }
5348
.article hr { border: none; border-top: 1px solid var(--rule); margin: 2.5rem 0; }
5449
.article-cta { background: var(--light-gray); border: 1px solid var(--rule);
5550
border-radius: 10px; padding: 1.5rem 1.75rem; margin: 2.5rem 0 0; }
@@ -136,27 +131,15 @@ <h2>What prompts-as-code looks like in practice</h2>
136131

137132
<p>(It grew out of a mess of my own — a few thousand lines of <code>StringBuilder</code> driving the characters in an LLM game. For the origin story, and the <em>data + text + render</em> decomposition that became the fix, the longer essay is <a href="https://dougmealing.com/writing/the-prompt-is-code/">The prompt is code — and yours is drifting too</a>.)</p>
138133

139-
<p>A prompt declares its input as a typed payload — a projection of the same entities that drive your database and API:</p>
134+
<p>A prompt declares its input as a typed payload — a projection of the same entities that drive your database and API — and names its text by a logical reference, so the text itself stays a versioned file in your repo rather than a row in someone's cloud:</p>
140135

141-
<pre><code><span class="tok-cmt"># prompt = typed payload + external text</span>
142-
<span class="tok-key">object.value:</span>
143-
<span class="tok-key">name:</span> <span class="tok-val">AuthorBlurbPayload</span>
144-
<span class="tok-key">children:</span>
145-
- <span class="tok-key">field.string:</span> { name: authorName }
146-
- <span class="tok-key">field.string:</span> { name: bio }
147-
148-
<span class="tok-key">template.prompt:</span>
149-
<span class="tok-key">name:</span> <span class="tok-val">authorBlurb</span>
150-
<span class="tok-key">payloadRef:</span> <span class="tok-val">AuthorBlurbPayload</span>
151-
<span class="tok-key">textRef:</span> <span class="tok-val">author/blurb</span> <span class="tok-cmt"># template text lives in a versioned file, not a cloud</span></code></pre>
136+
<pre class="example-code" data-snippet="showcase-prompt"></pre>
152137

153138
<p>From that one declaration you get a generated, typed <code>render</code> function per language — deterministic and byte-identical across all five ports (there's a shared conformance corpus that proves it), so snapshot tests pass and your exact-prefix prompt cache stays warm. Nothing reformats your prompt behind your back.</p>
154139

155-
<p>And because the payload is <em>declared</em>, the build can check it. Rename <code>authorName</code> in the model — or reference a variable the payload doesn't have — and:</p>
140+
<p>And because the payload is <em>declared</em>, the build can check it. Reference a variable the payload doesn't have — rename <code>subscriberName</code> in the model and forget the template, say — and <code>meta verify</code> says so and exits non-zero:</p>
156141

157-
<pre><code><span class="tok-ok">$</span> meta verify
158-
<span class="tok-err">[authorBlurb] (prompt) ERR_VAR_NOT_ON_PAYLOAD: displayName</span>
159-
meta verify — 1 drift error(s) across 1 template(s). <span class="tok-cmt"># exit 1 — the build fails</span></code></pre>
142+
<pre class="example-code" data-snippet="verify-transcript"></pre>
160143

161144
<p>That's the moment a prompt stops being a string and becomes code: <strong>the renamed field is a compile error now</strong>, not a quality regression you discover in three weeks.</p>
162145

0 commit comments

Comments
 (0)