← Matt Hastings  ·  Scientists of the Soul — releasing August 1, 2026
Built with Claude Code  ·  June 20 — July 14, 2026  ·  a directory, not an app

An engine for a graphic novel

A hand-drawn book about AI and religion — Joseph the Jesuit, the Scientists of the Soul, the world's faiths racing to convert an emerging mind. It began as 113 sketchbook drawings and a question. The system that turns them into a book was stood up incrementally, one tested piece at a time, in conversation with Claude.

You direct · Claude operates  —  the intelligence lives in the conversation, not a GUI
§01Intent

It started as drawings & a question

Not a repo. Not a spec. A sketchbook — 113 iPhone photos of ink drawings — and a premise: what happens to the soul when intelligence stops being ours alone?

The first decision was the most important one, and it wasn't technical: the drawings are the source of truth. Everything downstream — style, pipeline, book — exists to serve them, never to replace them. source/ is read-only. The pipeline may look; it may never touch.

The second decision: build no apparatus before the work demands it. No app, no framework, no GUI. A directory, a few Python scripts, and a running conversation where the actual intelligence lives.

Raw sketchbook drawing — the procession of faiths
raw sketchbook · source/sketchbook/IMG_7067.JPEG
Raw sketchbook drawing — Joseph among the racks
raw sketchbook · source/sketchbook/IMG_7085.JPEG
§02The engine

How the engine works

No skills, no slash-commands, no agents. Directory conventions, a few command-line scripts, and one loop. The files are the memory; the conversation is where the loop turns.

01 Images insource/sketchbook/ 113 hand-drawn pages, read-only forever. The pipeline reads; it never writes.
02 Conversationnarration.md · image-board.json You direct in plain language; story and intent are written to files before anything else happens — your words verbatim, never left in chat.
03 Align on styleexperiments/ → style-bible/ Render real candidates, look together, lock: four palette values, reference anchors, one house recipe. Decided by looking, not debating.
04 Codifypipeline/lib/style.py Aesthetic law becomes executable rules — GRAVITY · MOTIFS · LEANS — injected into every generation. "No cross-hatching" is a line of code now, not a memory.
05 Runstylize.py · generate.py · element.py Every script works the same way — you supply the what, the files supply the how:
your words (content) + style.py (the look, injected) + references/ (anchors)
   → gpt-image-1 → base.vN   # appends — never overwrites
stylize.py — your drawing in, the house look out (the main path)
generate.py — content-only prompt for the beats never drawn (the gaps)
element.py — regenerate one surface inside a page, zero drift to the rest
06 Evaluatepick.py · the canvas Review artifacts, not descriptions: a browser grid of every candidate — click a winner, it becomes art.png; every loser stays a live alternate.
07 Recodify style.py · wave logs · CLAUDE.md Feedback returns to the files, by scope: one image → a new command; "from now on" → a rule in style.py; a bug → code fixed + a ⚠ warning atop the wave log. The loop closes tighter than it opened.
The test for every piece of feedback: should it survive the session? If yes, it's written into the file that executes it — the chat is scratch space. That single habit is the whole engine.
§03Test, then decide

One drawing, three futures

Before locking any style, the same source drawings went through a matrix of candidate looks — run-01. Not descriptions of styles: actual rendered images, reviewed side by side. The decision that shaped the whole book (a unified core with per-image gravities) was made by looking, not by speculating.

The raw drawing
the raw drawing
comic-forward candidate
candidate: comic-forward
flat-graphic candidate
candidate: flat-graphic
sacred-machine candidate
candidate: sacred-machine
The Claude Code pattern: when a choice matters, don't debate it — generate the matrix, put real artifacts in front of your eyes, then lock. Cheap to produce, impossible to argue with.
§04The style bible earns its keep

Locked by iteration, not upfront

The style bible began loose: prose principles extracted from exemplars — Klimt's gold, woodblock flatness, Secession structure — plus a palette file and reference anchors. It was allowed to stay unlocked until the work proved what it should be.

