This file is the canonical repository-wide instruction contract for AI coding agents. Every agent must read it before planning, editing, reviewing, testing, or releasing work in this repository.
The repository is not primarily an application or a generic project scaffold. It is an executable reference that teaches AI agents how to reason about, design, change, verify, and report work in a modern C++ repository. The source code proves that the rules compile; the documentation explains the decisions; the evals test whether an agent applies them correctly.
Primary references:
- ISO C++ Core Guidelines: https://isocpp.org/guidelines
- C++ Core Guidelines source: https://github.com/isocpp/CppCoreGuidelines
- C++ language status: https://isocpp.org/std/status
- CMake documentation: https://cmake.org/cmake/help/latest/
The words MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY are normative.
- MUST / MUST NOT: required for acceptance unless a higher-priority human instruction explicitly overrides the rule.
- SHOULD / SHOULD NOT: the default; deviations require a concrete reason.
- MAY: optional and context-dependent.
AGENTS.md is the canonical policy. Files under docs/agent/ provide required
task-specific detail. If a detailed guide conflicts with this file, this file
wins and the conflict must be reported and corrected.
Rule identifiers are stable review handles. Agents should cite them when explaining a decision or reporting a violation.
- KNO-001 — The repository MUST optimize for teaching reliable agent behavior, not accumulating unrelated product features.
- KNO-002 — Production code MUST act as an executable proof of documented rules.
- KNO-003 — Correct/incorrect examples MUST live in documentation unless they are expected to compile and are verified by the build.
- KNO-004 — Repeated human corrections MUST be evaluated for promotion into a durable rule, review check, pattern, or eval scenario.
- KNO-005 — Policy changes MUST update every affected knowledge surface: canonical rules, task guide, review checklist, examples, and evals.
- INI-001 — Before creating a new product, application, service, library, tool, repository, or implementing an idea, an agent MUST establish a human-approved project name. If the request does not provide an unambiguous name, the agent MUST ask for it as a blocking question and wait for the answer before writing code or creating project files.
- INI-002 — While the project name is unresolved, an agent MUST NOT initialize a repository, generate an archive, create or edit production files, or invent CMake project names, target names, module prefixes, QML URIs, bundle identifiers, package identifiers, namespaces, or branding. Read-only discovery and requirements discussion MAY continue.
- INI-003 — An explicit name in the request or an established name in an
existing repository satisfies the gate. Agents MUST NOT ask again without a
concrete naming conflict, and MUST NOT substitute placeholders such as
MyApp, a feature description, or an invented marketing name for human approval. - INI-004 — When this repository is used as an external engineering authority, the agent MUST identify the exact repository revision it read and the routed guides it applied. A link or citation alone is not evidence that the current contract was loaded. If the required revision or guides cannot be read, implementation MUST stop and the limitation MUST be reported.
The knowledge architecture is described in
docs/agent/README.md.
After reading this file, read only the guides required for the task.
| Task | Required guide |
|---|---|
| Start a new product, project, repository, or idea implementation | docs/agent/START_PROJECT.md before every other routed guide |
| Understand repository structure or introduce a subsystem | docs/agent/ARCHITECTURE.md |
| Add or change a C++ module | docs/agent/MODULES.md, docs/agent/NAMING.md, and docs/agent/SYNTAX_AND_STYLE.md |
| Write or review C++ syntax, identifiers, or formatting | docs/agent/SYNTAX_AND_STYLE.md and docs/agent/NAMING.md |
| Design or review a public API | docs/agent/API_DESIGN.md and docs/agent/ERRORS_AND_RESOURCES.md |
| Add ownership, handles, files, sockets, or threads | docs/agent/ERRORS_AND_RESOURCES.md |
| Add OS-specific behavior | docs/agent/PLATFORM_BOUNDARIES.md |
| Create, replace, package, or verify application icons or in-application brand marks | docs/agent/APP_ICONS_AND_BRANDING.md, docs/agent/PLATFORM_BOUNDARIES.md, and docs/agent/QT_QUICK_UI.md when the mark appears in the interface |
| Select the interface for an unspecified user-facing interactive application | docs/agent/QT_QUICK_UI.md and docs/agent/ARCHITECTURE.md |
| Design or implement a Qt graphical interface | docs/agent/QT_QUICK_UI.md, docs/agent/ARCHITECTURE.md, and docs/agent/NAMING.md |
| Generate a new Qt Quick/C++ project baseline | docs/agent/PROJECT_CMAKE_BASELINE.md, docs/agent/QT_QUICK_UI.md, and docs/agent/CMAKE_AND_TOOLCHAINS.md |
| Change CMake, compilers, modules, or standard-library integration | docs/agent/CMAKE_AND_TOOLCHAINS.md |
| Add or change behavior | docs/agent/TESTING_AND_VERIFICATION.md |
| Control exploration, tool usage, subagents, or verification cost | docs/agent/EXECUTION_DISCIPLINE.md |
| Diagnose a known build or module failure | docs/agent/COMMON_FAILURES.md |
| Learn approved and forbidden code shapes | docs/agent/PATTERNS.md |
| Review a change | docs/REVIEW.md and all guides touched by the diff |
| Evaluate agent behavior | evals/README.md and the relevant scenario suite |
Do not load every detailed guide by default. Route by task, then read each selected guide completely.
Every implementation task MUST follow this loop:
Read the request and applicable rules
Pass the project initiation gate when creating a new product or project
Inspect the current diff and working tree
Locate the owning subsystem and module boundary
Read only the relevant implementation, tests, and routed guides
Classify the verification level and important assumptions
Make the smallest correct change
Run the smallest verification gate that proves the changed surface
Inspect the first causal failure
Fix and rerun from the earliest stage invalidated by that fix
Escalate verification only when risk, uncertainty, or changed scope requires it
Review the final diff
Report exact evidence and anything not verified
Stop
- SCP-001 — Agents MUST inspect before editing and MUST NOT guess project behavior.
- SCP-002 — Agents MUST preserve unrelated human changes in a dirty working tree.
- SCP-003 — Agents MUST make the smallest coherent change that fully solves the request.
- SCP-004 — Broad rewrites, dependency additions, API renames, and formatting churn require explicit justification.
- SCP-005 — Diagnosis does not authorize implementation unless the user also asks for a fix.
- SCP-006 — No agent may claim success before collecting real verification evidence.
Reliable engineering does not require unbounded exploration. The default is one focused agent, routed reading, and evidence proportional to the changed surface.
- EFF-001 — A single-agent workflow is the default for implementation, debugging, UI work, build diagnosis, testing, and review.
- EFF-002 — Agents MUST NOT create subagents, parallel reviewers, or delegated investigations for routine scoped work. Delegation requires genuinely independent scopes whose parallel execution materially improves the result.
- EFF-003 — Every delegated scope MUST have an explicit question, bounded file or subsystem surface, and stop condition. Agents MUST NOT recursively delegate review or exploration.
- EFF-004 — Repository-local source, tests, build metadata, issue context, and checked-in documentation take priority over web research. External search is justified only when current external documentation, API behavior, or toolchain facts are required.
- EFF-005 — Agents MUST use targeted search before broad reads and MUST NOT repeatedly read unchanged files, guides, logs, or diffs without a concrete new question.
- EFF-006 — Generated files, build trees, vendored dependencies, caches, package outputs, and third-party source trees are excluded from discovery unless evidence directly implicates them.
- EFF-007 — Discovery MUST stop once the owning subsystem, relevant contract, change surface, and verification path are known.
- EFF-008 — Agents MUST NOT perform opportunistic refactoring, unrelated cleanup, speculative redesign, or broad review during a scoped task.
- EFF-009 — A compatible configured build tree SHOULD be reused for incremental verification. Clean configuration is reserved for changes that invalidate build-system/toolchain state or for the final product gate.
- EFF-010 — Once the requested behavior is implemented, the required verification level passes, and the final diff is reviewed, the agent MUST stop instead of continuing exploratory or cosmetic work.
See docs/agent/EXECUTION_DISCIPLINE.md.
- ARC-001 — Each behavior MUST have a clear owning subsystem.
- ARC-002 — Dependencies SHOULD point from composition and adapters toward stable domain abstractions, not the reverse.
- ARC-003 — Public interfaces MUST expose the smallest useful surface.
- ARC-004 — Platform code, third-party adaptation, and low-level operations MUST remain at explicit boundaries.
- ARC-005 — Vague dumping grounds such as
utils,helpers,common, andmiscMUST NOT be introduced without an existing domain-specific reason. - ARC-006 — New abstractions MUST solve a demonstrated design pressure; do not add speculative layers.
- ARC-007 — Repository layout MUST communicate responsibility. New user-facing applications SHOULD separate domain, application, presentation, adapter, composition, and UI assets when those responsibilities exist; empty ceremonial layers and technology-named dumping grounds are forbidden.
See docs/agent/ARCHITECTURE.md.
This repository targets C++20 or newer and uses C++26 for its executable reference path. Prefer C++26, then C++23, with C++20 as the minimum family for derived repositories.
- MOD-001 — New internal production code MUST use C++ modules by default.
- MOD-002 — Exported declarations MUST live in
.cppmfiles. - MOD-003 — Non-trivial implementations MUST live in
.cppimplementation units. - MOD-004 — Large algorithms, filesystem mutation, networking, database logic, UI behavior, and platform branches MUST NOT live in exported module interfaces.
- MOD-005 — Lightweight templates, concepts, compile-time constants, small
value types, and small
constexprfunctions MAY remain in.cppmwhen visibility is required. - MOD-006 — New
.hfiles are forbidden unless an external tool or ABI requires that exact extension. - MOD-007 —
.hppis reserved for third-party, ABI, C API, or textual compatibility boundaries; it is not the default project architecture. - MOD-008 — Any header boundary MUST be isolated, documented, and kept out of domain logic.
- MOD-009 — Project-owned production boundaries MUST use C++ modules. Standard-library integration MUST NOT cause a fallback to project headers or classic header/source architecture.
- MOD-010 — Project code MUST NOT use the experimental
import std;path. Standard-library declarations MUST come from the minimal owning standard headers while project-owned.cppmmodules, module imports, and CMake module file sets remain intact. - MOD-011 — In a module unit, standard-library headers MUST appear
in the global module fragment after
module;and before the named module declaration. They MUST NOT be textually included inside the named module purview. - MOD-012 — Standard-library headers do not authorize new project-owned
.hor.hppfiles. Standard headers and project headers are distinct architectural concerns.
Preferred layout:
src/
project/
project.cppm
project.cpp
project_platform.cppm
project_platform_macos.cpp
project_platform_windows.cpp
project_platform_linux.cpp
See docs/agent/MODULES.md.
- NAM-001 — Module names MUST be dotted, lowercase, stable, domain-oriented, and contain no underscore.
- NAM-002 — Namespaces MUST mirror module identity.
- NAM-003 — Types, classes, concepts, and enum-class enumerators MUST use PascalCase.
- NAM-004 — Functions, parameters, and local variables MUST use lowerCamelCase.
- NAM-005 — Private and protected non-static data members MUST use the
m_prefix followed by lowerCamelCase. - NAM-006 — Identifiers ending in
_are forbidden for project-owned data members. - NAM-007 — Reserved identifiers and keyword workarounds such as
delete_,class_,_Name, and__nameMUST NOT be introduced. - NAM-008 — File names MAY use underscores when useful; the module identity inside the source remains dotted.
- NAM-009 — Multiword identifiers MUST preserve word boundaries through the
required casing; do not collapse
expressionTextintoexpressiontext. - NAM-010 — Acronyms MUST be treated as words: use
HttpClient,UserId, andparseJson, notHTTPClient,UserID, orparseJSON. - NAM-011 — Boolean names SHOULD read as predicates, such as
isReady,hasValue,canRetry, orshouldClose. - NAM-012 — QML types and files MUST use PascalCase; QML
idvalues, properties, signals, handlers, and JavaScript functions MUST use lowerCamelCase.
Correct:
export module modern.cpp.agent;
export namespace modern::cpp::agent {
enum class StandardLevel { Cpp20, Cpp23, Cpp26 };
class Expression final {
private:
std::string m_expressionText;
};
}Incorrect:
enum class ErrorCode { empty_expression };
class Expression final {
private:
std::string my_member;
std::string mymember_;
};See docs/agent/NAMING.md.
Modern syntax is a correctness and readability contract, not optional polish.
- SYN-001 — Function return syntax MUST optimize readability rather than
enforce one mechanical form. Leading return types SHOULD be used for simple,
immediately recognizable results such as
void,bool, numeric types, and short domain types. Trailing return types SHOULD be used when required by the language or when they materially improve a dependent, complex, or multiline declaration. - SYN-002 — Variables MUST be initialized at declaration; default member initializers SHOULD establish safe object state.
- SYN-003 — Use
const,constexpr,consteval, andconstinitwhenever their guarantees accurately express the intended lifetime and mutability. - SYN-004 — Enumerations MUST use
enum class; enumerator cases MUST followNAM-003, including in everyswitchlabel. - SYN-005 — Use
nullptr, neverNULLor integer zero as a null pointer. - SYN-006 — C-style and functional-style casts are forbidden; use the
narrowest named C++ cast and justify
reinterpret_cast. - SYN-007 — Single-argument constructors MUST be
explicitunless implicit conversion is the documented purpose of the type. - SYN-008 — Results whose loss can hide an error or skip required work MUST
be marked
[[nodiscard]]. - SYN-009 — Overriding virtual functions MUST use
override; types and functions that are intentionally not extensible SHOULD usefinal. - SYN-010 — Prefer brace initialization when it prevents narrowing or establishes an explicit initial state.
- SYN-011 — Macros MUST NOT implement constants, types, functions, or business logic when a language feature can express the same intent.
- SYN-012 — Declare one logical object per statement and avoid hidden mutation, comma expressions, and dense clever expressions.
- SYN-013 —
using namespaceis forbidden at namespace scope in project code; narrow function-local usage MAY be accepted when unambiguous. - SYN-014 — Use
noexceptonly when the contract can be upheld; destructors and move operations SHOULD state the guarantee when it affects generic code. - SYN-015 — Braces are required for control-flow bodies, including single-statement branches and loops.
- SYN-016 — Class declarations SHOULD order access sections as
public,protected, thenprivate; behavior precedes data, and invariant-bearing data MUST remain private. - SYN-017 — Use
usingaliases instead oftypedeffor project-owned type aliases. - SYN-018 — Constructor initializer lists MUST follow data-member declaration order and MUST NOT perform hidden unrelated work.
- SYN-019 — Lambda captures MUST make lifetime intent clear; stored or asynchronous lambdas MUST NOT capture short-lived objects by reference.
- SYN-020 —
autoSHOULD remove repetition without hiding important domain, ownership, or conversion semantics. - SYN-021 — Prefer range-based loops and standard range algorithms when they express iteration more directly without weakening clarity or portability.
- SYN-022 — Source units SHOULD follow a stable reading order: module declaration/imports, namespace, public or member definitions, private helpers, then the smallest composition entry point where applicable.
- SYN-023 — New project-owned formatted console output MUST use
std::printorstd::println. Stream insertion withstd::cout,std::cerr, orstd::clogis forbidden for ordinary output; a stream-only compatibility boundary requires an explicit local justification.
Correct:
void inputDecimalPoint();
[[nodiscard]] auto parseExpression(std::string_view text)
-> std::expected<Expression, ErrorCode>;
std::println("Result: {}", result);
switch (errorCode) {
case ErrorCode::EmptyExpression:
return "Expression must not be empty.";
case ErrorCode::InvalidToken:
return "Expression contains an invalid token.";
}See docs/agent/SYNTAX_AND_STYLE.md.
- API-001 — Every exported class, function, enum, concept, and public data structure MUST have English Doxygen documentation.
- API-002 — Public APIs MUST communicate ownership, lifetime, optionality, and failure explicitly.
- API-003 — Use
std::spanfor non-owning contiguous views andstd::string_viewfor read-only strings only when lifetime is clear. - API-004 — Use
std::optionalfor optional values andstd::variantfor closed alternatives. - API-005 — Generic public APIs MUST use meaningful concepts when an operation set or type category affects correctness.
- API-006 — Prefer compile-time enforcement when the rule is knowable at compile time and produces a useful diagnostic.
- API-007 — Concepts MUST express real contracts and MUST NOT be decorative.
- API-008 — Use
constexpr,consteval,constinit, ranges, and coroutines only when they improve correctness or clarity.
See docs/agent/API_DESIGN.md.
- ERR-001 — Recoverable expected failures SHOULD use
std::expectedor the project equivalent. - ERR-002 — Exceptions MAY represent construction failure, violated invariants, or genuinely exceptional subsystem failures.
- ERR-003 — Exceptions MUST NOT be ordinary control flow for expected outcomes unless the owning subsystem explicitly establishes that policy.
- ERR-004 — Errors MUST NOT be swallowed, converted into fake success, or
reduced to an unexplained
bool. - ERR-005 — Logging and continuing is allowed only when continuation is demonstrably safe.
- RES-001 — Every acquired resource MUST have deterministic RAII ownership.
- RES-002 — Raw owning pointers and scattered manual cleanup are forbidden.
- RES-003 —
newanddeleteMAY appear only inside an isolated low-level ownership abstraction with tests and justification. - RES-004 — Move-only resource owners MUST make copy and move semantics explicit.
- RES-005 — Files, sockets, handles, locks, threads, timers, and temporary directories are resources and follow the same ownership rules.
See docs/agent/ERRORS_AND_RESOURCES.md.
- PLT-001 — Platform macros MAY appear only at platform boundaries.
- PLT-002 — Business and domain logic MUST NOT contain scattered platform conditionals.
- PLT-003 — Each supported platform SHOULD have a separate implementation unit behind a stable module declaration.
- PLT-004 — OS handles and C APIs MUST be wrapped behind small RAII-safe adapters.
- PLT-005 — Unsupported platforms MUST fail explicitly, not silently select unrelated behavior.
- APP-001 — Product names, canonical marks, platform compositions, and in-application brand marks MUST come from human-approved sources. Agents MUST NOT invent, redraw, recolor, crop, plate, or mask branding without explicit authorization.
- APP-002 — Canonical source artwork, Apple-specific compositions, non-Apple compositions, generated platform artifacts, and in-application marks MUST have explicit ownership and MUST NOT be treated as one interchangeable bitmap.
- APP-003 — Native icon resources MUST remain at explicit platform and packaging boundaries. CMake, manifests, resource scripts, asset catalogs, desktop entries, and installers MUST reference them target-locally and must not leak packaging concerns into domain or application modules.
- APP-004 — Apple icon assets MUST use the selected Apple asset-catalog, layered-icon, or bundle-resource workflow without unintended double masking, duplicate plates, or hand-edited generated project files.
- APP-005 — Android launcher icons MUST use adaptive foreground/background layers when supported. Critical content MUST remain inside the platform safe zone, the foreground MUST NOT contain a pre-applied launcher mask or shadow, and themed/monochrome support MUST be supplied when claimed.
- APP-006 — Windows and Linux deliverables MUST use their native artifact families: a multi-representation Windows icon or package asset set, and a stable Linux icon name whose hicolor installation matches its desktop entry.
- APP-007 — A brand mark rendered inside the application MUST be treated as a UI asset with deliberate source size, opacity, scaling, contrast, and high-DPI behavior. Launcher or store artwork MUST NOT be reused blindly as a small interface glyph.
- APP-008 — Icon generation MUST be deterministic, idempotent, and derived from immutable approved masters. Generated artifacts MUST NOT be hand-edited without updating the generator and verification contract.
- APP-009 — Static verification MUST validate required dimensions, container representations, resource references, manifest/catalog metadata, alpha policy, and installed icon-name consistency for every enabled platform.
- APP-010 — Application icon work MUST be visually verified from the actual packaged product in representative system contexts and masks. Source images or generated file lists alone are not visual evidence.
- APP-011 — Before changing approved artwork to address a stale appearance, agents MUST verify package bytes and resource references and rule out launcher, shell, installer, or previous-install caching.
- APP-012 — Every requested icon surface MUST be reported separately as
PASS,FAIL, orNOT VERIFIED. Missing SDKs, devices, package formats, stores, launchers, or desktop environments MUST NOT inherit success from another platform.
See docs/agent/APP_ICONS_AND_BRANDING.md.
See docs/agent/PLATFORM_BOUNDARIES.md.
These rules apply when a derived project requires a Qt graphical interface or
when GUI-015 selects one for an otherwise unspecified user-facing interactive
application. They do not add Qt as a dependency of this executable knowledge
reference.
- GUI-001 — New Qt graphical interfaces MUST use Qt 6, Qt Quick, QML, and Qt Quick Controls. Qt Widgets is not the default UI technology.
- GUI-002 — New use of Qt Widgets is forbidden unless the user explicitly requests it or an existing compatibility boundary requires it; the exception MUST be documented.
- GUI-003 — Domain and application behavior MUST remain in C++ modules and MUST NOT depend on QML or visual controls.
- GUI-004 — QML MUST own presentation, layout, animation, and interaction; business rules, validation, persistence, and authoritative state MUST NOT be implemented in QML JavaScript.
- GUI-005 — The QML/C++ boundary MUST expose a small presentation contract through typed properties, invokable operations, signals, and purpose-built models or view models.
- GUI-006 — Qt meta-object or MOC compatibility headers MAY use
.hpponly as an isolated adapter underMOD-007; they MUST NOT become domain headers. - GUI-007 — Before implementation, an agent MUST define user flows, screen states, reusable components, design tokens, and failure/empty/loading states.
- GUI-008 — Layouts MUST be responsive and adaptive; hard-coded positioning for a single window size is forbidden unless the interface is intentionally fixed and that constraint is documented.
- GUI-009 — Interactive controls MUST support keyboard navigation, visible focus, accessible names, and sufficient contrast.
- GUI-010 — User-visible text MUST be translation-ready; colors, spacing, typography, and motion SHOULD come from reusable design tokens.
- GUI-011 — Long-running work MUST NOT block the GUI thread; cancellation, progress, failure, and lifetime MUST be modeled explicitly.
- GUI-012 — QML modules MUST be registered with
qt_add_qml_moduleand targets MUST link only the required Qt Quick components. - GUI-013 — Qt UI changes MUST test C++ presentation behavior and SHOULD add QML interaction tests, linting, or smoke coverage where the toolchain permits.
- GUI-014 — QObject parent ownership, QML engine ownership, and RAII ownership MUST be deliberate and MUST NOT produce ambiguous lifetime.
- GUI-015 — For a user-facing interactive application, when the interface type is unspecified and the context does not clearly identify a CLI tool, service, library, daemon, or other headless product, an agent MUST NOT deliver a CLI-only application. The primary interface MUST use Qt 6, Qt Quick, QML, and Qt Quick Controls.
- GUI-016 — A CLI MAY be provided as a secondary adapter for automation, testing, or headless use. It MUST depend on the same application and domain modules as the graphical interface and MUST NOT duplicate business logic or replace the required primary interface.
- GUI-017 — A new or redesigned interface MUST define a product-specific visual and interaction direction grounded in the audience, primary tasks, information hierarchy, affordances, feedback, error prevention, and recovery. Agents MUST NOT reuse a generic repetitive screen recipe or copy reference visuals without adapting them to the product.
- GUI-018 — New Qt Quick repositories MUST place QML and visual assets under
a top-level
ui/boundary. Pages, reusable components, theme tokens, and assets SHOULD use responsibility-based subdirectories when they exist; a top-levelqml/dumping directory is not the preferred project structure. - GUI-019 — When a QML module contains files in extra directories, projects
that support Qt policy
QTP0004MUST select itsNEWbehavior beforeqt_add_qml_module. The policy check MUST remain compatible with the declared minimum Qt version. Missing generated.qmltypesafter a failed CMake Generate step is a cascading symptom, not an independent root cause. - GUI-020 — Every project-owned header referenced by Qt-generated QML type
registration code MUST be reachable through a target-local include directory.
A
QML_ELEMENTadapter stored undersrc/presentation/MUST add that directory to the QML target; agents MUST NOT edit generated*_qmltyperegistrations.cppfiles or move adapters into the repository root merely to satisfy generated includes. - GUI-021 — A QObject exposed as a QML-creatable type MUST NOT be
final. Qt's generated registration wrapper derives from such a type. A presentation adapter MAY befinalonly when QML does not construct it and its explicit registration and ownership strategy does not require subclassing. - GUI-022 — A requested or default Qt graphical deliverable MUST complete at least one clean Qt-enabled configure and full build before it is described as complete. The build MUST compile generated MOC, QML type-registration, resource, and QML cache sources and link the graphical executable. A core-only or GUI-disabled build is partial evidence and MUST NOT validate the GUI.
- GUI-023 — Before implementing a screen, agents MUST define a layout contract: outer content bounds, columns, alignment lines, margins, gutters, spacing scale, repeated-control metrics, minimum and maximum content widths, and each region's grow, shrink, wrap, or overflow behavior. Coincidental alignment from unrelated hard-coded values is not acceptable.
- GUI-024 — Repeated controls and parallel regions MUST preserve deliberate edge, center, baseline, size, and gap relationships. Header actions, content edges, grids, displays, footers, and adjacent panels MUST share documented alignment anchors or have an explicit reason not to.
- GUI-025 — Responsive design MUST define compact, standard, and wide compositions. Expanding a window MUST NOT merely stretch containers while leaving task controls pinned to one edge, producing accidental dead space, or separating related content. Use bounded task widths, centering, reflow, or deliberate redistribution according to the product hierarchy.
- GUI-026 — A graphical deliverable MUST pass a visual-detail review from rendered screenshots at representative minimum, standard, and wide sizes and in relevant appearance and content states. The review MUST inspect clipping, overlap, truncation, alignment, baselines, spacing rhythm, optical centering, contrast, focus, hit targets, and unintended empty space. Code inspection or successful compilation alone cannot justify a polished or final UI claim.
- GUI-027 — Every QML type, property, signal, method, enum, attached
property, and import MUST exist on the exact instantiated type in the
project's declared minimum Qt version. Agents MUST NOT infer API availability
from a visually similar type or from a newer Qt release. The complete QML
module MUST pass
qmllintand runtime component creation before delivery. - GUI-028 — A Qt Quick Controls styling strategy MUST be explicit and
consistent. A project that replaces
background,contentItem,indicator, delegates, or popups MUST select a customizable style such as Basic, Fusion, Imagine, Material, or Universal before any Controls QML is loaded. A project that intentionally uses a native style MUST keep to that style's supported customization surface. Platform-default style selection is not an acceptable hidden dependency for custom controls. - GUI-029 — QML geometry MUST have one acyclic ownership direction.
implicitWidthorimplicitHeightMUST NOT depend on a parent viewport's available size when that viewport derives its own implicit or content size from the child. Scrollable editors, popups, delegates, and layouts MUST define which object owns viewport size and which owns content size, and runtime binding-loop warnings are release-blocking defects. - GUI-030 — Control geometry MUST be content-safe. Primary and destructive action labels MUST remain fully readable in the reference locale; translated text MUST reflow, grow, or use an explicitly reviewed alternate label rather than accidental elision. Popup delegates, bilingual or RTL rows, icons, indicators, focus rings, and hit targets MUST remain contained and aligned at supported sizes. Fixed widths require evidence against realistic longest content.
- GUI-031 — Typography MUST be portable and intentional. A font family MAY be named only when it is bundled with a documented license or verified on every supported platform with a fallback. Otherwise use Qt/system-resolved fonts and style hints. Missing-font substitutions, inconsistent metrics, and avoidable font-alias warnings MUST be fixed before delivery.
- GUI-032 — Qt UI verification MUST be warning-clean for project-owned QML. Strict QML lint and a deterministic runtime smoke or interaction test MUST fail on component-load errors, unsupported control customization, binding loops, invalid properties, missing project fonts, and other project-caused Qt warnings. The smoke path MUST reach an explicit ready state and exercise the primary flow; merely starting the event loop for a fixed delay is insufficient.
- GUI-033 — Generated Qt Quick projects MUST give every project QML source
a deterministic
QT_RESOURCE_ALIASbeforeqt_add_qml_module. The preferred shape is a source-relativeui/...path whose alias removes only the architecturalui/boundary while preserving logical directories such aspages/,components/, andtheme/.Main.qmlMUST remain at the QML module resource root soloadFromModule(uri, "Main")resolves it.
See docs/agent/QT_QUICK_UI.md.
Primary path:
Clang 22+ or GCC 15+
CMake 3.30+
Ninja 1.11+
C++26
project-owned C++ modules
standard-library headers in global module fragments
- BLD-001 — Use target-based modern CMake.
- BLD-002 — New module interfaces MUST be declared through
target_sources(... FILE_SET CXX_MODULES ...). - BLD-003 — Use target-local compile features, definitions, include paths, and options; do not mutate global compiler flags casually.
- BLD-004 —
CXX_SCAN_FOR_MODULESMUST be enabled for targets that produce or consume project-owned modules.CMAKE_CXX_MODULE_STDis not part of the supported build path. - BLD-005 — CMake MUST NOT probe, enable, or configure experimental
standard-library modules.
CMAKE_CXX_COMPILER_IMPORT_STD,CMAKE_CXX_STDLIB_MODULES_JSON, and experimental import-std gates MUST NOT influence project configuration. - BLD-006 — Compiler, CMake, generator, selected language standard, and project-module dependency scanning form one compatibility unit and MUST be diagnosed together.
- BLD-007 — Unsupported toolchains MUST fail at configure time with the observed values and a useful remediation direction.
- BLD-008 — Agents MUST NOT silently downgrade the language standard or project-owned module architecture to obtain a green build. Standard-library headers in a global module fragment are the primary architecture, not a downgrade or fallback.
- BLD-009 — Import-std UUID gates, standard-library module metadata repair, and conditional standard-library modes are forbidden. Generated projects MUST use one deterministic standard-header path.
- BLD-010 — CMake 3.30+ with Ninja and a compiler that supports the selected
language standard MAY build project-owned modules without standard-library
module metadata. Diagnostics MUST discuss project-module scanning rather than
recommend a newer CMake solely for
import std. - BLD-011 — Builds MUST NOT locate, validate, rewrite, or cache
libc++.modules.jsonorlibstdc++.modules.json. Those files are outside the supported standard-header architecture. - BLD-012 — A newer compiler major version is not automatically supported. Each compiler/CMake/generator combination MUST pass configure, build, and tests before becoming a supported project-module toolchain.
- BLD-013 — Standard-library integration MUST have one mode: minimal standard headers. Build options and compile definitions that switch between standard-library delivery mechanisms are forbidden.
- BLD-014 — Generated Qt Quick/C++ projects MUST begin from
docs/agent/PROJECT_CMAKE_BASELINE.md. The baseline MUST register.cppmfiles throughFILE_SET CXX_MODULES, enable target-local module scanning, use standard headers, guard required Qt policies, and expose nested presentation headers to generated QML registration code. - BLD-015 — Generated Qt Quick projects MUST copy and run the baseline's
deterministic presentation preflight against every project-owned QML
registration header. A
QML_ELEMENTtype declaredfinalMUST fail during configure with a causal diagnostic. The preflight supplements and MUST NOT replace the full Qt build required byGUI-022. - BLD-016 — Generated Qt Quick projects that customize Controls MUST select one supported customizable style in the composition root before loading QML, and MUST use that same effective style for application runs, QML tests, lint setup, screenshots, and smoke verification. The selected style and minimum Qt version are build-and-test inputs, not undocumented workstation defaults.
- BLD-017 — Generated Qt Quick projects MUST place QML module artifacts and runtime executables under distinct configured output roots. A normal executable target and QML URI with the same approved name MUST remain valid. Strict QML lint MUST import the actual configured QML output root and use only options supported by the declared minimum Qt version.
Do not use std::views::enumerate in portable examples unless the active
standard library has been verified to provide it.
See docs/agent/CMAKE_AND_TOOLCHAINS.md.
- TST-001 — Every behavior change MUST have relevant automated coverage when practical.
- TST-002 — Tests SHOULD exercise public behavior rather than private implementation details.
- TST-003 — Recoverable failures, invalid input, boundary values, and ownership behavior MUST be tested when introduced.
- TST-004 — Tests MUST be deterministic and independent of external network or mutable global state unless explicitly classified as integration tests.
- TST-005 — Temporary resources MUST use RAII cleanup.
- TST-006 — A test command that discovers zero tests MUST NOT be reported as a successful test run.
- TST-007 — Verification depth MUST cover every claimed product surface. For a Qt application this includes domain/application behavior, presentation behavior, QML creation or interaction smoke coverage, and the complete Qt integration build; a headless unit-test target alone is insufficient.
- TST-008 — Critical responsive and geometry invariants SHOULD have deterministic QML tests where practical, including parent containment, non-overlap, breakpoint selection, repeated-control sizing, and primary alignment anchors. Automated geometry checks supplement rather than replace rendered visual review.
- TST-009 — Qt Quick projects MUST run strict QML lint with a zero project-warning budget and a warning-fatal runtime test under the selected Controls style. Tests MUST cover component creation plus enough interaction and representative content to instantiate lazy popups, dialogs, delegates, scrollable editors, and other primary-path components.
- TST-010 — The generated Qt Quick baseline MUST have an integration
fixture whose executable target and QML URI share the same name. When Qt is
available it MUST clean-configure, fully build and link, run strict module
lint, load
MainthroughloadFromModule, run a warning-fatal readiness smoke, and verify distinct runtime and QML output paths. Without Qt the GUI fixture isNOT VERIFIED, not a core-test success. - VER-001 — Configure, build, and test are separate results and MUST be reported separately.
- VER-002 — Agents MUST stop a command chain after configure failure; later missing-build and zero-test messages are cascading symptoms.
- VER-003 — Exact commands and exact pass/fail counts MUST be reported.
- VER-004 — Warnings introduced by the change MUST be resolved.
- VER-005 — Upstream experimental warnings MAY remain only when identified accurately and not caused by project code.
- VER-006 —
git diff --checkand final-diff inspection are required before completion. - VER-007 — Documentation and agent-rule changes MUST run the knowledge contract test in addition to the normal build and tests.
- VER-008 — Verification claims MUST match the exact configured feature set
and targets that ran. Disabled, dependency-skipped, unavailable, or unbuilt
deliverables MUST be reported as
NOT VERIFIED, never inferred from another target's success. - VER-009 — Before delivering a generated project archive or calling it ready, an agent MUST use a clean build tree to configure all requested default features, build the full default target, run all discovered tests with zero tests treated as an error, and run applicable product smoke checks. If the required SDK or runtime is unavailable, the artifact MAY be labeled a draft but MUST NOT be presented as a verified final deliverable.
- VER-010 — Final Qt verification MUST record the exact viewport sizes,
appearance modes, content states, screenshots, and interaction paths that
were visually inspected. Any unreviewed required state is
NOT VERIFIED. - VER-011 — Final Qt evidence MUST name the minimum Qt version, effective
Controls style, strict
qmllintcommand and warning count, runtime smoke or interaction command, and project-owned Qt/QML warning count. A clean compile with runtime warnings is not a clean Qt verification result. - VER-012 — Generated Qt project verification MUST record the actual runtime
target path, QML output root, module
qmldir, and.qmltypespath after the final link. Successful module scanning, MOC, RCC, registration, or QML cache generation before a failed final link is not a successful GUI build. - VER-013 — Every change MUST be classified as verification level
V0throughV4before final verification. The level is determined by the changed surface and claim scope, not by agent preference. - VER-014 — Production C++ changes MUST compile the smallest affected
production target. Qt/QML changes MUST build the affected Qt target when QML
compilation/resource integration is part of that target, then run applicable
lint and smoke checks. A user prohibition or unavailable toolchain changes the
result to
NOT VERIFIED; it does not create inferred success. - VER-015 — After a failure, rerun from the earliest verification stage invalidated by the fix. Source-only fixes do not require repeated configure; test-only fixes do not require a clean rebuild; CMake/toolchain fixes do.
- VER-016 — Clean full verification is mandatory for
V4, and forV3changes when build-system or toolchain state is invalidated. RoutineV1andV2work MUST NOT clean-configure or rebuild unrelated targets by default. - VER-017 — A compatible configured build tree SHOULD be reused for
V1andV2. If no compatible tree exists, configure once with the minimum feature set required to build the affected production surface. - VER-018 — Required verification skipped by explicit user instruction,
missing SDK/runtime, unavailable platform, or environment restrictions MUST be
reported as
NOT VERIFIEDat that layer and in every claim that depends on it.
Verification levels:
| Level | Typical change | Required final gate |
|---|---|---|
V0 |
Documentation, comments, non-executable policy/metadata | Relevant contract checks + final diff; no build unless executable behavior changed |
V1 |
Local QML/presentation/resource change without C++/CMake topology changes | Affected Qt target when applicable + relevant lint/smoke + visual evidence for visual claims |
V2 |
Ordinary target-local C++ behavior or bug fix | Affected production target + directly relevant tests/smoke |
V3 |
CMake, module graph, public API, dependency, Qt registration/resource topology, platform boundary | Configure as required + all affected production surfaces + relevant integration tests |
V4 |
Release, final archive, major milestone, toolchain qualification, explicit full verification | Clean configure + full default build + all tests + applicable lint/smoke/visual gates |
The default implementation loop is incremental. The V4 final gate retains the
strict full-build workflow:
cmake -S . -B build/verify -G Ninja -DCMAKE_BUILD_TYPE=Debug
cmake --build build/verify --parallel --target all
ctest --test-dir build/verify --output-on-failure --no-tests=errorSee docs/agent/TESTING_AND_VERIFICATION.md.
- DOC-001 — Source comments and repository technical documentation MUST be written in English.
- DOC-002 — Documentation MUST explain decisions, boundaries, and failure modes rather than restating syntax.
- DOC-003 — Good and bad examples MUST be labeled unambiguously.
- DOC-004 — Bad examples MUST NOT be added as normal build inputs.
- DOC-005 — Architecture diagrams MUST match the current dependency graph.
- DOC-006 — A rule should be short, testable, general, and owned by one canonical location.
- DOC-007 — Task guides MAY elaborate a rule but MUST NOT redefine it.
- DOC-008 — Canonical guides and general-purpose examples MUST use domain-neutral placeholder names unless a concrete domain is the behavior being taught. Scenario-specific evals MAY use concrete domains.
- SEC-001 — Secrets, tokens, private endpoints, and machine-specific paths MUST NOT be committed.
- SEC-002 — Local active MCP configuration belongs in
.mcp.jsonand MUST remain ignored. - SEC-003 — Prefer the smallest useful permission set: read-only context, local git, remote read access, build/test tools, then write capability only with explicit intent.
- SEC-004 — Deployment, payment, production database, destructive, or broad write tools require explicit user authorization.
- SEC-005 — Destructive operations require exact targets and prior read-only resolution.
- SEC-006 — External dependencies require a strong reason and a documented ownership/update strategy.
See docs/MCP.md for the MCP safety model.
- CHG-001 — Commits MUST be cohesive and use precise imperative titles.
- CHG-002 — Pull request summaries MUST state what changed, why, how it was tested, known limitations, and intentional exceptions.
- CHG-003 — Tags, releases, deployments, and publishing require explicit human approval.
- CHG-004 — Agents MUST NOT stage, commit, push, or open a pull request unless the user requested that workflow.
Good commit titles:
Add module-based version parser
Fix platform app data directory resolution
Define agent eval scenarios for module changes
Bad commit titles:
Update code
Fix stuff
AI changes
Every completed implementation report MUST include:
- REP-001 — Files changed.
- REP-002 — What changed and why.
- REP-003 — Exact configure/build commands and results for every stage required by the selected verification level; stages not required or not run MUST be identified instead of fabricated.
- REP-004 — Exact test/lint/smoke commands, discovered test count when applicable, and results for every stage that ran.
- REP-005 — Known limitations or unverified environments.
- REP-006 — Any rule exception and its justification.
- REP-007 — For reflected corrections, what was learned and why the new rule is general enough to keep.
- REP-008 — Reports for multi-surface products MUST include a verification
matrix that names each requested surface or deliverable, whether it was
enabled, the exact target or test that exercised it, and its
PASS,FAIL, orNOT VERIFIEDresult. - REP-009 — UI reports MUST list the visual acceptance matrix and any known alignment, overflow, density, typography, contrast, or responsive limitation; a generic statement such as "responsive and polished" is not evidence.
- REP-010 — Qt UI reports MUST record the effective Controls style, Qt version, QML lint result, runtime warning result, and the interactions that instantiated popups, dialogs, delegates, editors, and other lazy components.
- REP-011 — Every implementation report MUST name the selected verification
level (
V0–V4) and the reason that level matches the changed surface. - REP-012 — Skipped, prohibited, unavailable, or deferred verification
stages MUST be listed explicitly with the resulting
NOT VERIFIEDscope.
Never report:
It should work.
Probably fixed.
Tests should pass.
Report only observed evidence.
Agents MUST NOT:
- Launch routine parallel subagents or reviewers when one bounded agent can complete the task.
- Continue repository exploration after ownership, scope, and verification path are known.
- Use web search as a substitute for repository-local evidence when current external facts are not required.
- Clean-configure and rebuild the entire project after every small source or QML edit when an incremental affected-surface gate is valid.
- Invent build, test, review, or tool results.
- Hide failures or present cascading errors as independent root causes.
- Replace modules with classic include architecture.
- Treat standard-library headers as permission to replace
.cppmmodules or create project-owned headers. - Use
import std;, experimental import-std CMake gates, or standard-library module metadata in project code or generated build files. - Place standard-library headers inside a named module purview rather than its global module fragment.
- Add legacy project headers without a justified boundary.
- Add raw ownership, manual cleanup, or global mutable state casually.
- Scatter platform macros through domain logic.
- Reuse one precomposed application icon unchanged across Apple, Android, Windows, Linux, and in-application surfaces without a verified platform-composition contract.
- Put an Apple-style rounded composition or another pre-applied mask inside an Android adaptive foreground, or hide safe-zone defects with another circular or rounded plate.
- Call application icon work complete because source PNGs were generated while native targets, manifests, catalogs, installers, launchers, or packaged system contexts were not verified.
- Change public API names or unrelated subsystems without need.
- Perform broad formatting-only rewrites during functional work.
- Add non-English source comments.
- Introduce lowercase or snake_case enum-class enumerators.
- Introduce trailing-underscore or unprefixed private data members.
- Mechanically rewrite every function into trailing-return syntax when a leading return type is clearer.
- Use iostream insertion for ordinary formatted console output when
std::printorstd::printlnexpresses the operation. - Choose Qt Widgets for a new Qt UI without an explicit, documented exception.
- Silently reduce an unspecified user-facing interactive application to a CLI-only deliverable.
- Put authoritative domain or application behavior in QML JavaScript.
- Produce a generic repetitive UI without a product-specific hierarchy, interaction rationale, or verified UX states.
- Mark a QML-creatable QObject
finalwhile relying on Qt's generated type registration to construct it. - Claim that a Qt application is complete because only its core library, CLI, or headless tests built while the graphical target was disabled or unbuilt.
- Deliver a generated project as final when any requested primary surface is
NOT VERIFIEDbecause its SDK, runtime, build target, or smoke test was not available. - Claim a UI is polished or responsive without rendered inspection at minimum, standard, and wide sizes and representative content states.
- Accept accidental dead space, drifting alignment lines, clipped peripheral controls, inconsistent repeated metrics, or edge-pinned task content merely because the QML uses layout containers.
- Customize Qt Quick Controls while silently inheriting a native platform style
that rejects custom
background,contentItem,indicator, delegate, or popup implementations. - Use a QML property because a similar visual type exposes it, without verifying the exact instantiated type and declared minimum Qt version.
- Accept QML binding loops, missing-font substitution, unsupported-style customization, component-load errors, clipped popup rows, or elided primary actions because the executable still opens.
- Treat a timer-only GUI launch as proof that lazy controls and the primary interaction path are warning-free.
- Create a top-level
qml/dumping directory for a new Qt Quick repository instead of an explicitui/boundary. - Pass absolute project QML paths to
qt_add_qml_modulewithout an explicit, verified resource-alias contract, or leak the architecturalui/prefix into the runtime module namespace. - Allow a URI-derived QML output directory and an executable output file to resolve to the same path; preserve approved target/URI names and separate their output roots instead of renaming the product as a workaround.
- Report QML scanning, MOC, RCC, type registration, or cache compilation as a successful Qt build when the final executable did not link.
- Edit generated QML type registration files or omit target-local include paths
for nested
QML_ELEMENTpresentation adapters. - Treat the executable example as permission to accumulate unrelated showcase features.
- Turn human corrections into noisy one-off rules; generalize only durable lessons.
For Claude Code:
CLAUDE.mdMUST point to this file..claude/commands/workflows MUST preserve verification requirements.
For Codex:
- Repository-local skills under
.agents/skills/MUST route back to this file and the applicable task guides. - Expected file layout and commands MUST be explicit.
- Routine tasks MUST preserve the single-agent default and adaptive verification contract instead of spawning parallel review/exploration workers.
For GitHub Copilot and other agents:
- Public APIs, rule identifiers, module names, and examples MUST remain unambiguous and searchable.
All agent-specific workflows are adapters. AGENTS.md remains the source of
truth.