PureXML/third_party/rules-swift/CHANGELOG.md

20 KiB

Changelog

All notable changes to this rule set are documented here. This project follows Semantic Versioning.

[Unreleased]

[2.14.0] - 2026-11-02

Changed

  • concurrency.md: where a synchronous API must guard shared state (a protocol requirement, a synchronous engine), the rule now names Synchronization.Mutex (SE-0433) beside actor: it is Sendable without @unchecked, and the state is reachable only inside withLock. The gate's escape-hatch and NSLock checks are unchanged.

[2.13.0] - 2026-10-31

Changed

  • ui/flowspec.md: the verb list now includes ambient and rotate, the engine is described with AsyncStepRegistry and AsyncScenarioRunner for an async pre-UI door, and a new DO says to load hand-edited scenarios with ScenarioLoader.loadValidated.
  • ui/flowspec.md, ui/pom.md, README.md: the FlowSpec link points at its Codeberg home, https://codeberg.org/Mihaela/FlowSpec, instead of GitHub, where it no longer lives.

[2.12.0] - 2026-10-28

Added

  • ui/pane-layout.md: a section on one set of panes on a Mac, an iPad and an iPhone with SuperSplit, ten rules: one view per pane role with many containers (a phone gets the same views as pages, not a split); the arrangement is a value that names the saved layout; a pane's share and its least size are different limits and the least wins; the Mac hides the problem by being wide, so test every pane at its least width; the divider is the edge of a pane and its frame in the accessibility tree is what a test asserts against; the card's clip loses what does not fit, so pair it with a test and a picture; maximize is the way to give one pane the whole area; a platform view needs an owner that lives as long as the pane; chrome as glass is a background; and three levels of test (the pure layout, the real window's frames, a picture of each arrangement).

[2.11.0] - 2026-10-28

Added

  • ui/pane-layout.md: eight rules from an iPad and an iPhone Duo with a real editor, each a defect that shipped: the split sizes a pane and the content does not; an optional part is decided by a measurement (a tip in ViewThatFits widened a 240 point pane to 296); a header fits the narrowest pane; columns are decided by the room the parts need and not by a fixed 1000 points (a 13 inch iPad upright is 1032); a layout is saved for each way the device is held; the whole area for the document; a platform view is updated by its inputs and keeps its controller; and a picture of each arrangement is a deliverable. With two acceptance commands.
  • iphone-duo.md: a section of what was observed on the simulator, kept apart from what Apple documents: a vertical toolbar over a vertical tab bar on the closed display, a fold that rebuilt the navigation and lost the screen, and the tools that work (Device Hub only; screenshots are black unless closed).

[2.10.0] - 2026-10-28

Changed

  • iphone-duo.md: availability is now stated from the SDK's own Swift interface and headers, with two facts the Apple pages do not carry (the macOS SDK of Xcode 27.1 is 27.0 and lacks the 27.1 symbols; members of a type listed for a platform can be unavailable there, as horizontalOnly, verticalPreferred, ToolbarOverflowMenu and the compression behaviors are on macOS), the per-API versions of the bar APIs are corrected (visibilityPriority iOS 27.0 and macOS 26.1, ToolbarOverflowMenu iOS 27.0), and a new rule says the newer APIs are reached through one layer that checks the SDK and the OS separately and gives each a fallback (the Forwards package).

[2.9.0] - 2026-10-28

Added

  • iphone-duo.md: the foldable iPhone, from Apple's own pages (the Human Interface Guidelines page, the documentation of Preparing your app for iPhone Duo, ArrangementView and reserved regions, five Tech Talks and the WWDC26 UIKit session; none is in the Cupertino corpus yet). The app is resized by a fold while it runs, so: the size is read on every change from the view and never from the screen or the launch; layout is decided by size classes and the space, not by idiom, orientation or UIScreen.main; state lives above anything a size class swaps; reserved regions, arrangement views and the hinge are iOS 27.1 and used in their places (regions and arrangements for layout, the hinge for effects); the system's bars carry the controls; safe areas are not symmetric; a second window is a request that can fail; and every pose and every change between poses is tested. States what Apple has not documented (the transition, state across a fold, scene behavior on a fold, sizes), and that the claim of support is made only after the transition test has been run.

[2.8.0] - 2026-10-28

Changed

  • accessibility.md: the Mac is audited too, and what it found is in the rules (a divider with no role is a slider on the Mac and an adjustable action on iOS; a list, an outline and a placeholder-only text field are named; a ruler beside text is hidden). A finding is checked against the pixels of the picture before it is listed, and one the pixels contradict is recorded as a false positive with its measured ratio. The ledger may name element kinds, a finding with no element is let pass only by an entry with no label, and the macOS SDK's missing audit types are named by their raw values. Rule 14 now has a built answer (pages instead of columns at accessibility sizes, decided by a tested pure function) and says for which screens it was looked at.

[2.7.0] - 2026-10-27

Added

  • accessibility.md: text through text styles (Dynamic Type) with the app's own zoom applied as a shift of it, every control named by what it does and never by its symbol's default name, 28 point tap targets, an alternative for every gesture (named actions, adjustable elements), the name and actions on the element a person reaches and not on a container, contrast as arithmetic (4.5 to 1, Light, Dark, Increase Contrast), announcements, Reduce Motion, layer-drawn UI exposed element by element, and a UI framework's core that describes while each surface must declare that it realizes it. The audit (performAccessibilityAudit) runs in UI tests and fails for a finding that is not on a ledger of known findings, each with its reason. Written from the Cupertino corpus (the Human Interface Guidelines pages Accessibility and VoiceOver, Performing accessibility testing, the audit's documentation) and from what the audit measured on an iPad app: 300 findings on five screens, 118 of them hit areas, 69 Dynamic Type, 59 contrast. States what is not established: the layout at the largest accessibility size, VoiceOver on a device, and the audit on the Mac.

