You've seen test-rot, specification rot, and documentation rot; we now introduce; prompt rot!
Cluttering the repo with out-dated, very wordy and quickly aging prompts will just confuse any agent tasked with looking at the repo in the future. Keeping context windows down is a real limitation to good LLM output, and this workflow may work completely against it.
- A plan.md describing the project, main abstraction idea, end costumer, and so on is great; but it should be kept minimal and up-to-date with the repo.
- Block comments on top of source-files and functions are great, and already very useful to coding agents. I don't see a value to anything more than what is already typical best practice.
Git history is a bit annoying to navigate, but that may just be a tooling issue. I've long been bothered by the loss of the review history when merging a PR. Would actually be pretty cool to click on a row of code and see the commit messages that formed that row of code in a little sidebar, and the technical discussions that were behind it.
Functional safety development processes often demand code-review, technical design decisions, changes of plans, or intentional compromises; to be linked together with reference IDs in the code they effect. But the workflow for this is usually extremely manual and absolute misery. But a codebase made like this is like magic to read later.
I want to do something like that with git-bug (keeping track of prompt/conversation/review alongside normal commit), but unsure what the DX would be. Insights welcome :)
Yes and no. Git blame is great yes, but it's still rather crude. If three commits changed one condition; it only shows the top commit. Getting a full sense of the history of a function over time is far less ergonomic.
The tech and data-structure is there; but the common UX is not quite expressing the data in a sophisticated manner. It doesn't help that the default diff algorithm is rather crude as-well.
Some tools will automatically ignore commits in a .git-blame-ignore-revs file. Git itself can "blame --ignore-rev <hash>" or "blame --ignore-revs-file <file>" since version 2.23.
Though git-blame may fail or crash if blame.ignoreRevsFile is set but the file is missing (hence "config", not "config --global"). Since version 2.53, a configured ignoreRevsFile can be missing if the value starts with ":(optional)".
I am skeptical of adding anything but a brief description of the change, the reason for the change and possibly some explanation of non-obvious implementation choices to the commit message.
The reason is that the commit message log serves as an overview of the changes commited. That's what humans use it for, anyway: to get an idea of what happened since they last pulled, to help give an idea of where a regression might have been introduced and so on, at a glance. To that end, brevity is very useful.
My understanding is that chatbots used to perform such tasks will also benefit from brevity.
Well, at least in Git, the commit message already has two sections.
AFAIK, the first line is supposed to be the a very brief summary, while the other lines may contain additional information and can sometimes make up a pretty long text. Lots of tools make use of this convention and only show the first line if no detail information is needed.
Most tools that show the history only show the first line of each commit.
But I agree with you, this still assumes that long commit messages are rare and not that almost every commit has a huge message. Also, "long" doesn't mean you should put a novel in there.
I think long is fine if that's necessary to get a rough idea of what the change is about across. Discerning in the choice of what information to include is perhaps a better way to put it. In those terms we should consider how likely it is for prompts to be immediately useful information when browsing the commit history, and whether it can't instead be reduced to an informative summary.
As far as specifications for changes go, the diff itself is as good a spec as it gets. It unambiguously describes the exact change that was made. The prompt you give a chatbot to make that change is IMO something else. Maybe it's more fair to call that a specification of the work you wanted it to perform.
Couldn't agree more. Rot is rot. People hate reading giant verbose AI generated PRs. Imagine mandating your codebase requires people now also read AI generated markdown files to compare the AI intent with the AI outcome. What a laugh and this is the guy giving out CS degrees and opposing React.
You could in theory require consistency of the spec with the product, but this is only valuable as a “source” if you ensure some kind of reproducibility. E.g., 9/10 times this spec + opus produces code that is equivalent, measured appropriately.
Mine doesn't. It mostly adds and keeps referencing previous decisions. Correctly, referring to them as being overridden. Even tweaking the original text or occasionally deleting a part. But text would look differently had it been written from scratch.
Unless a LLM works truly as a compiler, there will be a drift between the code and the spec.
For me they mostly append the end of the file with more sections or details. Heck it often adds very specific implementation details that it worked on recently that have no business being written in a repo wide summary.
Weird. I changed/amended model/integration and it updated table, provided explanation.
But yeah, I like to reference the docs so it can refresh his memory. But I may have had the .md files updated even if I didn't explicitly provide/ask for it, but a refactor that touched particular areas.
But yeah, my .md references others, it also maybe helps that my dir is named docs/ and it lists it somewhere in .md files... maybe its just the way it is structured helps infer agent what to do.
I agree, because at the end of the day the source code is the source of truth and that's what the LLM should look at instead of some months old markdown file.
Already happens in my experience. I'll try to figure out why it keeps doing this one thing and it turns out it's from some poorly advised info it put in a markdown file 20 commits ago that CLAUDE.md or AGENTS.md tell it to treat as gospel.
I think I'm with the majority of commenters here in thinking this would just wind up being clutter. Markdown might now generate code, but it isn't user facing and doesn't get shipped (I don't want to install a library and have a tonne of prompt text unnecessarily downloaded). I also don't really want to be on the hook for maintaining my co-workers past prompts etc.
For people who like this idea, or do something similar, how do you make use of prompts used to create code checked into your codebase?
I can see it valuable at the review stage, but if I was trying to trace-back a regression to a previous commit, I feel like I already have enough noise without this attached.
Prompts and LLM conversations have now become an important software artifact. I don't think the question should be whether or not to save them. They should be saved. The question is how to structure them in your folders and whether or not they should be part of the context for the LLM.
Our approach is to save LLM conversations but to not have them be part of the context.
If we go that route, can we have rich syntax highlighting, "go to definition"/"show usage sites", debuggers etc for the markdown docs as well? :)
But I don't really like the "LLMs as compiler" metaphor. If you followed that logic to the end, you'd have to "rebuild" your entire project from the spec every time the spec changes. Not just would the token cost be insane, but you'd also get a completely different implementation each time, maybe with different UI and design decisions where the spec left things open.
The alternative is to see the code as the source of truth and LLMs as (extremely sophisticated) editing or refactoring tools. Then by all means, still check in your prompts, but now they are documentation on how a feature was implemented, not the source of truth themselves.
I think that "machine translator" is a much better metaphor: there is a lot more to translating a text than there is to compiling code: contextual cues, cultural settings. Various translations can be equally valid. All translations are imperfect.
Now, if you excuse my ramblings, here are a few ideas: I think we probably need new "programming" languages that are actually specification languages: reproducible default states, deterministic spec-to-code transformation.
I am not sure we actually need the determinism, but that would be a good property to have. At least with the same model/spec/temperature.
Now, prompts mutate the spec, which can also be edited by hand. You can already do this with the final code of course, but it is tedious as it contains many trivial implementation details.
But then, how do you handle bugfixes that need to persist during re-generation? Such as "Both Foo and foo can be present in the same directory if the file system is case-sensitive". If you add them to the spec, you are micro-managing implementation details again. So I think such "bug fixes" should be part of a prompt/spec that is automatically loaded when generating similar snippets (here, file I/O). It feels like I've just reinvented the concept of software libraries, though.
I generally put markdown in /docs. I don't uppercase filenames. Instead I make a documentation generator consume the files so I get a decent navigation in HTML/PDF builds.
We did put non-code into /src for a very long time: It was heredocs, multiline docs, etc. Actually my preference is to put texts close to code and only fallback to /docs/something.md at a conceptual level. Which is probably what the author proposes, given that he sees markdown as primary interface to code.
In terms of a documentation artifact, I love what `cargo doc` generates, but when I'm inside a source file, any plaintext solution seems so limiting.
I actually miss what I had when I was playing around in TempleOS. All text in the OS is rich (you can toggle between the markup and the standard WYSIWYG view), so comments could have formatting, colours, images (bitmap or vector, great for diagrams), hell, even (aggressively spinning) 3D models.
The thing I used most was the collapsible sections, think <details> and <summary> in HTML. Although I appreciate plain text and would hate WYSIWYG rich text in my serious source code (not to mention binary data appended to the end of the source file for images and models), I can't help but pine for those features. Being able to just draw a real diagram and being able to edit it later in seconds as opposed to making some horrid ASCII art was awesome.
Personally, I build a loosely compiled / linted DSL to handle spec.
It's a SEXP language but could just as easily be markdown. It'd probably be better if it was - I spend a lot of tokens matching parentheses.
Compared to markdown - I lose some human readability but gain a lot in workflow.
For me - it turns the sort of "free form jazz code odyssey" into something with structure. It changes the question to "does the spec match my idea? And does the code match my spec?"
Every so often, I do a "code astrology reset" and try to purge all the tricks I use to keep things functional. I absolutely notice an efficiency hit when I don't have a spec language. Even with the new models - I find this essential to keep things on track.
I think most people on large projects hit a scaling ceiling with markdown specs. They get massive and contradictory very quickly. I think a src/md folder is a good strategy. I try to organize with a "one spec per module" rule. It doesn't always happen that way but I find that helpful.
I think Literate Programming is a good inspiration here. I also think Yegge's beads and Gastown have some really smart things to say in this regard - even if he's a bit tokenmaxxy for my taste.
If the goal is "locality", you can't get much closer than as a comment.
As far as markdown becoming "source code for agents" under the agentic paradigm, per-directory `AGENTS.md` seems more consistent, at least visually. If agent managed markdown is going to be high-churn, I'd rather it be confined to a single file. Constraints, especially for agents, are good.
In my adjunct teaching I tell all my students to focus on "why" comments. Everyone parrots that code should be self-commenting, and for the most part they are correct (conceding that, for long cryptic lines of regex, or trendy Python one-liners, the "what" comments can still be useful) -- but they miss the core idea of why comments are useful. I can't see into your brain as the other programmer. To me, your design choice might appear stupid, brainless, or completely baffling; but if you put a comment telling me why you did it that way, I'm a lot less likely to get fixated on the shenanigans when I'm the guy picking up your code 5 years later.
Markdown is non deterministic when it comes to piping it through an LLM. Sure the prompt intent is the same, but it doesn't guarantee the same output.
I would much rather have significantly more detailed comments inline with code to describe the intention at any given step than just a high level markdown file. We already have PDRs and markdown seems like it would just be an extension of that.
You have to track the thing that you expect humans to understand. I still prefer for the code to be that layer, and yet somehow I'm still employed and overseeing a profitable codebase. The software industry is vast and varied.
Essays of this nature should generally be prefixed with "if you happen to work in exactly the same way that I do..."
In-between all those ephemeral agent sessions, spec, plan and design files, there is something that survives. The src/*.md files.
With Varar you can link small parts (cells) of those Markdown files to your code, so they stay in sync. So you (and agents) can find out what your system does without reading 300 million lines of code.
Full disclaimer: I am the guy who wrote Cucumber - that most people here hate. I eventually lost my love for that tool myself, but I did miss the ability to keep docs and code in sync. Hence Varar - a tool like that with fewer (different?) warts, for the agentic area.
I have found a lot of value in the approach the post describes. I store my markdown as GitHub issues, regardless of how I come up with a detailed feature description (usually a chat session).
Before implementation, context is always cleared to ensure that the model is working only from known context (skills, AGENT.md, etc).
A major benefit of this is that agents can look up prior prompt instructions as needed or when mentioned in the current prompt it's working on.
src/
md/
README.md # index of all md, entry point for agents
TODO.md # a list of general TODOs open for this module
OVERVIEW.md # a technical overview of this module
features/FEATURE_1.md # a set of feature-specific documents
data/DATAMODEL_1.md # descriptions of data models in the module
api/API_1.md # descriptions of APIs the module provides
infrastructure/INFRASTRUCTURE_1.md # descriptions of infrastructure used by the module
What if we standardized on README.md in each subdirectory alongside the code?
src/
README.md # entry point for humans and agents
TODO.md # list of general TODOs open for this module
INFRA.md # descriptions of infrastructure used by the module
api/
README.md # descriptions of APIs the module provides
models/
README.md # descriptions of data models in this module
README.md in each subdirectory seems to align better with OP’s objective “that Markdown should be checked in to /src, next to the code it produces”. It is also a convention already in use in many code repositories.
MDs in subdirectories is how Anthropic recommends it too. If you have a CLAUDE.md in a subdirectory and an agent starts working in there, it's appended
I think these are different things. The source code, it’s tests, it’s documentation, it’s data. They are different perspectives to approach a given body of work while together building an overall understanding. It doesn’t matter at all where the files live but when you approach the work from that perspective you know how to find it, and I don’t think next to the source but away from the others is a good combination.
But we already have a folder for docs? It's called "docs". If the docs are the source code, that's fine, but that doesn't mean we have to move them into the source code folder. We already have somewhere to put them! The end goal should be for the source code folder to be in the .gitignore, same as you would with object files... but if the docs are in there, now you're stuck.
No, this is not a source file to be used to generate code. It's a spec to be used to build the code to - same as any other document. Aside from the fact that docs can be in any format - not merely .md - they do not belong in `src/`. Why? Well for one, many of my projects have multiple `src/` directories because they involve multiple binaries. But the documentation used to generate that source is in the project, not the `src/` directory of one of its binaries. I'm building a video streaming site that uses one server for the SFU, one server for the web interface, one server for the websocket connections, as well as STUN and TURN servers. None of the project works unless all these separate binaries are working together and communicating. Which `src/` directory should I place these markdown files in? What about the `.sql` files I use to spec out the database schema before passing it off to the LLM? What about the mermaid files, code snippets, `.txt` files, and data files used as part of the documentation project? Should they all go in `sfu/src/md/`? No. The project is one whole with multiple `src/` directories and they all require their own documentation. Beyond that they need access to each other's documentation so that when the agent is working on one part of the system it can still be aware of how the other pieces operate. Documentation should absolutely be under version control, but placing it in the `src/` directory is plainly the wrong call. And there is more documentation than just markdown. This was a shower thought that wasn't completely fleshed-out (and the article admits it wasn't) and never should've made it to the front page of HN.
This is an experimental thought. If people are vibe coding apps without looking at code, the argument here is that maybe ad-hoc prompts is not the best way to capture that because you lose the instructions. So the proposal, why not have those instructions saved as markdown files at least we have a reference in English.
We don't look at binaries, we don't look at assembly, we work with high level languages. The specs were for developers to translate to programming primitives, but if the translation is largely automated, then the specs will become the code and we will need better ways to manage those, and I think the IDEs are gradually trending that way, look at all the most recent agentic dev tools, it surely follows that trend.
With respect to not having this piece on HN. If the author is seeing many organizations doing this practice, then why he would not share that empirical observation? is it only because it is against your pure world and abstractions? Just the recent leak for the Muse agent shows that most of the system behaviour is written in markdown.
Whether you like it or not, technology never care about purest and idealist, it evolve under pressure of deliveries and pragmatic choices, and if there is such a pressure, which the author claims to be, then HN is the medium to share it.
1. he is saying md/english is the new source code..
2. yes - it is different that is geared towards english and very well supported by LLMs that is why it is being used in memory and instructions
3. llms are deterministic enough to translate adequately described specs into working system, the idea here is reason in md for core flow etc, and then verify with test cases
this not perfect but he is describing a real trend, so listen with open mind.
Well summarized, but I believe this is sadly why we're seeing a decline in software quality all over. And if people keep following this trend for libraries and core utilities... yikes things will get bad.
Yeah but keep in mind this tech only started to work last year? People still figuring it out, and I'm sure we will have more robust tooling, processes around it down the road.
The upside is that we are able to deploy more cognitive power into problems, security, edge cases, something that uses be to scarce. A lot of the people feeling insecure mainly because they benefited from that scarcity. But we will have more software deployed, I'd argue better, and larger, and this means the pie of software is getting bigger, the market is getting larger, deeper into the economy.
you need to have developer doc in src, is the only way to have the full picture in the future. The main point is to keep it in sync, the agent harness must enforce that
We are close to inventing something like deep modules [1] for markdown and a whole methodology of managing docs abstraction and layers. And I'm somewhat serious. It's hard to manage one random, interconnected bag of (spaghetti) markdown. Abstract is the new interface.
Docs is already a notoriously under-prioritized and often rotting part of software projects. Making it more complex and larger to maintain and update doesn't feel like the right solution.
Nested markdown or restructured-text or asciidoc is pretty good workflow already to re-use blocks, link to different pages, or do some rich formatting like collapsible sections.
Markdown in /src comes with some unwelcome assumptions.
This is being done with an agent-first approach in mind. Agents cost a lot to run. Moving markdown to /src will only help AI subscription sellers.
If you are a fan of local LLM, then you also know code is not cheap. It requires substantial amount of investment in infra acquisition and maintenance.
Markdown should be where they always were, in /docs. It does not make a difference for an agent. But it allows to keep /src clean and adhere to zero-token architecture.
In many apps I've built, every decision is stored in Markdown files under docs/. But documentation can become obsolete, even comments inside source files can.
I assume src/ is treated as the source of truth. If we start placing Markdown documentation inside src/, outdated documentation can live alongside the actual source of truth, blurring the boundary between what the system actually does and what the documentation says it does.
I wonder how would this work in an international dev teams. While code is always the common language (including the UML), markdown requires you to have really good english writing skills. This can get messy really fast.
Let’s keep the Codex session JSONL there too, why the hell not. And the debug build logs, since they’re easily greppable text useful for diagnosing recurring problems. And logs/reports from every test run - a ton of useful info there, lets you track regressions over time; would be a shame to throw it away. We could also store screenshots of every app run to have a LLM-compatible historical record of how each component changed visually. And the token provider billing documents, since we’re gonna have a lot of those once we’ll start maintaining all that.
The author is really just advocating for design docs, which do make sense in a repo. LLMs are excellent at creating .md docs tracking design decisions, code architecture, trade-offs, etc. And these actually can be of great use to future contributors.
I realize I've been doing this as part of working with agents heavily the last few weeks. The issue is remembering to have it write and keep them up to date. One thing I've been considering is using a Claude Hook[1] when the session ends to basically "update readme and todo from this session. only change them if needed" or something similar
I still like the idea of source code as documentation and unit tests as documentation. While revising code written by an LLM to make it easier for humans to understand is now a controversial practice, I believe it's worthwhile in a lot of case.
Hi there. I wrote this as a bit of speculation since I'm seeing more and more agent based coding in my consulting.
One thing to say given some of the comments here: in this approach the stuff in /src/md would be treated as well as stuff in /src/java or whatever: it would need to be maintained as precisely as possible, not just be a stream of development record of what has happened.
I'm also happy to consider that Markdown might not be the right format for this, or that the whole thing is a terrible idea. But I see people saving content in other places (linear, etc.) that drive agents and it just seems like maybe we should keep that stuff close to the generated source.
No different than UML diagrams: if you don't compile them to get your executable/binary, then they are out of date within a week. The code is the source of truth. Feel free to put steering in your docs. You can also use AI to make sure the docs still match the code.
so the holy grail of software engineering is a tool that allows us to commit minimally sufficient design documents as source code.
i'd be enthused to work this way if changes to `src/*.md` files could be "hot-reloaded" on save, like an iterative LLM watch compiler, and skipping the chat prompts altogether.
src/md doesn’t seem all that different from docs. Maybe it changes how people search the filesystem, though?
If you split code up into multiple packages, moving the docs closer to the code might make sense. The docs for package foo could be in packages/foo/docs.
Interesting article, and I generally agree! And I'm just thrilled it's being discussed at all, as a MyST superfan. That said, a few quibbles I'd be curious to hear thoughts on:
First, none of this changes the need for a separate `/docs` dir, also checked into git. Wikis are fun, but docs are essential!
Second, I personally think the new paradigm will be putting all of this into tons of new README.md files, which I'm kinda baffled aren't more common deep into dir hierarchies already. That intuitively tells the human authors and the artificial readers that;
A) it toes a similar "for technical people but not necessarily just our dedicated engineering team" line as the root README --more formal than an ephemeral "prompt" and less formal than a user-facing doc,
B) this isn't the AGENT.md file so should remain human-authored only,
C) this is only an overview with a strong preference for brevity & clarity, and
D) this is focused on this specific directory (along w/ the other benefits of locality, as the author extolls already).
Have I cracked the code? Is there a Turing award for inventing the concept of using a tool we already use but just a bit more extensively -- or at least a YC slot?
> A Proof of Concept for LLM as source code. I am of the position that the "code" is now target code and not source code. My strongest source for this claim is Stallman's classical definition of Source Code which is the "preferred way to modify the program".
> Upload the conversation with ChatGPT as source code
Although this was pre-agents/markdown, the main way to generate code was just with user-interface conversations with the LLM.
And my position differs in which I argue against uploading the target code, just the source code. Which is an issue if the LLM is not deterministic, but it's workable.
That said I apparently did foreshadow solutions to these issues
> Since we are using a consumer interface, and not an api, (first we have no guarantees that the code will not be used for training, so there's no IP protection, but also), we don't have much reproducibility, robust publishing should use API access and publish exact model with revision as well as seed (and even then we are not guaranteed reproducibility.
I think in general we'll end up rewinding so much, the sloppers are recursing and building a ton of harnessing tools that will need to be trashed because they made a fundamental mistake at the very first steps. Those of us who are a bit more careful will probably only get back to agentic engineering once the slopper activity dies down, it's pretty much career suicide at this point to get into it. Anyone who is barely careful is just waiting it out.
Cluttering the repo with out-dated, very wordy and quickly aging prompts will just confuse any agent tasked with looking at the repo in the future. Keeping context windows down is a real limitation to good LLM output, and this workflow may work completely against it.
- A plan.md describing the project, main abstraction idea, end costumer, and so on is great; but it should be kept minimal and up-to-date with the repo.
- Block comments on top of source-files and functions are great, and already very useful to coding agents. I don't see a value to anything more than what is already typical best practice.
If prompts are specifications for a change of the system's behavior, then it seems natural to manage them as changes and not as resources.
This would also keep them in the right "historical context" of the repo and avoid the "prompt rot" you were talking about.
Functional safety development processes often demand code-review, technical design decisions, changes of plans, or intentional compromises; to be linked together with reference IDs in the code they effect. But the workflow for this is usually extremely manual and absolute misery. But a codebase made like this is like magic to read later.
You'd consequently only need to implement your custom git gui and extension to visualize this information.
Maybe a good project for the next weekend? Just eg make a prototype tui in golang and see where you end up
The tech and data-structure is there; but the common UX is not quite expressing the data in a sophisticated manner. It doesn't help that the default diff algorithm is rather crude as-well.
The reason is that the commit message log serves as an overview of the changes commited. That's what humans use it for, anyway: to get an idea of what happened since they last pulled, to help give an idea of where a regression might have been introduced and so on, at a glance. To that end, brevity is very useful.
My understanding is that chatbots used to perform such tasks will also benefit from brevity.
AFAIK, the first line is supposed to be the a very brief summary, while the other lines may contain additional information and can sometimes make up a pretty long text. Lots of tools make use of this convention and only show the first line if no detail information is needed.
Most tools that show the history only show the first line of each commit.
But I agree with you, this still assumes that long commit messages are rare and not that almost every commit has a huge message. Also, "long" doesn't mean you should put a novel in there.
As far as specifications for changes go, the diff itself is as good a spec as it gets. It unambiguously describes the exact change that was made. The prompt you give a chatbot to make that change is IMO something else. Maybe it's more fair to call that a specification of the work you wanted it to perform.
Ok I already talked myself out of this idea.
Unless a LLM works truly as a compiler, there will be a drift between the code and the spec.
But yeah, I like to reference the docs so it can refresh his memory. But I may have had the .md files updated even if I didn't explicitly provide/ask for it, but a refactor that touched particular areas.
But yeah, my .md references others, it also maybe helps that my dir is named docs/ and it lists it somewhere in .md files... maybe its just the way it is structured helps infer agent what to do.
"yes claude i prefered the blue graph two months ago, how does thar help us with this json parsing bug?"
For people who like this idea, or do something similar, how do you make use of prompts used to create code checked into your codebase?
I can see it valuable at the review stage, but if I was trying to trace-back a regression to a previous commit, I feel like I already have enough noise without this attached.
Any prompt-storing/sharing ideas floating around hit the same wall - they assume the text will be in English. It won't.
Our approach is to save LLM conversations but to not have them be part of the context.
have they though? I feel like 50% of the chat history is gettin in the way of the model that just created it half the time, let alone any future LLM.
Humans wont re-read an old chat history either unless very desperate for clues.
The few valuable nuggets of information in the chat history can probably be summarize into 3 bullet points and put in the docs or in code comments.
I really dont see the value.
Much of the knowledge of writing the software is manifest and captured in those chats. and we share them so that we can learn from each other.
But I don't really like the "LLMs as compiler" metaphor. If you followed that logic to the end, you'd have to "rebuild" your entire project from the spec every time the spec changes. Not just would the token cost be insane, but you'd also get a completely different implementation each time, maybe with different UI and design decisions where the spec left things open.
The alternative is to see the code as the source of truth and LLMs as (extremely sophisticated) editing or refactoring tools. Then by all means, still check in your prompts, but now they are documentation on how a feature was implemented, not the source of truth themselves.
Now, if you excuse my ramblings, here are a few ideas: I think we probably need new "programming" languages that are actually specification languages: reproducible default states, deterministic spec-to-code transformation.
I am not sure we actually need the determinism, but that would be a good property to have. At least with the same model/spec/temperature.
Now, prompts mutate the spec, which can also be edited by hand. You can already do this with the final code of course, but it is tedious as it contains many trivial implementation details.
But then, how do you handle bugfixes that need to persist during re-generation? Such as "Both Foo and foo can be present in the same directory if the file system is case-sensitive". If you add them to the spec, you are micro-managing implementation details again. So I think such "bug fixes" should be part of a prompt/spec that is automatically loaded when generating similar snippets (here, file I/O). It feels like I've just reinvented the concept of software libraries, though.
We did put non-code into /src for a very long time: It was heredocs, multiline docs, etc. Actually my preference is to put texts close to code and only fallback to /docs/something.md at a conceptual level. Which is probably what the author proposes, given that he sees markdown as primary interface to code.
I actually miss what I had when I was playing around in TempleOS. All text in the OS is rich (you can toggle between the markup and the standard WYSIWYG view), so comments could have formatting, colours, images (bitmap or vector, great for diagrams), hell, even (aggressively spinning) 3D models.
The thing I used most was the collapsible sections, think <details> and <summary> in HTML. Although I appreciate plain text and would hate WYSIWYG rich text in my serious source code (not to mention binary data appended to the end of the source file for images and models), I can't help but pine for those features. Being able to just draw a real diagram and being able to edit it later in seconds as opposed to making some horrid ASCII art was awesome.
It's a SEXP language but could just as easily be markdown. It'd probably be better if it was - I spend a lot of tokens matching parentheses.
Compared to markdown - I lose some human readability but gain a lot in workflow.
For me - it turns the sort of "free form jazz code odyssey" into something with structure. It changes the question to "does the spec match my idea? And does the code match my spec?"
Every so often, I do a "code astrology reset" and try to purge all the tricks I use to keep things functional. I absolutely notice an efficiency hit when I don't have a spec language. Even with the new models - I find this essential to keep things on track.
I think most people on large projects hit a scaling ceiling with markdown specs. They get massive and contradictory very quickly. I think a src/md folder is a good strategy. I try to organize with a "one spec per module" rule. It doesn't always happen that way but I find that helpful.
I think Literate Programming is a good inspiration here. I also think Yegge's beads and Gastown have some really smart things to say in this regard - even if he's a bit tokenmaxxy for my taste.
One example is SpiderMonkey, which uses these beautiful, long expository comments explaining not only what, but why design choices have been made. https://searchfox.org/firefox-main/source/js/public/RootingA...
If the goal is "locality", you can't get much closer than as a comment.
As far as markdown becoming "source code for agents" under the agentic paradigm, per-directory `AGENTS.md` seems more consistent, at least visually. If agent managed markdown is going to be high-churn, I'd rather it be confined to a single file. Constraints, especially for agents, are good.
I would much rather have significantly more detailed comments inline with code to describe the intention at any given step than just a high level markdown file. We already have PDRs and markdown seems like it would just be an extension of that.
Source code main attribute should be reproducable builds...
Same source gives the same output.
The interesting part of any program source is what it took to make that program. I view AI-generated code in the same category that I see a binary.
[1] https://blog.tombert.com/Posts/Technical/2026/04-April/Stop-...
Essays of this nature should generally be prefixed with "if you happen to work in exactly the same way that I do..."
In-between all those ephemeral agent sessions, spec, plan and design files, there is something that survives. The src/*.md files.
With Varar you can link small parts (cells) of those Markdown files to your code, so they stay in sync. So you (and agents) can find out what your system does without reading 300 million lines of code.
Full disclaimer: I am the guy who wrote Cucumber - that most people here hate. I eventually lost my love for that tool myself, but I did miss the ability to keep docs and code in sync. Hence Varar - a tool like that with fewer (different?) warts, for the agentic area.
Before implementation, context is always cleared to ensure that the model is working only from known context (skills, AGENT.md, etc).
A major benefit of this is that agents can look up prior prompt instructions as needed or when mentioned in the current prompt it's working on.
I recently described my workflow here https://jaisenmathai.com/articles/sojourn-for-ios-was-45-one...
This is not doc, this is an .md file as a src to be used by LLMs to generate code. Therefore they are src files but in english.
We don't look at binaries, we don't look at assembly, we work with high level languages. The specs were for developers to translate to programming primitives, but if the translation is largely automated, then the specs will become the code and we will need better ways to manage those, and I think the IDEs are gradually trending that way, look at all the most recent agentic dev tools, it surely follows that trend.
With respect to not having this piece on HN. If the author is seeing many organizations doing this practice, then why he would not share that empirical observation? is it only because it is against your pure world and abstractions? Just the recent leak for the Muse agent shows that most of the system behaviour is written in markdown.
Whether you like it or not, technology never care about purest and idealist, it evolve under pressure of deliveries and pragmatic choices, and if there is such a pressure, which the author claims to be, then HN is the medium to share it.
1. he's describing a manual version of Spec-Kit / OpenSpec / BMAD?
2. Thinks Markdown is... somehow different from normal text or other markup languages?
3. Doesn't seem to understand that LLMs are not deterministic?
this not perfect but he is describing a real trend, so listen with open mind.
The upside is that we are able to deploy more cognitive power into problems, security, edge cases, something that uses be to scarce. A lot of the people feeling insecure mainly because they benefited from that scarcity. But we will have more software deployed, I'd argue better, and larger, and this means the pie of software is getting bigger, the market is getting larger, deeper into the economy.
IME developers have low tolerance for interrupting flow to track down the docu that is aimed at them, so keep it near and obvious.
1. https://softengbook.org/articles/deep-modules
Nested markdown or restructured-text or asciidoc is pretty good workflow already to re-use blocks, link to different pages, or do some rich formatting like collapsible sections.
My conclusion is, that i want neat markdown. Hence it needs to be linted/formatted.
Developed a linter/formatter https://mdsmith.dev to specifically do that. Includes tooling for progressive disclosure, etc.
This is being done with an agent-first approach in mind. Agents cost a lot to run. Moving markdown to /src will only help AI subscription sellers.
If you are a fan of local LLM, then you also know code is not cheap. It requires substantial amount of investment in infra acquisition and maintenance.
Markdown should be where they always were, in /docs. It does not make a difference for an agent. But it allows to keep /src clean and adhere to zero-token architecture.
I assume src/ is treated as the source of truth. If we start placing Markdown documentation inside src/, outdated documentation can live alongside the actual source of truth, blurring the boundary between what the system actually does and what the documentation says it does.
Yes, proximity indeed helps. However, I feel its better to automate docs revision using skills and related instructions in claude.mf/agents.md
I am building something in related problem, which is architecture visualisation
One thing to say given some of the comments here: in this approach the stuff in /src/md would be treated as well as stuff in /src/java or whatever: it would need to be maintained as precisely as possible, not just be a stream of development record of what has happened.
I'm also happy to consider that Markdown might not be the right format for this, or that the whole thing is a terrible idea. But I see people saving content in other places (linear, etc.) that drive agents and it just seems like maybe we should keep that stuff close to the generated source.
i'd be enthused to work this way if changes to `src/*.md` files could be "hot-reloaded" on save, like an iterative LLM watch compiler, and skipping the chat prompts altogether.
I don't like it though.
If you split code up into multiple packages, moving the docs closer to the code might make sense. The docs for package foo could be in packages/foo/docs.
First, none of this changes the need for a separate `/docs` dir, also checked into git. Wikis are fun, but docs are essential!
Second, I personally think the new paradigm will be putting all of this into tons of new README.md files, which I'm kinda baffled aren't more common deep into dir hierarchies already. That intuitively tells the human authors and the artificial readers that;
A) it toes a similar "for technical people but not necessarily just our dedicated engineering team" line as the root README --more formal than an ephemeral "prompt" and less formal than a user-facing doc,
B) this isn't the AGENT.md file so should remain human-authored only,
C) this is only an overview with a strong preference for brevity & clarity, and
D) this is focused on this specific directory (along w/ the other benefits of locality, as the author extolls already).
Have I cracked the code? Is there a Turing award for inventing the concept of using a tool we already use but just a bit more extensively -- or at least a YC slot?
*P.S.* OP you dropped this: )
> That Markdown should be checked in to /src
I've made a similar argument last June, although I made the point with a sample project rather than manifesto style
https://github.com/TZubiri/keyboard-transpositions-checker
> A Proof of Concept for LLM as source code. I am of the position that the "code" is now target code and not source code. My strongest source for this claim is Stallman's classical definition of Source Code which is the "preferred way to modify the program".
> Upload the conversation with ChatGPT as source code
Although this was pre-agents/markdown, the main way to generate code was just with user-interface conversations with the LLM.
And my position differs in which I argue against uploading the target code, just the source code. Which is an issue if the LLM is not deterministic, but it's workable.
That said I apparently did foreshadow solutions to these issues
> Since we are using a consumer interface, and not an api, (first we have no guarantees that the code will not be used for training, so there's no IP protection, but also), we don't have much reproducibility, robust publishing should use API access and publish exact model with revision as well as seed (and even then we are not guaranteed reproducibility.
I think in general we'll end up rewinding so much, the sloppers are recursing and building a ton of harnessing tools that will need to be trashed because they made a fundamental mistake at the very first steps. Those of us who are a bit more careful will probably only get back to agentic engineering once the slopper activity dies down, it's pretty much career suicide at this point to get into it. Anyone who is barely careful is just waiting it out.