Development policy¶
This page defines MQT Core’s repository-owned development policy. It supplements the contribution guide, which describes the contribution process, and the AI usage policy, which defines accountability for AI-assisted work.
C++ choices¶
Use C++20 standard-library facilities before adding a project abstraction or dependency.
Keep variables local, initialize them when declared, and give each name one clear meaning.
Use
autowhen the initializer makes the type clear or when spelling the type would hide the important part of an expression. Spell the type when it communicates a contract or prevents a surprising conversion.Preserve deterministic user-visible output. Do not rely on pointer values or unspecified container iteration order.
Keep cleanup separate from behavioral changes unless the cleanup is required to make the behavior correct.
Do not add flexibility, configuration, or abstraction without a current use.
The MLIR development policy explains the deliberate differences that apply to code built on LLVM and MLIR.
C++ documentation comments¶
Use /// for Doxygen documentation comments. The first sentence is the summary;
separate additional paragraphs with a blank /// line instead of using \brief
or \details. Document parameters and return values only when the explanation
adds information that the name and signature do not already provide. Preserve
existing documentation when changing comment style.
Keep //!< or ///< for trailing member documentation. Keep /** ... */
documentation inside backslash-continued macros: line comments there can consume
the following declarations after line splicing. Preserve explicit @brief
commands there when Doxygen needs them to retain summaries after macro
expansion.
Keep top-level @file documentation and put its summary on the next line,
without @brief:
/// @file Circuit.h
/// Defines the circuit representation.
/// Returns the number of qubits in the circuit.
[[nodiscard]] size_t getNqubits() const;
/// Applies an operation to the selected qubits.
///
/// Rejects duplicate indices in \p qubits.
///
/// \param qubits Qubit indices in application order.
/// \returns The created operation.
Operation apply(llvm::ArrayRef<Qubit> qubits);
Keep public API documentation in the declaration and do not duplicate it in the implementation. Use ordinary implementation comments for details that do not belong to the API contract.
Use // for ordinary implementation and namespace closing comments. Inline
/* ... */ comments remain valid, including unused parameter names such as
OpAdaptor /*adaptor*/ and argument labels such as /*isSigned=*/false.
Reproduce C++ lint locally¶
Before pushing a C++ change, run:
uvx nox -s cpp-lint
The session configures the lint preset and builds mqt-core-lint-headers to
prepare generated headers without compiling or linking the project. It then runs
the same cpp-linter release and options as CI against every line of each
changed C++ file. It compares against origin/main by default. Pass a different
Git diff base after -- when needed:
uvx nox -s cpp-lint -- upstream/main
Use --all to check every eligible project C++ file instead:
uvx nox -s cpp-lint -- --all
Changed-line clang-tidy commands remain useful for quick iteration, but they
do not reproduce CI’s whole-changed-file scope. Update this session when the
reusable C++ lint workflow changes its action version or inputs.
Commit messages¶
MQT Core adapts Chris Beams’s commit-message guidance to its gitmoji convention:
Start with the established gitmoji prefix and an imperative subject.
Target 50 characters and never exceed 72 characters, including the prefix.
Do not end the subject with a period.
Add a blank line before the body.
Use the body to explain why the change is needed, its constraints, and any non-obvious tradeoffs. Do not restate the diff.
Wrap prose at 72 characters where practical.
Preserve legitimate human
Co-authored-bytrailers. Record AI assistance withAssisted-by, never by representing an AI system as an author.
Terminology¶
Use one established term for one concept. The MQT Core glossary records preferred names, accepted aliases, and distinctions that matter to public APIs or compiler design. Update the glossary in the same pull request when introducing or changing a public or potentially ambiguous term. Do not add entries for ordinary language or private implementation details.
Maintenance¶
Review subsystem policy, agent instructions, formatting, lint rules, and exceptions when a major dependency changes. Update the recorded upstream version and remove obsolete exceptions. Existing code does not override a new decision merely because migration is incomplete.
Agent guidance¶
Treat AGENTS.md as a concise routing and guardrail layer, not a second copy of
the development policy. Keep rationale, examples, and detailed procedures in the
canonical documentation and link to the applicable sections. Repeat only short,
non-obvious rules that agents must keep in immediate context to avoid a
recurring mistake. Enforce mechanical rules in repository tooling instead of
relying on prose.
Documentation validation¶
Install Python 3.14, LLVM/MLIR 23.1, Doxygen, and Graphviz before building the
complete documentation. The Doxygen configuration is validated with Ubuntu
24.04’s version 1.9.8 and version 1.17. Use uvx nox --non-interactive -s docs
to build generated references and execute the MyST notebooks. This command fails
on Sphinx and Doxygen diagnostics and checks local links in the generated HTML,
including the native C++ reference. Use
uvx nox --non-interactive -s docs -- -b linkcheck to check external links
separately.
Notebook execution is forced on each build. The docs session isolates the QDMI registry from system, user, project, and inline environment definitions while retaining packaged devices. Executable examples use local DDSIM and require no credentials. Configuration recipes for external providers do not execute.
Use {code-cell} blocks in pages with MyST-NB front matter. Keep required setup
visible or collapsible with hide-input, display useful computed output, and
assert the demonstrated semantics. Use checked subprocess calls for CLI
examples. Ordinary code fences document configuration or interfaces without
executing them. Give figures descriptive alternative text and preserve full
contracts in linked references when they would interrupt a tutorial.