Origins — transclusion view

Source: the conversation, verbatim

You — voice note 1
Okay. Here's what I need to do. I have, uh, kind of a a workflow, a style of programming that I need to write two different, um, blog posts explaining. Um, I need to do this because there's a couple of people I work with and some interns that I think would benefit from this. So the first is kind of a general style of programming, um, without large language models, which specifically takes advantage of the fact that we don't know what we're doing all of the time. Um, the approach is extremely simple. Uh, I think in order to write this paper, I maybe just need to provide some context. What is the problem? Uh, what is my approach, and how my approach kinda solves the problem. And the general approach is just, like, write write programs procedurally when you don't know what you're doing. And when something starts to get complicated, you can hand wave a lot by just writing a call to a function that doesn't exist yet. And your compiler, at that point, will basically act as a to do list for you. Um, and if you want code to run, like, if you wanna skip over one of these procedural functions you've written, you could have it return, you know, a canned response or or whatever. Um, and this is an approach that we used back in college, um, specifically to build compilers, shells, all sorts of complicated C code, um, that we also had to write by hand on paper for our exams. Uh, and so this was a very effective technique of breaking down work, um, as you needed so that you could accomplish your goals in a timely manner without having to know how to solve all of your problems upfront. The second topic that I need to write about, uh, is about using large language models to write and solve large problems. So kind of in a a similar fashion, the main idea here is that we want to avoid this false assumption that we can just come up with the perfect architecture or the perfect way to solve a problem on our own, because it's just not realistic. Uh, so instead, um, instead of looking towards solutions like lane graph or, uh, complicated harnesses or stacked loops or all of these other this, like, crazy automation bullshit. Um, the best place to start is just with a casual chat. Come up with a couple tools that you know you will absolutely need to have, such as, um, a connection to a database that has all of the access and authorization already provided. And then just work with your your agent, like Claude, in a conversational setting to try to solve one particular problem or example problem, that you that you are trying to automate. work through the problem, interrupt the agent as frequently as you need if you see it doing something you don't want it to do, interrupt it, and teach it what to do in this session. Don't worry about writing other files. Just worry about getting the one instance of the task complete. Um, ask Claude questions. Make sure that Claude asks you questions, and treat this as a collaborative pair programming exercise and exploration. Once you've completed that goal, you can summarize that session into, uh, a handful of, uh, like, pseudocode lines. The idea would be figure out what all of the kind of starting input variables were, all of the questions that were asked related to the problem, uh, all of the nitpicks, um, and and separate and organize these elements so that what you're left with is some ground rules, kind of like what you would put in a Claude MD, like use UV, uh, over conda. Um, and then you have, uh, like, a playbook. And this playbook or pseudocode is basically a program written in English. Step one, do this. Step two, do this. If this, then that. Um, and then take the pseudocode to a new session and try to solve the same problem. Again, follow Claude along the way, correct mistakes. And through this process, revise the program that you've been making in English. There are some concrete reasons why this is more effective than writing a program. For one, the interpreter is the large language model. The interpreter is the agent. Just as the... just as on paper, uh, you are the interpreter, now Claude is the interpreter. Claude can read in an instruction and assume what the correct intent is. And the nice thing is is that if Claude assumes the correct intention, then you don't need to overexplain yourself. You don't need to provide any more context. If Claude reads an intention and gets it wrong and you catch that, you have the opportunity to fix that assumption, fix that intent, and build the correct program live. You don't have to exit or reload anything. And what's nice is that you don't have to worry about, uh, type inferencing getting in your way. You don't have to worry about the compiler throwing errors that you maybe don't necessarily care about yet. you can work purely in the abstract even though it is probabilistic and nondeterministic and more expensive, you're able to do the work of exploration, uh, a lot more freely. So finally, once you've gone through this, uh, systematic approach of working out a pseudocode program with your agent, and you can start using that pseudocode program on more examples from your domain, more questions, for instance, then you can take that pseudocode, which is robust enough English, and you can treat that as specifications for a real program. At that point, you can have a new session, try to translate that pseudocode into a coding target of your choice, like Python or Rust. Once you have that code translated to Python or Rust, again, you wanna do the same tests. You wanna run through one, two, possibly a hundred example inputs and then verify them altogether. And you could have another coding agent, uh, walk through and evaluate, did the program execute to match the specifications of the pseudocode. Um, at this point, trying to figure out how you verify you've built the right thing is is and becomes the hardest part of this job. And I would I would add that this was always the hard part of the job. But now instead of getting to this hard part a month into development, you're working on it on day one. If possible, for the purpose of these two writings, uh, it would be helpful if you could just take this exact text that is coming out of the voice transcribe and basically just fill out the outline of, like, what's the what's the setup, what's the approach, um, mark something as an aside if you can, because I know I have a couple of sides in there. Just write this as HTML. We don't need any super fancy formatting. It can be one document. Just make sure that the two posts are separated in different, like, article tags or something so that I can separate them out manually afterwards. And if you can think of any questions or concepts that I maybe should add, those would be helpful to include, um, as well at the end.
Claude — reply 1
Both posts are in one HTML file, each in its own <article> tag so you can split them apart later. Your tangents (the college/paper-exams story, the "you were the interpreter on paper" point) are marked with <aside> tags, and there's a highlighted editor-notes section at the end with suggestions — the two I'd push hardest on are adding a real example playbook to post 2 and expanding the verification ending, since that's your strongest idea and it currently gets two sentences.

