Literate Coding Guidelines

Coding & Documentation Guidelines for People and LLMs

Purpose

Guidelines for structuring code, configuration, and documentation so that people and language models can work together more reliably.

These guidelines are meant to be general. They should make sense whether the assistant is ChatGPT, Claude, Opus, Gemini, Copilot, or any future coding model. They apply to dotfiles, config management, project scaffolding, exploratory research, scripts, and ordinary software projects.


On Literate Programming

The useful lesson from literate programming is not that every project should use tangled documents. The useful lesson is that explanation is part of the work, not a decorative afterthought.

A fully literate workflow may make sense for some projects, but it is not required. A lighter-weight version is often enough:

  1. explain intent where syntax is not enough
  2. keep documentation near the work
  3. preserve reading order for newcomers
  4. keep comments and implementation in sync

In practice, well-commented code, well-structured configs, clear READMEs, and a small project guidance note are usually enough to capture most of the benefit.


Core Principle

Code should be readable on its own, but comments and documentation should preserve intent.

The goal is not full literate programming or tangled code by default. The goal is simpler: keep enough explanation near the work that a future human or LLM can understand why a decision was made, what constraints exist, and what must not be changed casually.

When deciding whether to add prose, prefer explanation that preserves reasoning, constraints, risks, assumptions, and operational context.


Commenting Style

What helps

  • Why comments — explain the reasoning, trade-offs, or constraints behind a decision. Example: # 30s timeout because upstream API is flaky under load

  • Policy comments — state rules or boundaries that should survive edits. Example: # SECURITY: do not expose this token to external tools

  • Breakage comments — describe what fails if this line or block is removed, reordered, or changed. Example: # removing this breaks fish completions for mise

  • Assumption comments — declare what this code expects about its environment, inputs, versions, or load order. Example: # expects PostgreSQL 15+ and DATABASE_URL in env

  • Decision comments — record why one approach was chosen over another, especially when the simpler-looking alternative is wrong. Example: # using profile instead of rc because login shells need the PATH fix early

What does not help

  • What comments — comments that only restate visible syntax usually add noise. Example: timeout = 30 # set timeout to 30

  • Decorative comments — banners and notes that look helpful but carry no operational meaning.

  • Stale comments — a wrong comment is worse than no comment. If code changes, the related explanation should be checked as part of the same edit.

Rule of thumb

Comment the parts that a reader cannot safely infer from the code itself.


Code and Config Structure

Prefer clear structure over cleverness

Use names, layout, and decomposition to make the code understandable before relying on comments. Comments should support the structure, not compensate for needless complexity.

Make dependencies explicit

Implicit dependencies are a common source of confusion for both humans and LLMs. Be explicit about:

  • environment assumptions
  • import or load order
  • side effects during initialization
  • required tools, versions, and services
  • generated files and their source of truth

Use clear internal ordering

Within a file, a predictable structure helps both humans and models:

  1. Purpose or file header
  2. Assumptions and dependencies
  3. Configuration or constants
  4. Core logic grouped by concern
  5. Helpers or utilities
  6. Entry point, exports, or commands

This is not a rigid template. It is a bias toward obvious reading order.


Documentation Artefacts

README as briefing

A README should help a cold reader understand:

  1. what this project or directory is for
  2. why it works the way it does
  3. how to use, build, test, or validate it
  4. what is likely to go wrong
  5. where the important files and boundaries are

Project guidance files

A project may also benefit from a guidance file such as AGENTS.md, CLAUDE.md, CONTRIBUTING.md, or another plain-language note.

Such a file should explain:

  • the purpose of the project or directory
  • important architectural decisions and why
  • what may be changed freely vs. cautiously
  • how to build, test, lint, or validate changes
  • which files are generated
  • which file is the source of truth when duplication exists

The filename matters less than the clarity of the guidance.

Inline prose for configs

Configuration often benefits from heavier commenting than application code. For config files, it is useful to:

  • group related settings under short prose headings
  • explain non-obvious interactions between settings
  • note version-specific or platform-specific behaviour
  • mark sections that are load-bearing vs. cosmetic

Working Well With LLMs

What LLMs are generally good at

  • translating between code and explanation
  • preserving formatting and structure
  • updating nearby prose when prompted to do so
  • spotting places where implementation and comments appear to diverge
  • summarizing local intent from explicit notes and comments