Then the first full build taught a hard lesson. Thirty-nine beats rendered as a patchwork — each gravity had been fed a different style family, and the Mignola anchors bled literal Hellboy into Joseph's face. The fix became Recipe v2: one fused blend fed to every image, Mignola dropped entirely (his mood survives in prose only), gold made structural — circuit-traces and keylines, the swirls cut in half — and the palette locked to four values.

#0E100E
#5E726B
#C8A43C
#C24A2C
style-bible/palette.json — near-black · teal-slate · gold · the one accent. This page is built from the same four values.
Lesson, codified: never feed mignola-*.png as image refs — likeness leaks. Every hard-won generation gotcha goes straight into the style bible's AVOID list and CLAUDE.md, so the system can't relearn it the expensive way.
House anchor: scene
house anchor · scene
House anchor: pinup
house anchor · pinup
House anchor: artifact
house anchor · artifact
Joseph — the character anchor
joseph-01 · the character anchor
the ladder of divine machines — one sequence, one recipe, nine frames
cell
cell
insect
insect
sealife
sealife
animal
animal
human
human
factory
factory
robot
robot
datacenter
datacenter
ai
ai
§05Story → beats → image board

The story becomes data

The story starts as a telling — voice-dictated, freeform, typos and all — captured immediately into book/narration.md, so the source of truth is a versioned file, never a chat scrollback.

From the telling, beats.yaml: 39 beats under 8 movements. Each beat carries its story slice, its source sketches, and a gap note. That one file makes the central production decision, per beat: a sketch exists → stylize it; a gap → generate.

By ch02b the boards had evolved into JSON with the collaboration protocol built in: the director's words ride along verbatim in a matt field; Claude's proposals are flagged "proposed": "claude" — strike or edit freely; and every row names 2–3 compositional variations (framing, camera, count) — never style variations, because the recipe owns the style.

The alignment layer. No pixel gets made until it has a row: whose words asked for it, which register renders it, what family it belongs to. Images stop being one-off prompts and become fulfillments of a shared, editable plan.
1 · the raw telling — narration.md, verbatim
…he stares at the servers… one soul or many? he turns his phone on, off, on off, a new soul each time? closes his eye, opens them, a new soul each monring? ho wmany souls in a lfie time? how can there be continuity, he is not hte same as he was, AI niether… book/narration.md — dictated, captured before anything else, committed
2 · structured — beats.yaml
- id: b01
  movement: 'A: The charge'
  story: Open on J and an off-camera interlocutor — breakfast
    table or office, minimal. The conversation begins.
  images: [IMG_7066.JPEG]        # a sketch exists → STYLIZE it

- id: b02
  story: 'Galileo, ostracized: heliocentrism decenters man…'
  images: []                    # no sketch → the gap says GENERATE
  gap: 'need: Galileo / heliocentric decentering'
3 · the working board — ch02b image-board.json
{ "n": "s01", "moment": "The trio, walking",
  "image": "Wide: Joseph + humanoid robot + Great Pyrenees on a
           park path, golden hour — long shadows, big negative-
           space sky, the dog a white mass against spot-blacks…",
  "register": "scene",
  "matt": "or have we made a companion on this journey…",  // the director, verbatim
  "note": "THE anchor scene… SCENE-FAMILY: the whole spine IS
          s01's family — generate s01 first, feed the winner
          into every other spine row.",
  "variations": [ "profile frieze, strict side-view procession",
                  "trailing 3/4 view, path curving into dusk",
                  "high wide — trio small, park huge" ] }  // compositional, never style
§06The firm rule of the art

Your drawings, stylized — never replaced

If a beat has a sketch, the pipeline stylizes the sketch. It never generates a substitute from scratch. The composition, the gesture, the idea — those stay yours; the recipe supplies surface, palette, and light. Generation-from-nothing is the exception, reserved for the handful of beats that were never drawn.

The raw drawing of Joseph among the server racks
the drawing · source/sketchbook/IMG_7085.JPEG
The stylized page: Joseph among the racks
the page · book/ch01/b12/art.png — b12, Joseph among the racks
Register rule, learned mid-build: grounded present-day realism. Real data centers, real fabs, real phones. The sacred enters by treating the real with awe — a glowing AI-god is "too on the nose," and one was cut from a finished page for exactly that reason.
§07Composition

