Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ai-setup

Make a repository explain itself to an agent. One command lays a Markdown structure into an existing repository, so that an agent opening it knows how the project works before it writes a line.

python3 ai_setup.py init /path/to/repo

Then open the repository with your agent and say:

read ai/BOOTSTRAP.md and do it

Python 3.8 or later. No dependencies. Nothing leaves your machine.


The problem

An agent can find and open any file in a large repository in under a second. Nothing it finds there tells it how to work with what it has just opened: which document explains that code, which rule it is about to break, or which test would catch it if it gets that wrong.

That knowledge exists. It lives in a wiki nobody updates, in a handful of review comments, and in the maintainer's head. A new developer absorbs it over weeks. An agent arrives with none of it, cannot ask for it, and starts again from nothing in every session.

Most repositories are well organised. The reasoning behind the organisation was never written into the tree, because the people carried it instead. Plenty of ecosystems ship a command that lays out a new project, and what those commands generate is aimed at the compiler, the package manager and the human reader. Not one of them puts anything in the tree for an agent.

This tool is one attempt at that missing part.

What it does, in one paragraph

It copies a set of rules, indexes and templates into your repository, asks one question about where your documentation lives, and leaves behind ai/BOOTSTRAP.md: an ordered list of what an agent should build next, from what it finds in your tree. The tool ships almost no code, because checks, hooks and generators depend on your language, your build system and your conventions. A generated check that fits the project beats a copied one that does not.

There is one exception, and it is deliberate: scripts/ai-commit.py. Git behaves the same in every repository, so the commit path is the one piece of machinery that transfers intact. See The commit path.

Use

python3 ai_setup.py init [PATH]     # copy the structure in
python3 ai_setup.py check [PATH]    # check the structure is consistent
python3 ai_setup.py list            # print what init writes
Flag Effect
--name NAME Project name in the templates (default: the directory name)
--docs LIST in-repo,wiki,site,external or none, instead of the question
--no-connect Do not wire documentation to the code
--force Overwrite files that exist, named individually before it asks
--dry-run Print the plan and the disclaimer, write nothing, ask nothing
--yes Accept the disclaimer and the detected defaults, ask nothing

It asks before it writes

init prints every file it will write, then a disclaimer, then waits for you to type yes. The disclaimer says what changes, what it does not touch (nothing outside the directory, no git command, no network), and that CLAUDE.md and AGENTS.md will govern every agent session opened in the repository from then on. A run that is not a terminal refuses rather than proceeding unattended.

An existing file is never overwritten without --force, so the tool is safe in a repository that already has a CLAUDE.md. When it keeps yours, it prints the one line to add to it.

Running it again

Safe, and useful. Three cases:

You run It does
The same command twice Nothing. Every file exists, so it reports nothing to do and writes zero bytes
A newer ai-setup that ships new rules Writes only the new files, then inserts each new rule into ai/rules/INDEX.md in alphabetical position, so a rule can never reach the tree without reaching the index
--docs <surfaces> after declining at install Writes the documentation rule and surface list, then inserts the missing row into ai/rules/INDEX.md, AGENTS.md, CLAUDE.md and ai/INDEX.md

Reconciliation is idempotent: a row already present is never added twice. If an anchor line has been edited away, the tool prints the row for you to place by hand rather than guessing.

--force is the exception. It overwrites, and it names every file first, marking the ones you have edited since install:

 OVERWRITES 34 existing file(s), losing their content:
     ai/INSTRUCTIONS.md  <-- EDITED SINCE INSTALL, your answers are lost

The one question

Where does this project's documentation live?
  * 1  in-repo docs/        Markdown inside this repository
    2  GitHub wiki          a separate <repo>.wiki.git checkout
    3  published site       GitHub Pages branch, or a sibling worktree
    4  external service     Notion, Confluence, a hosted docs service
    0  none

Connect the documentation to the code?
  Source files point at the document that explains them, documents point back,
  the index between them is generated, and a stale link fails verification.

Answering yes adds ai/rules/documentation.md and ai/DOC-SURFACES.md, with one section per surface saying what that surface owes. A wiki is treated as an output, not a source, because nothing there can be gated. A published site is checked out as a worktree beside the code so one session can read both, and every page carrying a factual claim is generated from the code rather than transcribed. A surface outside the repository also gets ai/DOC-SURFACE-AI.md, the entry file to copy to its root.

Answer 0 and none of it is written. There are no empty sections left behind.

What lands in the repository