What LLMs generally struggle with

  • inferring intent from code alone
  • understanding hidden dependencies and load order
  • knowing whether a comment is a hard rule or a soft preference
  • recognizing generated files unless clearly marked
  • preserving system-specific assumptions that were never written down

How to make collaboration easier

  • state intent before or near implementation when the reason is non-obvious
  • mark hard boundaries with consistent labels such as SECURITY, POLICY, INVARIANT, DO NOT MODIFY, or GENERATED
  • say explicitly when something is load-bearing
  • keep comments close to the code or config they explain
  • update explanation and implementation together
  • avoid making the model guess when a short note would remove ambiguity

How Humans Can Help LLMs Do Better Work

When working with any coding model, the most useful input is not just the task, but the intent and constraints around the task.

Give the goal and the constraint

Describe both what you want and what must be preserved.

Good example: make PATH initialization deterministic on macOS, preserve fish behaviour, avoid hidden shell magic

This is better than only asking for a fix, because it tells the reader what to optimize for and what not to break.

State what must be preserved

Useful constraints often include:

  • existing workflow
  • portability
  • readability
  • startup order or load order
  • security boundaries
  • file layout and naming
  • compatibility with a particular shell, OS, or toolchain
  • comment style and documentation depth

Say how much change is acceptable

It helps to state whether you want:

  • minimal patching
  • moderate cleanup
  • broader refactoring
  • full redesign

This changes how aggressive an LLM should be.

Prefer reasoning over cleverness

Say when you want the solution optimized for future maintenance rather than compactness or novelty. In many real code and configuration tasks, a slightly longer but more explicit solution is the better one.

Show the real file when possible

Local context matters. Configuration, shell setup, and infrastructure code are often shaped by nearby assumptions that are not obvious from isolated snippets.

Ask for the kind of explanation you want

Be explicit about whether you want:

  • inline comments in the file
  • explanation outside the file
  • both

This avoids over-commenting or under-explaining.

Signal uncertainty or discomfort

Feedback such as this feels too magical, too dense, too brittle, or too implicit is useful even when it is imprecise. It points to the kind of risk or maintenance problem that should be addressed.

Best shared division of labour

A good default is:

Code carries the mechanism. Comments carry the intent.

That gives both humans and LLMs a stable way to collaborate without forcing a fully literate workflow.


Practical Preferences

For ordinary code

Prefer self-explanatory code first. Use comments to capture:

  • why this exists
  • what constraint it is satisfying
  • what would break if changed
  • what assumption is being made
  • what alternative was rejected and why

For config, scripts, and infrastructure

Comment more heavily. These files often contain fragile interactions, platform-specific behaviour, side effects, or historical workarounds that are not obvious from syntax.

For generated or derived files

Mark them clearly. Say where changes should be made and what file or process is authoritative.

For future maintenance

Treat stale comments as defects. A code change is incomplete if it leaves the reasoning around the code misleading.


Simple Rule Set for Any LLM

Use this as a compact custom instruction set when working on code or config:

  1. Prefer clear code first, then add comments for intent.
  2. Preserve and improve comments that explain why, constraints, assumptions, risks, or what breaks if changed.
  3. Remove or avoid comments that only restate obvious syntax.
  4. Treat stale or misleading comments as defects.
  5. Keep comments close to the code they explain.
  6. Mark hard boundaries clearly: SECURITY, POLICY, INVARIANT, GENERATED, DO NOT MODIFY.
  7. For config and infrastructure files, comment more heavily than for ordinary application code.
  8. When editing, update nearby documentation and comments along with the code.
  9. Do not make hidden assumptions when a short explanatory note would prevent confusion.
  10. Optimize for future readability by both humans and LLMs, not cleverness.

Simple Rule Set for Humans Working With LLMs

Use this as a compact briefing when asking an LLM to help with code or config:

  1. State the goal and the main constraint.
  2. Say what must be preserved.
  3. Indicate how much change is acceptable.
  4. Prefer maintainability and explicit reasoning over cleverness.
  5. Share the real file or enough surrounding context when possible.
  6. Say whether you want inline comments, external explanation, or both.
  7. Call out anything that feels too magical, brittle, dense, or implicit.
  8. Keep code as the mechanism and comments as the record of intent.

v1.2.0 — March 2026