[2.6.0] - 2026-10-27

Added

  • help.md: an app's help is written once, in one JSON file, and every platform's help is made from it. The Mac carries an Apple Help Book (the two Info.plist keys, the book's structure and indexes, generated and checked against the file) and leaves the Help menu to the system; an iPad and an iPhone have an in-app help sheet in a Help menu of the toolbar and in the menu bar of an iPad, and the version in the Settings app through a Settings bundle; tips (TipKit) point at the first thing to do and go when it is done. Each platform is told in its own words. Ships a build-checked acceptance list and tests; what was observed on a built app is stated as observed, and the Help Book format, which the Cupertino corpus does not hold, is marked as such.

Changed

  • versioning.md rule 14: the stamp phase names the built Info.plist as an input file, so that it runs after the system writes the plist; observed on a clean build, where the stamp was lost without it.

[2.5.0] - 2026-10-18

Added

  • app-logging.md: every shipped app has one given recorder, entries that are facts and never the person's content, every intent and state change logged, a Developer menu in Debug and Beta builds only, and a report (log window, snapshot, optional content) made on the person's request and sent only by their choice. Ships a build-checked acceptance list and tests.
  • crash-and-state-reporting.md: MetricKit and StateReporting used behind canImport and availability, the system's crash reports as a second door, one crash seen through both doors kept once, the call stack never in the log, states joined to the log. Claims about delivery and the return of states are stated at the strength they were shown.
  • versioning.md rule 14: the stamp in an Xcode app target is a post-build script phase.

[2.4.0] - 2026-10-17

Added

  • versioning.md: the version is written once, in a VERSION file, and read as Semantic Versioning 2.0.0 (a value outside the grammar stops the build); the store's short version is the core only; the build number is the first-parent commit count of the release branch, which grows by one per commit, never restarts, and names one commit; both reach the code through a generated file from a build-tool plugin whose command names its inputs (VERSION and the git HEAD files); a shallow clone or a missing history is refused, never defaulted to 1; CI fetches full history; release history is append-only; a store build comes from the release branch with a clean tree; a second upload of one commit needs its own number (the dotted form is stated as not established until one upload orders it). Each rule names its basis as documented, observed, or design. Ships six acceptance commands and the tests, including a regeneration check in a throwaway clone.

[2.3.0] - 2026-10-14

Added

  • app-intents.md: App Intents live in one adapter target; an intent in a package is declared by an AppIntentsPackage that each app and extension includes; dependencies are registered, not passed; every string a person sees is a localized resource that names the package bundle and is handed to the system unresolved, so Siri and Shortcuts resolve it in their own language; an interpolated sentence keeps its plural forms (one and other in English and German, one, few and other in Croatian); a sentence is one key, not translated fragments. Each rule names its basis as documented or observed. Ships five acceptance commands, a test recipe for the languages (set locale on a copy of the resource, because String(localized:bundle:locale:) reads the process's language), and the statement that a unit test does not prove Shortcuts lists the intent in each language.

[2.2.0] - 2026-10-14

Added

  • ui/appuikit.md: imperative AppKit and UIKit renderers, features, and app shells import the cross-framework layer and name its AppUI* types, never an NS or UI type or a direct SDK import; a missing alias or helper is added to the layer first. Ships an acceptance check (two greps to promote to a self-tested gate). appkit-views.md and uikit-views.md point to it.

[2.1.1] - 2026-10-11

Fixed

  • exp/common-mistakes.md: the test-target pairing command filtered swift package describe output on the target type regular, which that output never uses (it says library), so the command checked no library target and passed vacuously. It now selects library and executable, and the rule says how to confirm the command selects something.

[2.1.0] - 2026-10-11

Added

  • testing.md: an exception to "mocks live in the test target" for test-support targets that several test targets share, because SwiftPM does not let a test target depend on another. It names four conditions (declared in a checked-in table, not published, not shipped except by a named allowlist, mechanically checked) and ships a runnable acceptance check.

[2.0.0] - 2026-07-11

Added

  • A complete local repository gate covering leak, namespacing, filenames, relative links, rule structure, changelog, version bumps, and fault injection.
  • A checked-in five-label tracker manifest plus scheduled issue-body and label-drift auditing against Codeberg.
  • An exact vendored core license, allowing the upstream README and every changed core rule to remain byte-identical after synchronization.
  • A byte-for-byte core-sync gate with a planted divergent-vendor negative control.
  • Negative controls for commit-message rejection, breaking-change notation, missing Markdown links, leaked prose, namespacing violations, missing rule proof sections, missing changelog/version bumps, stale issue bodies, label drift, and consumer freshness.
  • Acceptance checks for the remaining binding parsing, namespacing, planning, design, dependency-injection, migration, and package-testing rules.

Changed

  • Breaking: Renamed the non-conventional CONVENTIONS.md overview to conventions.md; inbound repository links now use the lowercase path.
  • Breaking: Reconciled the target graph, DI seams, namespace exception, protocol-creation threshold, test-framework scope, and dependency direction into one non-contradictory architecture. Consumers must review these rules before updating their freshness marker.

Fixed

  • Made forbidden-byte matching portable across POSIX shells so Linux sh does not treat hexadecimal escape text inside the gates as a leak.
  • Replaced the unavailable hosted priority-label action with a repository-owned Forgejo API script and deterministic add, remove, and no-op fixtures.
  • Renamed the consumer workflow from conformance to freshness so its name matches its actual proof: it compares the shared-rules version marker and does not claim semantic conformance.
  • Strengthened the commit hook to enforce Conventional Commit types, the 72-column limit, automated-author attribution prohibitions, and the em-dash rule.
  • Made missing SwiftFormat or SwiftLint fail instead of silently weakening a commit that contains Swift files.
  • Repaired stale repository-relative links and narrowed the shared-path exception in the folder-grouping rule so it no longer contradicts the default mandate.
  • Scoped the Apple framework policy to Apple client/UI targets so it no longer contradicts the Swift Linux, Windows, WASM, and server rules.
  • Normalized ExtremePackaging terminology and examples to the repository's one-package/many-targets architecture, removing impossible nested manifests.
  • Classified the repository's VERSION marker as a conventional root filename and repaired the file-naming rule's non-Conventional commit example.
  • Removed the dead GitHub workflow badge and documented the Forgejo fallback and local source of verification evidence.
  • Moved the shell-only consumer freshness job from an unproven macos label to the repository's demonstrated ubuntu-latest Forgejo runner label.
  • Flattened the sole consumer workflow template from the one-file templates/ directory to rules-freshness.yml at the repository root.

[1.1.2]

  • scripts/leak-gate.sh (.build exclusion): all three scans and the file count now exclude .build/ directories. Fetched dependency checkouts carry their own vendor names, absolute-path examples, and em dashes in documentation the repo does not own and git does not track; scanning them made the gate permanently red on any consumer with resolved dependencies, which trains readers to ignore it. Found by a rule-canon audit on 2026-07-04 where the gate failed consumers solely on .build/checkouts/ markdown.

[1.1.1]

  • scripts/leak-gate.sh (charter-file exception): the vendor-name scan now excludes the two agent charter files at the repository ROOT, where the filename is the tool's addressing interface (function, not attribution). Root only; the same name in any nested file still fails, and the exception is fault-injection tested downstream. A permanently red gate trains readers to ignore it, which is worse than no gate.

[1.1.0]

  • documentation.md Rule 0 (DocC scope): DocC is packages-only (never apps), and only for packages that are public OR heavily used. Non-qualifying packages skip the DocC catalog entirely. Narrows the former "every project" framing.

A conformance pass brought the repository closer to agreement with its own rules.

Added

  • Vendored core/oracle-first.md from the engineering-discipline upstream: build the answer key (Oracle, comparison law, failure report, unsupported-case classification, parity gate) before any system or new correctness surface, including the "a codified expectation is a witness, not a verdict" guidance. Indexed in core/README.md and the README core-spine list.
  • Acceptance check sections for the rule files that lacked one (per core/rules.md): core/first-principles-analysis, core/systematic-debugging, concurrency, linux-server, ui/native-per-platform, and the ExtremePackaging set (exp/build-performance, exp/common-mistakes, exp/critical-rules, exp/dependency-management, exp/implementation-patterns, exp/package-swift).
  • Namespacing gate scripts/check-namespacing.sh (one non-private top-level type per file, per code-style.md), wired into the pre-commit hook and the gates CI workflow.
  • GitHub issue forms (feature, bug) with required status/priority/complexity fields, a pull-request template, and an issue-priority labeler workflow, per core/git-discipline.md.
  • README CI and license badges, and a License section.

Fixed

  • Broken cross-reference links in CONVENTIONS.md and code-style.md.

Changed

  • Label set trimmed to the brutal-minimum per core/git-discipline.md (added epic and priority: high; removed the decorative stock labels), with the Rule 2.3 semantic color palette.
  • Synced the vendored core spine to the engineering-discipline upstream: core/systematic-debugging.md gains "Rule 6: Debugging against a differential or parity oracle" and two anti-patterns; core/verification.md and core/git-discipline.md gain the GitHub-hosted vs self-hosted CI runner escalation rule; core/testing-discipline.md gains the hosted-first runner note; core/proof-discipline.md and core/no-shortcuts-first-principles.md gain oracle-first.md cross-references. The local acceptance-check sections in core/first-principles-analysis.md and core/systematic-debugging.md are preserved.

[1.0.0] - 2026-06-15

Initial public release of the Swift domain rules, built on the engineering-discipline core spine (vendored in core/).

Added

  • Where an app starts: business-rules-and-constraints (MANDATORY first artifact: business rules as explicit checkable statements, plus the constraints that bound them, which REST services, what compliance, which auth model) and domain-first (MANDATORY: start at the domain and business rules, framework-free and headless-provable; the UI framework is the last, reversible, and plural choice).
  • Swift craft: code-style, namespacing, dependency-injection, concurrency, cross-platform, linux-server, testing, formatting-and-linting, documentation, documentation-search, package-structure, package-architecture, package-import-contract, shared-protocols.
  • UI (ui/): pre-ui-layer (the display-less model seam, MANDATORY: Domain + Surface, one perform(Intent) channel, renderers the only UI import; one model drives the SwiftUI, AppKit, and UIKit renderers at once, both the architecture's payoff and a comparison instrument), pom (Page Object Model for UI tests), flowspec (declarative UI scenarios via the FlowSpec package), plus three renderers over the one model (swiftui-views, uikit-views, appkit-views), view-models, components, colors, fonts.
  • Parsing and validation: parsing-rules and validation-rules (the OpenAPIKit idiom). Validation requires every public type to be validated or excluded with a reason, enforced mechanically.
  • Apple-platform stance: framework-policy (Apple-only mandate), openapi-generated.
  • Drop-in kit: .gitignore, .swiftformat, .swiftlint.yml, .pre-commit-config.yaml, and .githooks/ (a pre-commit format-and-lint hook and a commit-msg attribution/em-dash check).
  • Vendored core/ spine: the cross-cutting engineering-discipline rules (incl. round-trip-transformation).
  • Dual license: prose under CC BY 4.0, code under MIT.