CLAUDE.md            entry point, a copy of AGENTS.md
AGENTS.md            the always-on rules and the dispatch table
ai/
  INSTRUCTIONS.md    canonical source of the two entry points
  BOOTSTRAP.md       what the agent builds next, in order (delete when done)
  INDEX.md           task to document routing: "I want to X, read Y"
  rules/             17 rules, plus documentation.md when connected
  patterns/          the approved shape of each repeated concern
  workflows/         the procedure for each repeated multi-step job
  DOC-SURFACES.md    where documentation lives (when connected)
  DOC-SURFACE-AI.md  entry file for a surface outside this repository
plan/
  README.md          spec lifecycle
  TEMPLATE.md        the spec format
  journal/           one file per problem class, one row per occurrence
  learned/           why the design is this shape, and what recurs
scripts/
  ai-commit.py       the one piece of machinery that transfers

The commit path

scripts/ai-commit.py is a small, dependency-free version of the commit helper Ze uses. It exists because three failures are silent and expensive:

Failure What the helper does
A commit carries a file nobody intended, because several sessions share one working tree and one index Stages an explicit list, and aborts if anything else was already staged or if staging picks up more
Verification passed against a different tree Refuses unless a stamp matches a fingerprint of this exact tree, tracked and untracked
A check was bypassed to get green No bypass flag for a red run. --no-verify-stamp is for a commit no verification covers, and the reason belongs in the message
make verify && python3 scripts/ai-commit.py verified   # stamp this tree
python3 scripts/ai-commit.py status                    # FRESH or STALE
python3 scripts/ai-commit.py commit -m "message" a.py b.py

The stamp lives in .git/, so it is never committed and never shared. A commit clears it, because HEAD moved and the evidence no longer describes the tree. The helper never pushes: pushing stays a separate, deliberate act.

Delete it if your project already has an equivalent, and name the real one in ai/rules/change-control.md.

The rules

Each file opens with a trigger (**When:**) and a severity. The trigger is a routing key: an agent matches it against the task in hand, then opens one file.

Rule Says
discoverability.md The tree explains itself, and the links are checked
documentation.md Code points at its document, the document points back, the index is generated
architecture.md Search the repository before proposing; placement follows dependency direction
simplicity.md The simplest FULLY CORRECT answer. Simplicity cuts machinery, never correctness
evidence.md Read the producer before claiming what code does. A coherent story is a hypothesis
testing.md The change decides the test it owes. Break a new test on purpose before trusting it
proof.md Name every obligation. A tag in a file nothing runs is no evidence
completion.md Deferred is not done. Recording a problem is not addressing it
verification.md One entry point, cheap failures first, every message teaches
change-control.md A commit carries evidence that this exact tree was checked
planning.md Spec before code. Review is independent of the author
sessions.md Enumerate a handoff before planning. Write state down, do not hold it
context-economy.md Batch independent calls, read ranges not files, size the work to one agent
agent-interface.md Your program's errors are the agent's next prompt. Make them say what to do
writing.md Say it once, say it short. No hedging, no marketing adjectives, no stale comments
repo-maintenance.md A change updates its discovery path in the same change
rule-format.md A trigger routes. A directive states a level. An unenforced rule is deleted
rule-precedence.md One ladder for deciding whether to stop, ask or continue

Every rule carries <!-- ADAPT: ... --> markers where a project fact is missing: the layers of your architecture, the table of which change owes which test, the commands that verify.

Delete the rules that do not apply. An unenforced rule teaches the next agent that rules here are decorative, and that costs more than the rule was worth. proof.md says so about itself: a project making no external claim should remove it.

What the agent builds next

ai/BOOTSTRAP.md is the handover. Ten steps, in the order that makes each one pay for itself alone, so you can stop after any of them:

  1. Make the project folder runnable. Predictable places for configuration, fixtures and data. One table an agent reads to start the program.
  2. Write the architecture map. One row per directory, what belongs in it, which way its dependencies run.
  3. Create the task index. Read the twenty most recent changes and ask what each one needed to know before it started. Each answer is a row.
  4. Link source to design, and back. A marker in the file, a marker in the document, the reverse index generated, a stale link failing the build.
  5. Record the approved patterns. One file per repeated concern, written from the code that already exists.
  6. Turn repeated mistakes into checks. Explanation, example, mechanical check, behavioural test. The check fires as early as it can.
  7. Decide which change owes which test. Fill the lookup table, list the exceptions, so the choice is looked up and not improvised.
  8. Provide one verification command. Cheap failures first, continuing far enough to report every useful failure. The same command in CI.
  9. Make the proof traceable. Only if the project claims something publicly: stable names for obligations, tagged tests, published gaps.
  10. Sync the entry points, then delete the bootstrap file.