I kept your phrasing close to the transcript, just cleaned of speech disfluencies. One liberty: I softened "crazy automation bullshit" to "crazy automation machinery" since interns will read it — easy to swap back if you want the edge.
You — voice note 2
This looks absolutely great. Uh, I love how simplistic the styling is too. That's exactly what I wanted. Thank you. Um, I am curious if you could help me with something maybe a little more complicated next. Everything that is verbatim from my voice note should be wrapped in a span or something, like a span, uh, to indicate that it came from me. Everything that you wrote should be wrapped in a span to indicate that it came from you. If there's something where, you know, you just kind of took the liberty to rewrite something that I said, just a... even a little bit, I would I would urge you to try to use my exact words even though they might be clunkier and might not flow as well together.
Claude — reply 2
Done — this is a new file so your original draft stays intact. Every phrase is now wrapped: <span class="you"> renders as plain text (your words are the default register of the page), and <span class="claude"> gets a light blue highlight so my contributions are visible at a glance. There's a legend at the top explaining the key.

Per your instruction, I went back to the transcript and reverted my paraphrases to your exact words throughout — including restoring "crazy automation bullshit," your repeated "the interpreter is the large language model; the interpreter is the agent," and the full run of "you don't need to overexplain yourself; you don't need to provide any more context." The result is that the body of post 2 is now almost entirely yours, which honestly suits it.

