MANIFEST · PROJECT 1 OF 6

Migrate DITA to docs as code, and prove nothing was lost.

Moving a DITA library to Markdown usually loses content quietly: a conref becomes a copy, a condition disappears, an anchor stops existing. Teams find out from customers. MANIFEST converts with DITA-OT, restores the reuse in MyST, and then checks every topic against DITA-OT's own output, in every audience's build, before a writer approves the merge.

MANIFEST's own help is written in DITA and migrated to MyST by MANIFEST. Read its report.

0unreported losses
100%reuse kept as includes and substitutions
98%IDs kept as anchors
2broken links, old URLs included
22/24topics passed without a writer
$0a month on Google Cloud's free tier

This build's gate is fail: topics/tpu-v5e-slice-planning.dita needs a mapping rule. That is the agent's job: it proposes the rule, the checks test it, and a writer approves it in the console.

How each number was measured

Migrate your DITA  Upload a .zip of DITA; get MyST files and the proof back in about three minutes.

Open it

ConsoleRuns, proof, the review queue and rules. Help on every screen. Help centerGet started, concepts, tasks, reference and troubleshooting, built from DITA. Migrated docsThe TPU sample set as MyST, built with Sphinx. Migration reportEvery topic, every check, every build. Design documentProblem, users, architecture, decisions and success metrics. SourceEngine, agent, API, console, help, tests and ADRs.

How it works

  1. Inventory counts every element, conref, key, condition, ID and link: the before picture.
  2. Convert swaps reuse for numbered placeholders and runs DITA-OT's Markdown writer.
  3. Restore turns placeholders into MyST includes, substitutions, only blocks and anchors.
  4. Check compares DITA-OT HTML5 with Sphinx for each topic, in each build: text, structure and IDs.
  5. Links checks links, navigation and every old URL offline.

When a topic fails, a Gemini agent proposes a mapping rule. The checks decide whether it works; the agent gets two attempts; a writer approves every rule before it runs again. Approved rules run without the model, so each new kind of element costs one model call, not one per topic.

Economics

Everything scales to zero: a Cloud Run job for migrations, a Cloud Run API, Firestore and Cloud Storage, deployed from GitHub without keys. A migration of the sample map takes about two minutes of compute; the whole product fits in a fifth of Google Cloud's free tier.

— checked, not assumed