Then it reports which steps it completed, which ADAPT markers are still open, which rules it deleted as inapplicable, and what it could not decide without you.

The check that ships

python3 ai_setup.py check .

It is deliberately small, and it is the only check the tool contributes to your quality gates. It fails on:

  • a rule file missing from ai/rules/INDEX.md, or listed there and absent
  • a rule with no **When:** trigger or no **Severity:**
  • a rule declaring advisory while its body states MUST
  • a scaffold file that has gone missing, which is how a half install reads
  • AGENTS.md and CLAUDE.md having drifted apart
  • a dead relative link in ai/, plan/, AGENTS.md or CLAUDE.md
  • an unfilled {{...}} placeholder

It reports, without failing, every open <!-- ADAPT --> marker. That keeps it green from the first day and useful as a progress meter afterwards. Wire it into CI once the structure settles.

Tests

python3 -m unittest discover -s tests

30 tests, no dependencies. Each one names the failure it prevents rather than the function it exercises, and the two that guard the worst bugs (a template error leaving a half install, an upgrade leaving a rule unindexed) were checked by breaking the fix and confirming they go red.

Design decisions

Why rules and not code. A check that does not fit the project is worse than no check: it fires on correct code, somebody switches it off, and everything it protected goes with it. The rules are portable because they are about how to work. The enforcement is not, so the agent writes it.

Why Markdown. It is what the agent reads, what the editor opens, what the diff shows and what review already covers. Karpathy's LLM Wiki gist reached the same answer, and so did several other people independently, which is a reasonable sign that it is the right level.

Why boring file names. ai/INDEX.md, CODE-TO-DOCS.md, DOCS-TO-CODE.md. An agent can guess a boring name. It cannot guess a product name invented for a simple idea.

Why one question and not twelve. Everything else can be read from the tree by an agent that is already sitting in it. Where the documentation lives, and whether you want it wired to the code, is a decision about your project that no amount of reading answers.

Why it asks for consent. It writes into your repository, and then hands an agent a list of machinery to build that can refuse edits and fail your build. That deserves a yes.

Why ai-setup does not run on itself. The obvious credibility move is to install the scaffold here. It was considered and rejected: this repository would then hold two near-copies of every rule, templates/ai/rules/x.md as the product and ai/rules/x.md as its own instance, and the wrong one would get edited. They are meant to differ, since an instance has its ADAPT markers filled in, so no check can demand they match. The rules that govern this tool live in templates/, and what proves the tool behaves is tests/, not a second copy of its own documentation.

Where this comes from

This tool came out of the Ze blog, where the practice behind these rules is written up as it was built. The two that matter most here:

They describe the machinery built for Ze, a network operating system of 623 Go packages where most of the code is written by Claude and none of it is trusted until it earns its place. Ze runs 28 rules, around 6,000 cross-reference comments, 1,600 functional scenarios, a 25-stage verification command and an RFC requirement ledger.

That is more than most projects need, and it was built over a year of finding out which parts pay for themselves. What is here is the part that transfers, in the order the first article recommends building it.

Cloudflare arrived at a similar shape from the other end, across a large engineering organisation, in How Cloudflare enforces engineering standards using AI. Two efforts that different converging on the same answer is useful evidence.

Honest limits

The rules are a starting point, not a description of your project, and they are worth very little until the ADAPT markers are filled and the checks exist. Step 6 of the bootstrap is where the value actually appears, and it is the step that takes real work. Until then the repository holds rules nothing enforces, which the rules themselves call a failure state.

Everything here was derived from one project: a large Go network operating system with a single maintainer, in a domain where published standards supply the requirements. The reasoning transfers better than the specifics. Two rules in particular, sessions.md and context-economy.md, govern how an agent works rather than what your project is, and both say to delete them when your harness already carries an equivalent. context-economy.md also inherits its conclusions from measurements taken elsewhere, and says so: measure them in your own repository before quoting any of them.

Model releases arrive almost every month, and each one moves the boundary. A more capable model may make some of this unnecessary, or may use a richer structure correctly and justify more. If you are reading this a year from now, check which of these problems have already been solved before copying anything.

License

BSD 3-Clause. See LICENSE.

Ze itself is AGPL. This part is deliberately permissive, because a convention nobody may copy is not a convention.

About

Helping your AI to understand your repository

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages