000 — Specs
This document is the entry point for the MDD specifications.
Use the /spec-extension skill to add new specs.
Spec index
Section titled “Spec index”Run uv run python scripts/spec-list.py to recreate this overview:
| # | Title | Purpose | Status |
|---|---|---|---|
| S01 | Spec-Based Development | Document new features in structured specs before implementation to ensure consistency and enable design review | Implemented (2026-05-07) |
| S02 | mdd CLI Tool | A unified mdd CLI dispatcher that routes subcommands to command modules. | Superseded by S35 (2026-05-16) |
| S03 | convert command | mdd convert recursively converts .docx files to Markdown (.docx.md) using Docling for body content and python-docx for metadata extraction. | Implemented (2026-05-07) |
| S04 | new / new-pptx / new-docx commands | Scaffold new Quarto projects from bundled templates. | Implemented (2026-05-07) |
| S05 | pdf / pdf-pptx / pdf-docx commands | Export Office files to PDF via AppleScript (macOS only). | Implemented (2026-05-07) |
| S06 | Documentation Site | Publish a Starlight documentation site at https://schubergphilis.github.io/mdd/ on every merge to main, built from checked-in Markdown under docs/, whose primary content is operator documentation and whose secondary content is the existing spec and research corpus, demoted. | Draft |
| S07 | data protection | Two cross-cutting rules that protect the organisation’s data and credentials for every command. | Implemented (2026-05-19) |
| S09 | confluence command | mdd confluence adds Confluence Cloud integration for exporting, creating, and updating pages. | Implemented (2026-05-08) |
| S10 | sharepoint command | mdd sharepoint mirrors SharePoint sites to Markdown by reading locally synced files (via OneDrive), without ever calling the SharePoint API. | Implemented (2026-05-08) |
| S11 | convert pptx | Extend mdd convert to handle .pptx input, producing <name>.pptx.md output for round-trip with Quarto presentation projects. | Implemented (2026-05-08) |
| S14 | confluence sync command | mdd confluence sync is the primary bidirectional verb for keeping a git mirror repo in lockstep with its Confluence space. | Implemented (2026-05-08) |
| S15 | Converter registry | Promote the implicit extension-dispatch logic in mdd convert into an explicit, importable registry under src/mdd/converters/. | Implemented (2026-05-08) |
| S16 | Confluence attachment conversion (pull-side) | Extend mdd confluence sync and export so non-image attachments are run through the converter registry, producing markdown siblings. | Implemented (2026-05-08) |
| S17 | Confluence office publishing (push-side) | Render opted-in markdown pages to .docx/.pptx via Quarto and upload them as versioned Confluence attachments. | Implemented (2026-05-09) |
| S18 | sharepoint sync command | Bidirectional sync between .md/.qmd and .docx/.pptx in SharePoint sites mirrored via OneDrive, without office-format diff/merge. | Implemented (2026-05-09) |
| S19 | search command | mdd search "<query>" is a thin ripgrep wrapper that searches markdown across all configured mirror locations. | Implemented (2026-05-08) |
| S20 | LiteLLM AI client and caching infrastructure | Establish a shared mdd.ai package wrapping a LiteLLM gateway with uniform retry, concurrency, and caching. | Implemented (2026-05-08) |
| S21 | ai rewrite and ai index commands | Two user-facing AI commands built on the S20 client: mdd ai rewrite and mdd ai index. | Implemented (2026-05-08) |
| S22 | ai review command | mdd ai review runs cross-page checks on a mirror’s markdown content and produces a structured report listing candidates for human action. | Implemented (2026-05-09) |
| S23 | Agent skills bundle and skills command | Bundle Claude Code skills with mdd so agents can discover when and how to drive mdd reliably. | Implemented (2026-07-30) |
| S24 | SVG sibling rasterization | Keep a high-quality <name>.svg.png sibling next to every .svg file in a mirror, refreshed automatically when the source changes. | Implemented (2026-05-08) |
| S26 | Externally-managed Confluence pages | Detect Confluence pages maintained by external automation and block mdd pushes; pull/export remains allowed. | Implemented (2026-05-09) |
| S27 | confluence page rename / move / archive | Imperative mdd subcommands (rename, move, archive, unarchive) that mutate a Confluence page then refresh the local mirror. | Implemented (2026-05-23) |
| S28 | Document Intermediate Representation (foundation) | Typed, in-process Python IR for documents supporting bidirectional Confluence ↔ markdown sync with identity, provenance, and JSON serialization. | Implemented (2026-05-13) |
| S29 | Confluence storage XHTML ↔ IR conversion | Map Confluence storage XHTML to and from the document IR defined in S28. | Implemented (2026-05-13) |
| S30 | Markdown ↔ IR conversion | Map markdown to and from the document IR, with 100% flavour coverage and a documented fallback policy. | Implemented (2026-05-13) |
| S31 | IR normalization and whitespace preservation | Define normalising and preserving modes for IR converters, where both modes share the same IR but differ in reader metadata and writer behaviour. | Implemented (2026-05-13) |
| S32 | IR test corpus expansion | Expand mdd/test-confluence/MDD to a complete coverage matrix of every non-deprecated Confluence storage shape and markdown construct. | Implemented (2026-05-13) |
| S33 | IR roundtrip testing and benchmarks | Define the test surface and performance gates the IR and its converters must pass before promotion to default for mdd confluence. | Implemented (2026-05-13) |
| S34 | 034 — Code Quality Gates | Define the static-analysis rule set, complexity thresholds, and grandfathering policy that mise run lint enforces, so future iterations (human and agent) cannot let function size, branchiness, or argument bloat regress unnoticed. | Implemented (2026-05-15) |
| S35 | Argparse-based CLI parsing | Replace the home-grown flag-parsing helpers and while i < len(args): loops in src/mdd/commands/ with argparse, deleting the bespoke _FlagSpec framework. Amended 2026-05-24 with the typed-Namespace adapter convention (per-handler Namespace subclass + cast). | Implemented (2026-05-16) |
| S36 | Module structure and file-size shape | Split the eleven src/mdd/ files >500 lines into cohesive sub-packages so file length stays manageable after the S34 per-function refactors land. | Implemented (2026-05-16) |
| S37 | Complexipy cognitive complexity | Add cognitive-complexity as a second structural gate alongside ruff’s McCabe, using complexipy with a snapshot watermark for grandfathering. | Implemented (2026-05-18) |
| S38 | SharePoint test corpus | Vendor a local mirror of the MDD SharePoint site as a test corpus alongside the existing Confluence corpus, and reshape tests/corpus/ to host both. | Implemented (2026-05-20) |
| S39 | .mddignore source-side filtering | A .gitignore-style file (and matching --ignore=<path> flag) that filters source content before download/conversion in mdd sync commands, with a single shared matcher consumed by sharepoint/confluence/lucid. | Implemented (2026-05-24) |
| S40 | Typed frontmatter layer | Replace the ~5 per-module hand-rolled YAML/JSON coercer kits with a single typed pydantic v2 layer (extra="forbid", flexible type coercion), deleting a class of silent-failure bugs in hand-edited frontmatter. | Implemented (2026-05-24) |
| S42 | Image extraction and optimization | Records the shared convert/images.py image-writer policy (content-addressing, TIFF→JPEG, WMF/EMF→PNG, 4k cap) and adds lossless PNG re-optimization on write, keeping the smaller of original/re-encoded bytes. Office-conversion path only; excludes Confluence’s byte-exact attachment mirror. | Implemented (2026-05-29) |
Naming scheme
Section titled “Naming scheme”Spec files use the SNN-<slug>.md form (e.g. S07-data-protection.md).
Numbers are assigned in order, starting at 1, zero-padded to two digits.
Research notes live under docs/research/ with an RNN- prefix; see
000-research.md.
Existence check before adding a new spec
Section titled “Existence check before adding a new spec”Before writing a new spec, confirm the system or feature does not already exist:
ls docs/spec/find src/mdd -maxdepth 2 -type dIf a system or feature already exists, amend its existing spec rather than starting a new one.
How to add a new spec
Section titled “How to add a new spec”Use the /spec-extension skill. It helps with these steps and more:
-
Run the existence check (see above) — search
docs/spec/andsrc/mdd/before opening a new file. -
Scaffold with
mise run new-spec <slug>. This picks the next free number and writes a scaffolded file:Terminal window mise run new-spec my-feature# prints: docs/spec/S34-my-feature.md -
Append a row to the spec index in this file (above).
-
Commit with a
docs(spec):prefix. Docs-only commits skipmise run ci.
Cross-reference convention
Section titled “Cross-reference convention”Use relative links, not bare spec numbers.
Do:
See [data protection](S07-data-protection.md) for the blacklist gate.See [confluence sync](S14-confluence-sync.md) for the reconciliation algorithm.Don’t:
See S07 for the blacklist gate.See S14 for the reconciliation algorithm.When prose requires a bare number (e.g. in a table row), keep the link: [S07](S07-data-protection.md).
A repo that keeps its own specs but cites one of the core’s uses the
absolute GitHub form instead, which scripts/spec-check.py validates the
same way — against docs/spec/ and a sibling ../mdd/docs/spec/ checkout:
See [data protection](https://github.com/schubergphilis/mdd/blob/main/docs/spec/S07-data-protection.md).Spec files MUST NOT link to docs/research/ (RNN) artefacts, and MUST
NOT depend on one to be understood. Research notes are working /
process documents; specs are the durable design record. Copy any
relevant content into the spec instead of linking out.
A spec MAY credit the note a design came from by number, in prose and
without a link — Originates from research note R03. — as long as the
spec still reads completely on its own.
Status convention
Section titled “Status convention”The **Status:** line near the top of each spec uses one of these forms:
Draft— design still in flux.In progress — <short description>— partial implementation; describe what has shipped and what is deferred.Accepted — <short description>— design accepted but no code (e.g.Implemented (YYYY-MM-DD)— feature has shipped. The date is the commit date of the newest commit that landed the spec’s implementation. Do not list commit shas, PR numbers, or rollout-plan references in the Status line — those belong in commit history. The matching row in the index above MUST mirror the same Status string.Superseded by [SNN](SNN-slug.md) (YYYY-MM-DD)— design has been replaced by a later spec. Keep the original file as historic record, add a short “Superseded” callout near the top pointing at the replacement, and mirror the same Status string in the index above.
scripts/spec-check.py enforces the Implemented (YYYY-MM-DD) shape. Any
deviation (commit shas, extra prose inside the parens) fails the check.
Spec Template
Section titled “Spec Template”Use spec-template.md.
Site built 2026-07-30.