On this page

Why a history bundle is a zip of markdown files

A .mdh file is a zip archive of markdown files, one per version, each named with a timestamp. The history bundle reference covers what is in one, what happens when you open it and how images travel. This page is the reasoning behind the format.

It is Wymark’s own model, written down

The reason the format can be this plain is that it invents nothing. It is a direct mirror of how Wymark already works on your machine.

Wymark does not record edits. There is no operation log, no change journal, no stored list of insertions and deletions. What it keeps is whole snapshots of the document — the version you saved, the baseline you are reviewing against — and every diff you see is computed on demand from two of those snapshots. The review in front of you is not a replay of what you did; it is the difference between two texts, worked out fresh each time.

That design decision is what makes a bundle possible without any Wymark-specific payload. Because diffs are derived rather than stored, there is nothing else to carry: hand any tool the same byte-identical snapshots in the same order, and it can reconstruct exactly the same history and exactly the same diffs. Nothing is lost in the export because nothing extra existed to begin with.

So a .mdh is not a serialisation of Wymark’s internal state, and there is no importer that “reads Wymark files”. It is the local model — an ordered set of document snapshots — expressed in the most ordinary form available: files in a zip, named so their order is obvious. A reader that understands zip archives and can sort file names has everything it needs, and would arrive at the same review Wymark shows.

Why a container at all

The obvious question is why not just send the markdown file.

You can, and often should — a .md file is still the thing Wymark edits, and nothing about the review workflow requires a bundle. But a plain markdown file carries only its current state. Everything that makes a review a review — what changed, what it changed from, which checkpoints the author considered worth keeping — is gone the moment the file leaves your machine.

The usual answers to that don’t fit the case:

  • A git repository solves it properly, and if both sides use git you should use git. But most people receiving a document for review do not have a repo, do not want one, and are not going to clone anything to read your draft.
  • Track-changes in .docx is the right answer for a wider audience, and Wymark exports it (as an early-access feature; see exporting). What it cannot do is carry a history: track changes describes one round of edits against one baseline, not the chain of versions behind it.
  • A patch or diff file carries the changes without the document, so the recipient needs both, in the right order, plus a tool to apply them.

A bundle is the smallest thing that carries a document and its history in one artifact you can attach to an email. It is deliberately not a repository — no branches, no merges, no remotes, no identity. It is a snapshot chain, which is what a review needs and no more.

Nothing here is Wymark-only

This is worth stating explicitly, because “we invented a file format” reads as a lock-in move and it isn’t meant as one.

The format is written down as a versioned specification, wymark.history/1, independently of our implementation. It has no dependency on Wymark’s editor, our review engine, or anything about how we store data locally. Two rules do all the work: file names follow <name>.<YYYYMMDDTHHMMSSZ>[.<label>].md, and a reader ignores any entry it does not recognise.

That second rule is the important one, and it is why we are comfortable publishing this as a stable contract rather than an internal detail. It means the format can grow without breaking readers that were written against today’s version — an older reader encountering a newer bundle skips what it doesn’t understand and still reads every version correctly.

If you want to read or write .mdh files from your own tool, you need nothing from us. If you want to use the format and find it lacking, that is a conversation we would genuinely rather have than watch three similar formats appear. We picked a container because we needed one, not because we wanted to own one — and a second version of the spec shaped by someone else’s requirements would be a better outcome than a first version that only fits us.

Which is also why the experimental label on the reference page is honest rather than defensive: we needed a way to export a document with its history, so we specified the simplest one we could and shipped it. Whether it deserves to exist as a format, rather than as an implementation detail of one editor, is a question the answer to which is not ours alone.


# Why a history bundle is a zip of markdown files

A `.mdh` file is a zip archive of markdown files, one per version, each named with a timestamp. The [history bundle reference](/docs/reference/history-bundles) covers what is in one, what happens when you open it and how images travel. This page is the reasoning behind the format.

## It is Wymark's own model, written down

The reason the format can be this plain is that it invents nothing. It is a direct mirror of how Wymark already works on your machine.

Wymark does not record edits. There is no operation log, no change journal, no stored list of insertions and deletions. What it keeps is **whole snapshots of the document** — the version you saved, the baseline you are reviewing against — and every diff you see is *computed on demand* from two of those snapshots. The review in front of you is not a replay of what you did; it is the difference between two texts, worked out fresh each time.

That design decision is what makes a bundle possible without any Wymark-specific payload. Because diffs are derived rather than stored, there is nothing else to carry: hand any tool the same byte-identical snapshots in the same order, and it can reconstruct exactly the same history and exactly the same diffs. Nothing is lost in the export because nothing extra existed to begin with.

So a `.mdh` is not a serialisation of Wymark's internal state, and there is no importer that "reads Wymark files". It is the local model — an ordered set of document snapshots — expressed in the most ordinary form available: files in a zip, named so their order is obvious. A reader that understands zip archives and can sort file names has everything it needs, and would arrive at the same review Wymark shows.

## Why a container at all

The obvious question is why not just send the markdown file.

You can, and often should — a `.md` file is still the thing Wymark edits, and nothing about the review workflow requires a bundle. But a plain markdown file carries only its *current* state. Everything that makes a review a review — what changed, what it changed *from*, which checkpoints the author considered worth keeping — is gone the moment the file leaves your machine.

The usual answers to that don't fit the case:

- **A git repository** solves it properly, and if both sides use git you should use git. But most people receiving a document for review do not have a repo, do not want one, and are not going to `clone` anything to read your draft.
- **Track-changes in `.docx`** is the right answer for a wider audience, and Wymark exports it (as an early-access feature; see [exporting](/docs/guide/exporting)). What it cannot do is carry a *history*: track changes describes one round of edits against one baseline, not the chain of versions behind it.
- **A patch or diff file** carries the changes without the document, so the recipient needs both, in the right order, plus a tool to apply them.

A bundle is the smallest thing that carries a document and its history in one artifact you can attach to an email. It is deliberately not a repository — no branches, no merges, no remotes, no identity. It is a snapshot chain, which is what a review needs and no more.

## Nothing here is Wymark-only

This is worth stating explicitly, because "we invented a file format" reads as a lock-in move and it isn't meant as one.

The format is written down as a versioned specification, `wymark.history/1`, independently of our implementation. It has no dependency on Wymark's editor, our review engine, or anything about how we store data locally. Two rules do all the work: file names follow `<name>.<YYYYMMDDTHHMMSSZ>[.<label>].md`, and **a reader ignores any entry it does not recognise**.

That second rule is the important one, and it is why we are comfortable publishing this as a stable contract rather than an internal detail. It means the format can grow without breaking readers that were written against today's version — an older reader encountering a newer bundle skips what it doesn't understand and still reads every version correctly.

If you want to read or write `.mdh` files from your own tool, you need nothing from us. If you want to *use* the format and find it lacking, that is a conversation we would genuinely rather have than watch three similar formats appear. We picked a container because we needed one, not because we wanted to own one — and a second version of the spec shaped by someone else's requirements would be a better outcome than a first version that only fits us.

Which is also why the experimental label on the [reference page](/docs/reference/history-bundles) is honest rather than defensive: we needed a way to export a document with its history, so we specified the simplest one we could and shipped it. Whether it deserves to exist as a format, rather than as an implementation detail of one editor, is a question the answer to which is not ours alone.