DJ Von Frank AI Implementation

Colophon

How this site is built

Every page here argues that I wire rules into a build so a violation cannot ship. This is the one page where you can check that, because the system being described is the one rendering the page.

Rendered by the system it describes.

The build runs the quality gate against its own output: exactly one H1 per page, every internal link resolving, every image carrying alt text, no unresolved template token, and 97 terms that must never reach the output. If the gate finds an error the build exits non-zero and the upload folder is never handed over.

Read the gate
DJ Von Frank

The short version

A Node script renders every page through one shell, copies the static assets, and then runs the quality gate against its own output. If the gate finds an error the build exits non-zero and the upload folder is never handed over. There is no framework, no dependency to install, and no build step beyond node build.mjs.

The gate checks the ordinary things: exactly one H1 per page, a meta description with actual length to it, Open Graph tags present, every internal link resolving to a file that exists, every image carrying alt text, and no unresolved template token surviving into the output. It also counts the draft testimonials, and refuses to build at all in launch mode while any remain, because invented words in a real person’s mouth are the one defect on this site that could hurt somebody else.

The same pattern, four times over

This is not a technique invented for a portfolio. It is the fourth build in a row where the house rules ended up as executable gates, and the excerpts on this page and on the brain pages are the other systems doing the same thing in their own repositories.

This build, measured

97

terms the build refuses to ship, checked against every text file in the output

Passing
3

source excerpts on the site, each verified against its repository line for line

143

quoted lines of real code, none written for the page

0

npm packages. No lockfile, no install step, nothing to audit but this code

These figures are computed from the source when the site is built, not typed into this page. When the scrub list grows, this number moves with it.

The gate that matters

This site publishes rebuilt versions of confidential systems. That makes one check more important than all the others put together: a list of terms that must never reach the output, and a build that refuses to ship if one of them does.

Trusting a careful copy-paste is not a control. This is. And it is worth reading the comment in the middle of it, because it is a record of the same gate being wrong twice while reporting that everything was fine.

A terminal showing a build failing with three errors, including an unresolved template token that survived into the output and a draft testimonial quoting a named person from a file still in the review queue, ending with the deploy aborted and nothing published.
What a refusal looks like from the outside. Errors stop the line and warnings do not, which is why the em dash below them is a warning and the unapproved quotation above them is not. Reconstruction. Real mechanism, demo data, the same fictional company the demos on this site already use. No client data appears here. Open full size
qa.mjs djvonfrank.com · lines 143 to 277 of 403, four comment blocks elided

The gate that had to pass before this page could exist. It is the least flattering code on the site: the comments running through it are an account of the same control being wrong four times, and all four are the same mistake, which is reading something narrower than the file.

export async function runQA(outDir) {  const errors = [];  const warnings = [];  let checked = 0;   const all = await walk(outDir);  const htmlFiles = all.filter(f => f.endsWith('.html'));  const rel = f => '/' + path.relative(outDir, f).split(path.sep).join('/');   /* ---- THE SCRUB GATE, over EVERY text file ---------------------------------     This used to run only over .html, and only over HTML with <script> and     comments stripped out. Both scopings were wrong, and both were caught by an     audit rather than by this file:       · a scrub term shipped inside a CSS comment, invisible to a .html-only loop       · the brain-data JSON lives in <script type="application/json">, which         strip() deleted before the check ran — pointing the control away from         the highest-risk content on the site     Now: every text file, raw, before any stripping. */  const TEXT = /\.(html|css|js|json|svg|xml|txt|md)$/i;   // ... 17 comment lines trimmed: the account of the THIRD fault, found on  // 2026-08-12. It has to be trimmed for the same reason as the block below,  // and more sharply: it quotes the exact string that got through, and that  // string contains a scrub term. Publishing the explanation would fail the  // build that published it ...  const views = raw => {    const out = [raw];    try {      const decoded = decodeURIComponent(raw);      if (decoded !== raw) out.push(decoded);    } catch {      /* Not valid percent-encoding as a whole. Decode the escapes that are         well-formed and leave the rest, so one malformed sequence anywhere in         a file cannot buy an exemption for the whole file. */      const partial = raw.replace(/%[0-9A-Fa-f]{2}/g, m => {        try { return decodeURIComponent(m); } catch { return m; }      });      if (partial !== raw) out.push(partial);    }    return out;  };   // ... 10 comment lines trimmed: the rationale for boundary-matching short  // terms. It names one of the scrub terms as its worked example, and this  // page is scanned by the gate it documents, so the comment cannot be quoted  // here. The gate forbids its own documentation, which is this page's whole  // point, made three times now ...  const SHORT = t => t.length <= 4 && /^[A-Za-z0-9]+$/.test(t);  const hitsOne = (text, term) => SHORT(term)    ? new RegExp(`(?<![A-Za-z0-9+/=])${term}(?![A-Za-z0-9+/=])`).test(text)    : text.includes(term);   // ... 12 comment lines trimmed, for the same reason as the two above: they  // work through a listed term that got past the list by having its space  // closed up, and naming it here would fail this build ...  const forms = term => {    const words = term.toLowerCase().split(' ');    return [...new Set([' ', '', '-', '_', '.'].map(sep => words.join(sep)))];  };   /* A MULTI-WORD term is matched case-insensitively across all five shapes; a     single-word term keeps exactly the behavior it had, boundary rule and     case-sensitivity included. The split is deliberate. Single-word entries     include short acronyms whose case is load-bearing, and folding those     would trade real catches for base64 noise. A two-word name is not     something anyone types by accident, so widening it costs nothing and     closes every casing a URL, a slug or a filename might arrive in. */  const hits = (texts, term) => {    if (!term.includes(' ')) return texts.some(t => hitsOne(t, term));    const lower = texts.map(t => t.toLowerCase());    return forms(term).some(f => lower.some(t => t.includes(f)));  };   for (const file of all.filter(f => TEXT.test(f))) {    const raw = await readFile(file, 'utf8');    const texts = views(raw);    for (const term of SCRUB) {      if (hits(texts, term)) {        errors.push(`${rel(file)}: SCRUB VIOLATION — "${term}" reached the output`);      }      checked++;    }     // ... the comment explaining why the demo needs its own stricter list,    // and what a skeptical reader found that this shared list could not, is    // elided here for length; it is the longest comment in the file ...    if (/^\/llm\//.test(rel(file))) {      const lowers = texts.map(t => t.toLowerCase());      for (const term of DEMO_SCRUB) {        if (lowers.some(l => l.includes(term))) {          errors.push(`${rel(file)}: DEMO SCRUB VIOLATION — "${term}" reached the demo, which claims to carry no real names`);        }        checked++;      }    }  }

What it caught

An audit found a confidential term live in the deployed CSS, inside a comment I had written myself. The gate at the time scanned HTML only, so it never looked at the file. It had been reporting clean the whole time.

The same audit found that the check ran after script blocks had been stripped out, and the brain demos put their entire folder structure into a JSON script tag. The one control protecting the most sensitive content on the site was pointed away from it.

Both are fixed, and the fix was not a patch to the two known faults. It was widening the scope until there was nowhere left to hide: every text file, read raw, before anything is stripped. Then I planted a scrub term in a CSS file and watched the build die, because a control nobody has ever seen fail is a belief rather than a control.

Still true, and worth saying

Both of those defects were caught by an audit rather than by me. That is the argument for adversarial verification in one sentence: I wrote the gate, I believed it worked, and I was the last person who was going to find out otherwise. Verification that runs in the same head that produced the work is just agreement.

Excerpts are checked, not asserted

Three pages on this site quote real source code out of real repositories. A quotation is only worth something if it is exact, so there is a second script whose entire job is to open each source file and confirm every published line still exists in it, character for character.

Where an excerpt is trimmed, the trim is printed as a line of its own. Splicing two distant parts of a file into something that reads as continuous would be the same class of dishonesty as inflating a count, and rather harder for a reader to catch.

That script deliberately does not run inside the build. The source repositories live outside this folder and are not always present, and a build that fails on a machine where one of them is missing would teach me to ignore a failing build. It is run by hand, and it is the reason the numbers on those pages can be trusted.

The rest of it

  • Design system. Named tokens with measured contrast, and where a color fails it is written down as a rule rather than nudged until it passes.
  • Motion. One named piece of decorative motion in the whole system. Reduced motion removes it rather than slowing it down, because a slowed signature reads as a broken one.
  • Type. Archivo for display, IBM Plex Sans for text, IBM Plex Mono for anything that is data. All three are self-hosted from this folder as latin subsets, so no page here asks another company’s server for a font, a script or an image. The ambience-forecast demo, which fetched live weather and its own fonts, was retired on 2026-08-12.
  • Hosting. Cloudflare Pages, from a folder the build script produces.
  • Dependencies. No npm packages, so there is no node_modules, no lockfile and nothing to install before the site will build. Earlier versions fetched webfonts from Google and this page said so plainly. The fonts now live in the repo, which retired that request.
  • What still talks to somebody else, named rather than buried. Two things, and the count went two, three, two again on 2026-08-13, which is the honest version of how it is kept. A pre-launch sweep found a third that had been true for a while and unwritten: 342 pages under the LLM demo requested a webfont from Google. The number moved to three that morning. The fonts were self-hosted that afternoon. It moved back. Page-view counting loads one script from Cloudflare after the page does: cookieless, no cross-site identifier, nothing sent onward, and if your browser sends Do Not Track or Global Privacy Control the request is never made at all, because the check runs before the script element is created. That is a choice rather than compliance, since neither signal is binding here. One imported artifact is the other: the Brand OS page at /brand-os/spectrum-killian/, a single-file React application that boots a compiler, a framework and a webfont from three CDNs. This paragraph used to say four such pages. Checking rather than assuming showed the other three embed their runtime and only list those URLs in a manifest the browser never fetches, so they are self-contained and the number is one. Everything else was measured the same way: across 787 built files, exactly one reaches a third party. The demo's fonts are 57 self-hosted latin subsets, its placeholder images are inline SVG, and the three scripts that generate its pages were patched too, because they were emitting the CDN link and would have put it back on the next run.
  • The images on those pages used to come from somewhere else too. One of them served 32 files from a client CDN, which meant every visitor fetched a third party's assets and the client's own systems could see who was reading. They are self-hosted now, resized from print originals to web sizes, at about a fifth of the bytes. One partner mark is a gray placeholder instead: the page anonymizes that line in its copy, so shipping the real logo would have undone that in the one place nobody reads, the URL. The lab video went with them, at seventy megabytes for a decorative loop whose poster frame was already a dead link.
  • Syntax highlighting. Ninety-two lines of hand-written tokenizer. A highlighter is not a good enough reason to take on a supply chain, and the hard part is only deciding whether a forward slash starts a regular expression or divides.