Three small honesty notes on what still counts as edited: I stripped pure fillers ("uh," "um," stutter repeats like "is is") but nothing else; I rendered "lane graph" as "LangGraph" and "Claude MD" as "CLAUDE.md," assuming those were transcription artifacts; and punctuation/paragraph breaks are mine, since speech doesn't carry them. If you'd rather keep even the fillers, say the word and I'll restore them.
You — message 3
AWESOME! Yes this is great. For an even harder challenge - I want you to try and create a replica of the Xanadu transclusion demo (https://xanadu.com/xanademos/MoeJusteOrigins.html). On the left should be my original input - ums and all, unedited, copied verbatim. On the right is our Attribution+Editted mini essays. We want to use vanilla js and html. we want to connect spans from my words into the new document - they should be transparent so that the page isn't overwhelming - and the backlink highlight should have a decent hover effect. We may want a toolbar at the top to edit some settings too - like, I like the mini-map view - but we should have a slider to change it's respective size to 1:1 down to very small. Any questions before you give this a shot ?

Result: two posts, attributed

Let the Compiler Be Your To-Do List: Programming When You Don't Know What You're Doing

The setup

This is a general style of programming, without large language models, which specifically takes advantage of the fact that we don't know what we're doing all of the time. Most programming advice quietly assumes the opposite: that you can design first, decompose the system, and then implement the pieces. But on hard or unfamiliar problems, not knowing is the normal condition of writing software. The question is whether your workflow takes advantage of that fact or pretends it isn't true.

The failure mode of pretending is familiar: you stall at the top of a file trying to figure out the "right" structure, or you go down a rabbit hole solving a sub-problem you didn't need to solve yet, and the actual goal slips further away.

The approach

The approach is extremely simple. The general approach is just: write programs procedurally when you don't know what you're doing. Start at the top and describe the steps of the solution in the order they happen, as if you were narrating it.

When something starts to get complicated, you can hand-wave a lot by just writing a call to a function that doesn't exist yet:

result = parse_declaration(tokens);   // no idea how yet
emit_code(result);                    // also no idea

Your compiler, at that point, will basically act as a to-do list for you. Every "undefined function" error is an item of work you've deferred — explicitly, visibly, and in whatever priority order you feel ready to tackle next. You never lose track of what's left, because the build won't let you.

And if you want code to run — if you want to skip over one of these procedural functions you've written — you could have it return a canned response or whatever. Now you can test the parts you do understand while the parts you don't are safely fenced off behind a name.

Why it works

This was a very effective technique of breaking down work as you needed, so that you could accomplish your goals in a timely manner without having to know how to solve all of your problems upfront. Naming a function you can't write yet is itself a design act — you're defining an interface and deferring the implementation, which is most of what "good architecture" actually is, just done lazily and honestly.

Programs Written in English: Solving Big Problems with an LLM, One Conversation at a Time

The setup

This post is about using large language models to write and solve large problems. The main idea here is that we want to avoid this false assumption that we can just come up with the perfect architecture or the perfect way to solve a problem on our own, because it's just not realistic.

So, instead of looking towards solutions like LangGraph, or complicated harnesses, or stacked loops, or all of this other crazy automation bullshit — start somewhere much smaller.

Step 1: Start with a casual chat

The best place to start is just with a casual chat. Come up with a couple tools that you know you will absolutely need to have, such as a connection to a database that has all of the access and authorization already provided. And then just work with your agent, like Claude, in a conversational setting to try to solve one particular problem, or example problem, that you are trying to automate.

Some ground rules for this session:

  • Work through the problem. Interrupt the agent as frequently as you need — if you see it doing something you don't want it to do, interrupt it, and teach it what to do in this session.
  • Don't worry about writing other files. Just worry about getting the one instance of the task complete.
  • Ask Claude questions. Make sure that Claude asks you questions, and treat this as a collaborative pair programming exercise and exploration.

Step 2: Summarize that session into pseudocode

Once you've completed that goal, you can summarize that session into a handful of pseudocode lines. The idea would be: figure out what all of the starting input variables were, all of the questions that were asked related to the problem, all of the nitpicks — and separate and organize these elements so that what you're left with is some ground rules, kind of like what you would put in a CLAUDE.md, like "use uv over conda."

And then you have a playbook. And this playbook, or pseudocode, is basically a program written in English. Step one, do this. Step two, do this. If this, then that.

Step 3: Run the English program, and revise it

Take the pseudocode to a new session and try to solve the same problem. Again, follow Claude along the way, correct mistakes. And through this process, revise the program that you've been making in English. You are iterating on a program; the source code just happens to be prose.

Why an English program beats a real one (at this stage)

There are some concrete reasons why this is more effective than writing a program.

  • For one, the interpreter is the large language model. The interpreter is the agent. Claude can read in an instruction and assume what the correct intent is. And the nice thing is that if Claude assumes the correct intention, then you don't need to overexplain yourself. You don't need to provide any more context. If Claude reads an intention and gets it wrong, and you catch that, you have the opportunity to fix that assumption, fix that intent, and build the correct program live. You don't have to exit or reload anything.
  • You don't have to worry about type inferencing getting in your way. You don't have to worry about the compiler throwing errors that you maybe don't necessarily care about yet. You can work purely in the abstract.
  • Even though it is probabilistic and nondeterministic and more expensive, you're able to do the work of exploration a lot more freely.

Step 4: From playbook to specifications for a real program

Once you've gone through this systematic approach of working out a pseudocode program with your agent, you can start using that pseudocode program on more examples from your domain — more questions, for instance. Then you can take that pseudocode, which is robust enough English, and you can treat that as specifications for a real program.

At that point, you can have a new session and try to translate that pseudocode into a coding target of your choice, like Python or Rust. Once you have that code translated to Python or Rust, again, you want to do the same tests. You want to run through one, two, possibly a hundred example inputs, and then verify them altogether. And you could have another coding agent walk through and evaluate: did the program execute to match the specifications of the pseudocode?

The hard part, moved to day one

At this point, trying to figure out how you verify you've built the right thing becomes the hardest part of this job. And I would add that this was always the hard part of the job. But now, instead of getting to this hard part a month into development, you're working on it on day one.

Notes: things you might want to add (this whole section is Claude's)

For Post 1 (procedural hand-waving)

  • Name the lineage. Closely related to "top-down design with stepwise refinement" (Wirth) and TDD's "fake it till you make it" stubs.
  • When NOT to use it. Works less well when the hard part is a data structure or an invariant rather than a procedure.
  • A worked micro-example. A tiny shell main loop with three undefined functions, then the compiler output acting as the to-do list.
  • Stubs vs. TODOs. Comments are ignorable; link errors aren't.

For Post 2 (programs in English)

  • An example playbook. Even 6–8 lines of real pseudocode from one of your sessions would make this concrete.
  • How you "interrupt and teach." One short before/after exchange would help interns.
  • Version control for the English program. Git? A markdown file? Worth a sentence.
  • When to stop iterating in English. What signals "robust enough"?
  • Cost framing. Exploration in English is still cheaper than a month of building the wrong harness.
  • The verification story deserves more. Your strongest idea currently gets two sentences.
  • Tie the two posts together. Shared thesis: defer what you don't understand behind a name, and let an interpreter tell you what's left.