Skip to content
This document describes intent at the time it was written. It is part of the design record, not user documentation, and may not reflect the current behaviour of the code.

000 — Specs

This document is the entry point for the MDD specifications.

Use the /spec-extension skill to add new specs.

Run uv run python scripts/spec-list.py to recreate this overview:

#TitlePurposeStatus
S01Spec-Based DevelopmentDocument new features in structured specs before implementation to ensure consistency and enable design reviewImplemented (2026-05-07)
S02mdd CLI ToolA unified mdd CLI dispatcher that routes subcommands to command modules.Superseded by S35 (2026-05-16)
S03convert commandmdd convert recursively converts .docx files to Markdown (.docx.md) using Docling for body content and python-docx for metadata extraction.Implemented (2026-05-07)
S04new / new-pptx / new-docx commandsScaffold new Quarto projects from bundled templates.Implemented (2026-05-07)
S05pdf / pdf-pptx / pdf-docx commandsExport Office files to PDF via AppleScript (macOS only).Implemented (2026-05-07)
S06Documentation SitePublish 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
S07data protectionTwo cross-cutting rules that protect the organisation’s data and credentials for every command.Implemented (2026-05-19)
S09confluence commandmdd confluence adds Confluence Cloud integration for exporting, creating, and updating pages.Implemented (2026-05-08)
S10sharepoint commandmdd sharepoint mirrors SharePoint sites to Markdown by reading locally synced files (via OneDrive), without ever calling the SharePoint API.Implemented (2026-05-08)
S11convert pptxExtend mdd convert to handle .pptx input, producing <name>.pptx.md output for round-trip with Quarto presentation projects.Implemented (2026-05-08)
S14confluence sync commandmdd confluence sync is the primary bidirectional verb for keeping a git mirror repo in lockstep with its Confluence space.Implemented (2026-05-08)
S15Converter registryPromote the implicit extension-dispatch logic in mdd convert into an explicit, importable registry under src/mdd/converters/.Implemented (2026-05-08)
S16Confluence 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)
S17Confluence 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)
S18sharepoint sync commandBidirectional sync between .md/.qmd and .docx/.pptx in SharePoint sites mirrored via OneDrive, without office-format diff/merge.Implemented (2026-05-09)
S19search commandmdd search "<query>" is a thin ripgrep wrapper that searches markdown across all configured mirror locations.Implemented (2026-05-08)
S20LiteLLM AI client and caching infrastructureEstablish a shared mdd.ai package wrapping a LiteLLM gateway with uniform retry, concurrency, and caching.Implemented (2026-05-08)
S21ai rewrite and ai index commandsTwo user-facing AI commands built on the S20 client: mdd ai rewrite and mdd ai index.Implemented (2026-05-08)
S22ai review commandmdd 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)
S23Agent skills bundle and skills commandBundle Claude Code skills with mdd so agents can discover when and how to drive mdd reliably.Implemented (2026-07-30)
S24SVG sibling rasterizationKeep 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)
S26Externally-managed Confluence pagesDetect Confluence pages maintained by external automation and block mdd pushes; pull/export remains allowed.Implemented (2026-05-09)
S27confluence page rename / move / archiveImperative mdd subcommands (rename, move, archive, unarchive) that mutate a Confluence page then refresh the local mirror.Implemented (2026-05-23)
S28Document 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)
S29Confluence storage XHTML ↔ IR conversionMap Confluence storage XHTML to and from the document IR defined in S28.Implemented (2026-05-13)
S30Markdown ↔ IR conversionMap markdown to and from the document IR, with 100% flavour coverage and a documented fallback policy.Implemented (2026-05-13)
S31IR normalization and whitespace preservationDefine 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)
S32IR test corpus expansionExpand mdd/test-confluence/MDD to a complete coverage matrix of every non-deprecated Confluence storage shape and markdown construct.Implemented (2026-05-13)
S33IR roundtrip testing and benchmarksDefine the test surface and performance gates the IR and its converters must pass before promotion to default for mdd confluence.Implemented (2026-05-13)
S34034 — Code Quality GatesDefine 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)
S35Argparse-based CLI parsingReplace 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)
S36Module structure and file-size shapeSplit 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)
S37Complexipy cognitive complexityAdd cognitive-complexity as a second structural gate alongside ruff’s McCabe, using complexipy with a snapshot watermark for grandfathering.Implemented (2026-05-18)
S38SharePoint test corpusVendor 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 filteringA .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)
S40Typed frontmatter layerReplace 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)
S42Image extraction and optimizationRecords 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)

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.

Before writing a new spec, confirm the system or feature does not already exist:

Terminal window
ls docs/spec/
find src/mdd -maxdepth 2 -type d

If a system or feature already exists, amend its existing spec rather than starting a new one.

Use the /spec-extension skill. It helps with these steps and more:

  1. Run the existence check (see above) — search docs/spec/ and src/mdd/ before opening a new file.

  2. 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
  3. Append a row to the spec index in this file (above).

  4. Commit with a docs(spec): prefix. Docs-only commits skip mise run ci.

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.

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.

Use spec-template.md.

Site built 2026-07-30.