ai-manifest/1

A plain-Markdown format for recording how AI tools were, or weren't, used in a project. Like a shipping manifest, it lists what's inside without judging it. A project with no AI involvement and one built almost entirely by AI are described the same way.

Each fact is written once, as text that reads naturally on its own. A small set of conventions makes the same text machine-parseable.

The file is called AI-MANIFEST.md and lives in the repository root.

The canonical home of this spec is https://ai-manifest.ahnlak.com/spec/1.

Examples

A project with no AI involvement:

# AI manifest

- Format: ai-manifest/1
- Updated: 2026-10-02
- Default level: none

No AI tools were used in this project.

A project with mixed involvement:

# AI manifest

- Format: [ai-manifest/1](https://ai-manifest.ahnlak.com/spec/1)
- Updated: 2026-10-02
- Tools: Claude (hosted)
- Default level: none

Designed and written by me. Anything not listed below had no AI involvement.

## Styling

- Level: directed
- Review: full
- Paths: `assets/css/**`

Most of the CSS was generated to my direction, then checked in a browser.

## Code: Rust

- Level: suggested
- Review: full
- Familiarity: expert

All Rust code is mine. Claude suggested some alternative structures.

Structure

  1. Title. The file starts with exactly one # heading. Its text is free.
  2. Header. The first list under the title holds the header fields. Any prose after that list, up to the first ## heading, is the summary.
  3. Area sections. Each ## heading starts an area. Its first list holds that area's fields, and any prose after the list is the area's notes.
  4. End marker. An optional horizontal rule (---, *** or ___, on its own line, after a blank line) ends the parsed content. Anything after it, such as a legend, is ignored by tools.

Field lists are written as - Key: value. Keys are case-insensitive, and - **Key:** value is also accepted. The field list must come directly after its heading (blank lines are allowed). Any later lists are treated as prose.

### and deeper headings, code blocks and other Markdown are allowed inside prose and are not interpreted.

HTML comments (<!-- ... -->) are ignored outside code blocks, because Markdown hides them from readers. Tools must not read anything a reader can't see.

Whitespace follows ordinary Markdown. Blank lines may appear anywhere, including between field-list items. Headings and list items may be indented by up to three spaces. Spacing around the : is ignored, and so are trailing whitespace, CRLF line endings and a UTF-8 byte-order mark. The one blank line that matters is the one between a field list and the prose after it. Without it, Markdown displays the prose as part of the last field, so the validator warns about it.

Header fields

FieldRequiredValue
Formatyesai-manifest/1, optionally as a link (see below)
UpdatedrecommendedISO date, YYYY-MM-DD
Toolsif AI usedComma-separated Name (hosting), where hosting is hosted or local. Or none.
Default levelyesThe level for anything not covered by an area section
Default reviewsee belowThe review for anything not covered by an area section

The Format line is what identifies the file as an AI manifest. Tools must ignore a file without it, whatever the file is called. The identifier can be written as a Markdown link to this spec, so human readers can follow it:

- Format: [ai-manifest/1](https://ai-manifest.ahnlak.com/spec/1)

Tools match on the link text and report the link target as spec.

Area sections

The heading is ## Area or ## Area: label. Area names are case-insensitive. The standard areas are:

concept, spec, planning, design, code, debugging, tests, styling, docs, assets, ops

Custom areas are allowed. The validator warns about them, because other tools may not recognise them. The label is free text that distinguishes sections with the same area. For code, the label names the language, as in ## Code: Kotlin. The same area and label combination may appear only once.

FieldRequiredValue
LevelyesSee Levels below
Reviewsee belownone, light or full
Familiarityoptionalexpert, proficient or learning. Recommended for code.
PathsoptionalBacktick-quoted globs, comma-separated: `src/ui/**`, `*.css`

Levels

These describe who produced the work, from least to most AI involvement.

LevelMeaning
noneNo AI involvement.
consultedDiscussed with AI or had things explained. No AI output in the work.
suggestedAI proposed approaches or snippets. A human wrote the actual work.
co-writtenSubstantial AI-written parts, reworked and integrated by a human.
directedAI wrote most of it, following detailed human instructions.
delegatedAI wrote it from a brief. The human set goals, not details.

Review

Review describes how carefully a human checked AI output. It is required at suggested and above, and has no meaning at none or consulted.

ReviewMeaning
noneNot reviewed.
lightSkimmed or spot-checked.
fullEvery part read and understood, and tested where applicable.

Familiarity

Familiarity is the author's own skill in the language or domain. It shows how well the author could judge what the AI produced.

Extensions

Field names starting with X- (such as - X-Model: ...) are allowed anywhere and are passed through untouched. Any other unknown field is an error.

Validation and JSON

ai-manifest-check.py validates files against this spec. With --json, it prints each parsed file as a JSON list like this:

[{
  "file": "AI-MANIFEST.md",
  "format": "ai-manifest/1",
  "spec": "https://ai-manifest.ahnlak.com/spec/1",
  "title": "AI manifest",
  "updated": "2026-10-02",
  "summary": "Designed and written by me. ...",
  "tools": [{"name": "Claude", "hosting": "hosted"}],
  "default": {"level": "none", "level_rank": 0, "review": null},
  "areas": [{
    "area": "code", "label": "Rust", "line": 18,
    "level": "suggested", "level_rank": 2,
    "review": "full", "familiarity": "expert",
    "paths": [], "notes": "All Rust code is mine. ...",
    "extensions": {}
  }],
  "extensions": {}
}]

level_rank counts from 0 (none) to 5 (delegated), so tools can compare levels without hard-coding the list.