The canvas — & features only when composing demanded them

Once hundreds of candidates existed, the bottleneck moved: not making images but arranging them. So the system grew a composition canvas — a zoomable board per chapter where candidates from the pool get placed, compared, sequenced into the scroll.

Every feature below was added the day a real compositional need surfaced it — never speculatively. That's the whole ergonomics method: compose until it hurts, then build exactly the relief.

Jun 27open-canvas toolarranging beats in folders stopped scaling — needed a spatial board
Jun 27pick.py grid pickercurating re-rolls: click a candidate → promote + reflatten
Jun 28request-notes on canvasannotate a spot on the board, ping Claude to fulfill the note
Jun 28wide-page splits + rebase-on-savewide friezes needed segmenting without losing arrangement work
Jul 05trackpad navtwo-finger pan + pinch zoom, once boards hit 200+ images
Jul 12canvas_append.pya touched canvas is composition WORK — append-only, never reseed
Jul 12style LEANSper-chapter voice (graham-walk, wash-line) without breaking the house
The composition canvas: ch03 images arranged on the zoomable board
the canvas editor, live at localhost:8765/?canvas=ch03 — ch03 early in composition; 265 images arranged on this board by Jul 10
The radiation — a literal-scene tile from the ch03 swarm
one atom of the ch03 radiation swarm — ~45 discrete tiles, two resolution zoom-chains
§08Where it stands · what's next

The book reads — the words come last

All 39 beats of chapter one have art. Chapters two, the ch02b interlude, and three have full candidate pools — roughly 800 generated images across the book, every one versioned, none overwriting another. Below: the sea → snap reader — the whole book drifts as a churning sea of fragments behind one fixed page-frame; turn the page and the panels fly out of the sea and settle into composition, then dissolve back. It reads the same canvases/ch01/canvas.json the composition board produces — arrange the canvas, and the book turns.

Now comes the text layer — and it was designed to come last. Dialogue is written after images are composed, in Markdown, placed by normalized coordinates in page.yaml. The art never carries a word; re-cutting the book means editing YAML, never touching a PNG.

art: art.png          # text-free, always
text:
  - md: "But what of our *souls*?"
    at: [0.62, 0.18]   # normalized 0–1 — resolution-independent
    style: whisper
enter: bloom          # earned move, progressive enhancement
Why last? Comics are composed images first. Writing dialogue onto a finished composition means the words respond to what the page actually became — not to what an outline predicted.
The data-lake mind — gold sparks in deep black
b17 · the data-lake mind — a page waiting for its words · book/ch01/b17/art.png
sea → snap — fragments fly out of the sea and settle into the page
The sea-snap reader: panels fly out of a churning sea of fragments and settle into a single page frame
live capture of preview/sea-snap.html — one fixed stage, the whole book adrift behind it; each turn pulls the next page's fragments into frame. Run it: python -m http.server 8000localhost:8000/preview/sea-snap.html
twenty-five days, in commits
JUN 20
Scaffold the system: directory, pipeline, reader, design doc — one day, whole skeleton
JUN 20
Style decision from the run-01 matrix; first real page live in the reader by nightfall
JUN 20
Layered-art pipeline: base + maskable element layers — restyle one element, zero drift
JUN 24
Story structured: 39 beats, 8 movements, 76 sketches mapped via the sketchboard
JUN 25
Scroll choreography: pacing gutters, movement vectors, earned enter-moves
JUN 26
All 39 beats built in one pass — then rebuilt two days later on Recipe v2
JUN 27
Open-canvas composing tool; features accrete as composition demands
JUL 03
Chapter one composed: the cardinal dialogue, ghosts-in-the-machine, the ladder
JUL 09
Chapter three built: JSON image board, generation waves, the radiation swarm
JUL 12
Ch02b interlude ("the walk — can AI love?") + per-chapter style LEANS
JUL 14
→ the text layer
behind this text: every image in the book, tiled as the pixels of one field
113source drawings
39story beats
~800versioned candidates
4palette values
0originals modified
25days

The book doesn't answer its question — it's an act of attention. The system was built the same way: look first, then decide, then lock.