Design principles for structuring projects so that AI-assisted iteration is precise, auditable, portable — and gets better every time you use it.
Most AI workflow failures come from one of two structural mistakes.
The first is entanglement: content, rendering, and logic are fused into monolithic files. A 1,000-line HTML file that mixes copy, layout, and code is technically one thing but contains three distinct concerns. When an AI edits that file to change a headline, it must navigate the entire structure and risk mutating unrelated sections. The larger and more entangled a file, the noisier and more dangerous each edit becomes.
The second is amnesia: each session starts from zero. The AI reconstructs intent from code, re-litigates decisions already made, repeats mistakes from prior runs, and produces no artifact that makes the next session cheaper. Work accumulates in conversation history — which expires — rather than in files, which persist.
Data redundancy solves entanglement. Artifact-based design, or deposit-based design, solves amnesia. Together they define a project architecture where AI collaboration is fast, precise, and self-improving.
How to represent information so that AI can work on it precisely, right now.
Every project that produces a visual or formatted output has two distinct layers:
- The content layer — the words, data, structure, and intent
- The rendering layer — the CSS, templates, code, or tooling that makes it look right
The rendering layer should be treated as stable infrastructure. The content layer should be explicit, human-readable, and independently editable. When an AI needs to iterate on what a slide says, a homepage declares, or a pipeline step does, it should be editing the content layer — not navigating the renderer.
Applied: A slide deck with embedded HTML content should have a companion slides.yaml that defines each slide's headline, subline, theme, and data fields. The HTML reads from that manifest. Iterating on the pitch means editing the YAML; iterating on the design means editing the HTML. A pipeline step's goal, expectedInput, and expectedOutput are content — they live in a separate content block from the config that governs capabilities and permissions.
The rule of thumb: if a non-technical person could reasonably edit it, it's content. If changing it requires understanding the system, it's infrastructure.
Not all redundant formats are equally useful. Evaluate a format on three axes:
Human legibility — Can a person read it cold and understand what it contains? A YAML manifest or Markdown outline is legible. A binary .pptx or a minified JSON blob is not.
Diffability — Does a version control diff tell you exactly what changed? Line-oriented text formats produce clean, meaningful diffs. Binary formats produce noise. This matters especially in AI workflows where many small iterations happen in rapid succession — and where the diff is the record of what the AI changed.
Structural expressiveness — Can the format represent the actual shape of the data? Short, labeled, multi-field content fits YAML. Prose-heavy documents fit Markdown. Tabular data fits CSV or JSON. Forcing the wrong format onto content creates friction for both humans and AI.
| Content type | Recommended format | Avoid |
|---|---|---|
| Labeled fields (slides, steps, configs) | YAML | Binary formats as source of truth |
| Prose documents | Markdown | Monolithic HTML |
| Tabular / structured data | CSV or JSON | Spreadsheet as single source |
| Configuration / metadata | YAML or TOML | Embedded in code |
| Hierarchical / nested data | JSON | Flat text |
| Run records, audit logs | YAML | Database-only storage |
A redundant file that drifts from the rendered artifact is worse than no redundant file at all — it creates confusion about which version is authoritative. The content file should be canonical, and the rendered output should be a downstream artifact that can be regenerated from it.
This means edits happen in the content file and propagate to the render. The rendered output is never edited directly. Version control commits the content file; the rendered artifact may or may not be committed depending on whether it needs to be shared.
In practice, strict propagation discipline is hard to maintain in fast-moving projects. At minimum, the content file should be updated any time the rendered output changes, and the two should be reviewed for sync before any major milestone. When in doubt, the file wins over the rendered output.
When a human edits a file, they use a GUI, can see the rendered result in real time, and develop intuition for the structure over time. An AI reads text, makes edits, and cannot visually verify the result. A well-structured content file is a collaboration interface designed specifically for this constraint. It should be:
- Scoped: Only the content an AI needs to change, not the full implementation
- Labeled: Fields with clear, consistent names so the AI can target precisely (
goal, not an unnamed string) - Flat where possible: Deeply nested structures create more surface area for edit errors
- Commented if helpful: Short notes explaining non-obvious constraints (
# keep under 12 words for layout) prevent well-intentioned but layout-breaking changes
The better this interface, the faster each iteration round and the lower the error rate. A content layer that takes two hours to design saves ten hours of noisy edits.
Content locked inside a rendered format is difficult to repurpose and impossible to review quickly. A pitch narrative embedded only in an HTML slide deck cannot easily become a PDF, a PPTX, or a speaker script without reverse-engineering the render.
A content layer that exists independently can serve as input to multiple renderers. The same slides.yaml can generate an HTML presentation, a PowerPoint deck, a printed summary, and a text outline — each from the same authoritative source.
Auditability is equally important. Before a stakeholder review or content handoff, a content file can be read top to bottom in minutes to verify the narrative arc, check for outdated claims, or confirm consistency. A rendered file requires opening the application and clicking through it. In AI workflows specifically, this matters: it lets the human verify that accumulated edits across many sessions have produced a coherent whole, rather than a document where each part was locally optimized but the whole has drifted.
How to design systems so that each action makes the next one cheaper.
Data redundancy is synchronic — it describes how information should be structured at any given moment. Depositional design is diachronic — it describes how a project should evolve over time so that each session, each run, and each decision accumulates into a foundation that makes future work faster and better.
The question depositional design asks is not "is this file well-structured?" but "does this file, when written, make the next session or the next run more valuable than the last?"
The default AI workflow pattern is: start a session, produce an output, end the session. The output is the goal. What the session leaves behind — the decisions made, the patterns discovered, the mistakes corrected — is typically lost to conversation history.
A compounding workflow treats every session output as two things: the deliverable, and the deposit. The deposit is what gets written back to the content layer to make the next session cheaper. Over time, the deposit compounds: the content layer becomes denser, more precise, and a more reliable starting point.
Applied: A DECISIONS.md file that logs architectural choices with rationale is a deposit. A PATTERNS.md file that records discovered conventions is a deposit. An AI that edits the codebase and also updates these files after each session compounds. An AI that only edits the codebase starts fresh every time.
The flywheel rule: every session should be able to describe what it added to the content layer — not just to the output.
In a compounding system, the output of every action is structured to be the input of a future action. This is not automatic — it requires designing output formats with their downstream consumption in mind.
A pipeline run that produces a plain text log meets the deliverable requirement. A pipeline run that produces a structured YAML audit file — with step-by-step inputs, outputs, durations, and status — meets the compounding requirement. The audit file can be read by the next run to improve step configurations. It can be diffed against a previous run to understand what changed. It can be queried by Claude to answer "what did this pipeline actually do last time?" without re-running it.
The difference is not in the information produced — it's in whether that information is captured in a format that can flow back into the system.
The depositional output checklist:
- Is the output human-readable? (data redundancy)
- Is the output machine-queryable? (depositional design)
- Does the output have a stable schema that future sessions can rely on? (both)
- Does the output accumulate — i.e., does having ten of them tell you more than having one? (depositional design specifically)
The canonical depositional design artifact is the index — a lightweight file that grows with every run, session, or event, and enables the system to answer historical questions without parsing every individual record.
A runs-index.yaml that appends one entry per pipeline run lets the app show run history on load in milliseconds, without parsing individual audit files. A step-stats.yaml that updates per-step success rates after every run lets the UI surface reliability signals without any explicit analysis step. These files start small and compound indefinitely — the more they accumulate, the more valuable they become.
Index design principles:
- Append-only: Never overwrite history; only add to it
- Lightweight: Store metadata, not full content — the full content lives in individual record files
- Stable schema: New sessions must be able to read indexes written by old sessions without migration
- Machine-first: Designed for the app or AI to query; the individual record files are human-first
In a compounding system, artifacts improve through use. A pipeline template that started as a design exercise and has since run successfully fifty times is a fundamentally different artifact than one that was designed and never tested. The compounding system should reflect this.
The promotion pattern: artifacts that have been validated through real use get elevated in status — from draft to canonical, from personal to shared, from experimental to template. The mechanism should be as low-friction as possible. A pipeline that has run N times successfully can be promoted to a template via a file copy. A pattern discovered in three sessions gets added to PATTERNS.md. A decision made twice and second-guessed once gets added to DECISIONS.md with rationale, so it doesn't get made a third time.
Promotion is how the compounding system encodes institutional knowledge without requiring explicit knowledge management. The knowledge compounds because the artifacts that carry it improve through use.
An AI agent's context window is ephemeral — it expires with the session. The files it reads and writes persist. The content layer is therefore the AI's only form of long-term memory, and it should be designed explicitly for that purpose.
A content layer that works as cross-session memory is not just accurate — it is dense. It contains not just what the project does, but why decisions were made, what was tried and rejected, what patterns have been discovered, and what the current status is. Each session that reads this content layer starts from a higher baseline. Each session that adds to it leaves the project smarter.
The test for whether a content layer is working as memory: Can a new session, reading only the content layer with no conversation history, pick up where the last session left off — without re-making the mistakes of the sessions before? If yes, the memory is working. If no, sessions aren't depositing enough.
Data redundancy and depositional design are not separate practices — they are two faces of the same principle: information should exist in the most useful form for the work that needs to happen on it.
At any given moment, that means a clean, scoped, labeled content layer that an AI can edit precisely. Across time, that means a content layer that accumulates, gets denser, and starts each new session higher than the last.
| # | Principle | Type | What it prevents |
|---|---|---|---|
| 1 | Separate content from rendering | Redundancy | Noisy, high-risk edits in monolithic files |
| 2 | Choose legible, diffable formats | Redundancy | Unreadable history, binary noise |
| 3 | Content file is the source of truth | Redundancy | Drift between content and render |
| 4 | Design for AI as collaboration interface | Redundancy | Slow, error-prone iteration rounds |
| 5 | Enable portability and auditability | Redundancy | Locked-in formats, invisible drift |
| 6 | Design for the flywheel, not the sprint | Depositional | Sessions that start from zero |
| 7 | Outputs become inputs | Depositional | Ephemeral results that don't accumulate |
| 8 | Accumulating indexes as flywheel mechanism | Depositional | Expensive historical queries, no signal |
| 9 | Proven artifacts promote upward | Depositional | Knowledge lost after each use |
| 10 | Content layer as cross-session memory | Depositional | AI that re-litigates decisions and repeats mistakes |
Test 1 — Precision (data redundancy working): Can an AI edit a single field in the content layer without touching anything else? If the answer requires navigating a rendering layer or entangled logic, the content layer needs more separation.
Test 2 — Compounding (depositional design working): After ten runs or ten sessions, does the system know more than after one? Can it answer "what has this actually done?" without re-running it? Can it surface which parts are reliable and which are not, without any explicit analysis step?
Test 3 — Memory (both working together): Apply the test from Principle 10 directly. If it fails, sessions are not depositing enough.
For a new project:
- Define the content layer before writing any rendering code. What are the fields? What format? What schema?
- Identify the three most important things a future session will need to know. Write them in a
DECISIONS.mdbefore starting. - Design the first output format to be machine-queryable as well as human-readable. What will the tenth run know that the first run doesn't?
For an existing project:
- Find the most entangled file. Extract its content into a separate, flat, labeled YAML or Markdown file.
- After each session, spend five minutes updating
DECISIONS.mdandPATTERNS.mdwith what was learned. The deposit is as important as the deliverable. - Look at what the last several runs produced. Is there a structured artifact that accumulates that information? If not, design one.
The one question to ask before ending any session:
What does the content layer know now that it didn't know when this session started?
If the answer is nothing, the session didn't compound.