# Rules conformance This records how PureYAML conforms to the vendored Swift rules canon (`docs/rules-swift/`, mirror of `rules-swift`), including the few places where a canon rule does not apply to a dependency-free YAML library or conflicts with a project non-negotiable. Per `docs/rules-swift/core/rules.md`, conflicts are resolved by scope: the condition under which each rule applies is named, so exactly one governs any case. ## Conformant (applicable rules) Every applicable rule passes its acceptance check. Mechanically verified: `check-style`, `check-namespacing` (now namespace-aware, catches one-type-per-file inside `extension` blocks), `check-forbidden-patterns`, `check-changelog-touched`, `check-roadmap`, `swiftformat --lint`, `swiftlint --strict`, `swift build`, `swift test` (277 tests). Concurrency, dependency-injection, cross-platform, framework-policy, namespacing (anchor choice), folder-grouping, domain-first, and the no-shortcuts mechanical tells are all clean. ## Conflict: documentation.md Rule 1 vs the dependency-free non-negotiable `documentation.md` Rule 1 mandates a DocC catalog plus `swift-docc-plugin` as a **package dependency**. PureYAML's binding non-negotiable (`CLAUDE.md`, `AGENTS.md`) is **no external SwiftPM dependencies** (`dependencies: []`). Both cannot hold. Resolution by scope: the dependency-free invariant is the higher-stability project contract and wins. PureYAML is therefore exempt from `documentation.md` Rule 1's plugin requirement. API documentation lives in source `///` comments and `docs/`. If a maintainer later accepts a build-time plugin dependency, this exemption is revisited. ## Not applicable: domain-mismatched canon files Several canon files describe other domains (OpenAPIKit data parsing, an After-Effects-style tool, app startup, UI). Their domain-specific clauses do not bind a dependency-free YAML library; the transferable clauses are satisfied. - `parsing-rules.md`: the CSV/XML/Excel/`Codable`-record and multi-encoding `Data` clauses are N/A; the applicable parse-then-validate separation and enum-with-associated-values clauses pass. - `validation-rules.md`: the OpenAPI component-store / `$ref` / type-erasure and "validate-or-exclude every public type" coverage-gate clauses are N/A (the input model is the 5-case `Model.Value` enum, handled exhaustively, so no input is silently dropped). The applicable rule/validator/issue-path clauses pass. - `business-rules-and-constraints.md`: entirely N/A (no external services, auth, PII, or compliance surface in an offline library). - `ui/*`, `openapi-generated.md`, `exp/app-target.md`: N/A (no UI, not generated, no app target). ## Conscious deviations (intent met another way) - `core/round-trip-transformation.md` "by construction" (one `ParserPrinter`): PureYAML keeps a hand-written parser and emitter rather than a single invertible algebra, because a bijective ParserPrinter is not a faithful model of full YAML (block/flow, anchors, tags, chomping, comments; surface-to-model is many-to-one). The law it protects is enforced by a fixed-point gate: `parse(dump(parse(x))) == parse(x)` over the corpus and generated documents, plus the empty-collection adversarial regression. The round-trip law is stated in `docs/DESIGN.md`. - `code-style.md` file-naming: the repo uses folder-based bare names in some folders (`Parsing/`) and dotted `..swift` in others (`Tagged/`, `Validation/`). Both are blessed patterns; the standing convention is dotted for new namespaced files. A full rename to one pattern is deferred as disproportionate churn against the highest-stability rename surface. - `documentation.md` Rule 14 (`///` on every public decl): the non-trivial public entry points are documented; the remaining gap is the MAY-skip categories (`Codable` conformance members, `CustomStringConvertible.description`, self-describing data fields). Tracked, not blanket-filled. ## Historical commits A few commits that predate the commit-message hook have non-Conventional or over-72-character subjects. They are already on `origin/main`; rewriting pushed history is out of scope. The `commit-msg` hook now enforces Conventional Commits and the 72-character subject limit going forward.