dotty-cps-async/dotty-cps-async
59.6
Adequate · 20 September 2026
27.4k
lines of production code
Scala
primary language
1
measurement over time
What this system is
This system is a Scala 3 library and compiler plugin that enables asynchronous programming using direct-style async/await syntax by transforming code into Continuation-Passing Style (CPS). It provides a comprehensive runtime for handling asynchronous control flow, including support for collections, streams, and resource management, while integrating with various execution models like Java Loom virtual threads and JavaScript Promises. The library also extends its capabilities to support non-deterministic logic computations and structured concurrency patterns.
How it got here
2020–2021 — Scala 3 migration and CPS architecture rewrite
39 changes.
The project underwent a major migration to Scala 3, accompanied by a comprehensive rewrite of the internal CPS transformation engine to use a structured 'forest' of typed AST nodes. This period introduced extensive new features, including direct-style async/await, stack-safe monads, and JavaScript Promise interoperability, while establishing robust cross-platform test coverage.
2022–2023 — Compiler plugin and Loom support
61 changes.
This period focused on implementing and stabilizing the rssh.cps compiler plugin, which transforms async/await code into Continuation-Passing Style. Significant work included adding initial support for Java Project Loom virtual threads and expanding comprehensive test coverage across JVM, Scala Native, and Scala.js platforms.
2024–2025 — Logic monad and CPS plugin testing
16 changes.
This period focused on introducing a stack-safe logic monad with concurrent and lazy-list support, alongside comprehensive test suites for the new Logic and LogicT implementations. Significant effort was also dedicated to expanding the compiler-plugin test coverage, verifying CPS bridge rewriting, abstract method handling, and the new CpsPreprocessor functionality across various environments.
Features
Add CompletableFuture monad support and timed Future helpers
Users can now use the CPS compiler plugin with Java's CompletableFuture via the new CompletableFutureCpsMonad, which handles async mapping, flatMapping, and exception unwrapping. Additionally, new timedAwait and timedReady helpers allow Scala Futures to be awaited with a timeout, throwing a TimeoutException if the duration expires.
jvm/src/main · high confidence
Add debug settings for printing CPS-transformed code and trees
A new DebugSettings module has been introduced, defining the PrintTree and PrintCode classes. These settings provide users with the ability to enable debugging output for the CPS transformation process, allowing them to inspect the generated code structure and the resulting tree representation.
shared/src/main/scala/cps/plugin/settings · high confidence
Add runtime await implementations for Future and CompletableFuture
The library now provides built-in support for awaiting Scala's standard \Future\ and Java's \CompletableFuture\ within the CPS runtime. This is achieved by introducing new implicit definitions in the \cps.monads\ package that map these types to their respective runtime await handlers (\FutureLoomRuntimeAwait\ and \CompletableFutureRuntimeAwait\), enabling seamless async/await syntax for these common asynchronous types.
jvm-loom-addon/src/main/scala/cps/monads · high confidence
Added async shift implementations for boundary, Either, Try, and resource management
This change introduces new \AsyncShift\ implementations in the \cps.runtime.util\ package to support Scala 3 control flow and standard library types. Specifically, it adds \BoundaryAsyncShift\ to handle \break\ and \continue\ semantics via \boundary.Label\ and \boundary.Break\, \EitherAsyncShift\ for async operations on \Either\ (including left projections), \TryAsyncShift\ for async operations on \Try\ (with fixes for \recoverWith\ pattern matching and \forall\ logic), and \UsingAsyncShift\ for safe resource management using \scala.util.Using\. These utilities enable the CPS runtime to correctly transform code blocks involving these types into asynchronous computations.
shared/src/main/scala/cps/runtime/util · high confidence
Added compiler plugin entry points for async transformations
The CPS compiler plugin now includes a new \PluginEntryPoints.scala\ file that defines \cpsAsyncApply\ and \cpsAsyncStreamApply\ methods. These methods are marked with \@compileTimeOnly\ and serve as placeholders that delegate the actual async transformation logic to the compiler plugin, enabling the handling of delayed monads and async streams within the compilation process.
shared/src/main/scala/cps/plugin · high confidence
Added macro utility and test components for tree manipulation and context handling
This change introduces several new files in the macro utilities package to support internal macro implementation details. ChangeOwnerTest provides test cases for verifying that tree manipulations, such as changing owners and reassembling blocks, do not break default getter selects. CollectionHelper adds a macro to retrieve the companion IterableFactory for a given collection type. ContextualExtractor defines a trait and object for handling contextual patterns. WithOptExprProxy implements a mechanism to create proxy values for expressions, handling flags and block structures to ensure correct owner changes during macro expansion.
shared/src/main/scala/cps/macros/misc · high confidence
Added monadless syntax support for await and unlift
This change introduces a new \cps.syntax.monadless\ package that provides syntax extensions for integrating with the Monadless library. It adds a \lift\ function as a synonym for \async\ and an \unlift\ extension method on effect types, which serves as a synonym for \await\ to facilitate unwrapping values within the monadless context.
shared/src/main/scala/cps/syntax/monadless · high confidence
Async shift support for collections, options, and functions
The runtime library now provides comprehensive async shift implementations for standard Scala types, enabling asynchronous operations within CPS blocks. This includes new \AsyncShift\ classes for \ArrayOps\, \Iterable\, \Seq\, \List\, \Map\, \Option\, and \PartialFunction\, which translate methods like \map\, \flatMap\, \filter\, \fold\, and \exists\ into their asynchronous equivalents. Additionally, function composition (\andThen\, \compose\) and \WithFilter\ expressions are now supported with proper async substitution, allowing complex asynchronous data processing pipelines to be written naturally.
shared/src/main/scala/cps/runtime · high confidence
Initial build infrastructure and documentation generation setup
This change establishes the foundational build configuration for the project, introducing a custom Sbt plugin (SphinxPlugin) that integrates Sphinx documentation generation directly into the build lifecycle, ensuring HTML docs are produced and included in site mappings. It also sets up essential build plugins for publishing (sbt-pgp, sbt-ghpages), cross-compilation (Scala.js, Scala Native), API compatibility checking (sbt-mima-plugin), and code formatting (sbt-scalafmt), while defining the Sbt version as 2.0.9.
project · high confidence
Initial support for Project Loom in CPS macros
Added LoomTransform.scala, a new macro transformation component that enables the CPS library to work with Java's Project Loom (JDK 19+). This implementation intercepts await calls within the macro expansion phase, transforming them to integrate with the Loom runtime API via CpsRuntimeAwait, allowing asynchronous code to leverage virtual threads.
shared/src/main/scala/cps/macros/loom · high confidence
Introduce JSFuture for bridging Scala async code with JavaScript Promises
A new JSFuture class is added to the JavaScript platform, allowing Scala async/await blocks to execute using JavaScript Promises while remaining compatible with Scala's Future API. This enables developers to expose asynchronous Scala functions as JavaScript Promises via @JSExport and to use standard async/await syntax within those functions. The implementation includes implicit conversions between JSFuture, scala.concurrent.Future, and js.Promise, facilitating seamless interoperability between the Scala CPS monad and the JavaScript runtime.
js/src/main/scala/cps/monads/jsfuture · high confidence
Introduce async stream support with AsyncIterator and asyncStream macro
Users can now process asynchronous data streams using the new \AsyncIterator\ trait, which provides standard functional operations like \map\, \flatMap\, \filter\, and \mapTry\ for handling async sequences. Additionally, the \asyncStream\ macro enables the creation of custom async generators via an emitter pattern, allowing code to yield values asynchronously using \out.emit(value)\ within an async block.
shared/src/main/scala/cps/stream · high confidence
Introduce rssh.cps compiler plugin for CPS transformation
Adds the \rssh.cps\ compiler plugin, which implements a multi-phase transformation pipeline to convert code using \CpsDirect\ context parameters into Continuation-Passing Style (CPS). The plugin introduces several compiler phases: \PhaseSelectAndGenerateShiftedMethods\ identifies methods with CPS context parameters and generates shifted method variants for higher-order functions; \PhaseCps\ performs the core AST transformation of async blocks and apply sites; and \PhaseChangeSymbolsAndRemoveScaffolding\ updates symbol denotations and removes internal scaffolding code after erasure. It also includes helper utilities for type manipulation (\CpsTransformHelper\), scaffolding management (\Scaffolding\), and async kind tracking (\AsyncKind\), enabling users to write asynchronous code using direct context parameters that are automatically transformed by the compiler.
compiler-plugin/src/main · high confidence
Introduce stack-safe logic monad with concurrent and lazy-list support
The library now provides a new \CpsLogicMonad\ typeclass for backtracking and non-deterministic logic computations, along with concrete implementations for both synchronous \LazyList\ and asynchronous concurrent environments. Users can now leverage stack-safe operations like \limit\, \mObserveOne\, and \mFoldLeftWhile\ without risking stack overflows, and can run logic computations concurrently using the new \CpsConcurrentLogicMonad\ which supports parallel evaluation via \parOr\ and conversion to async streams.
logic/shared/src/main · high confidence
Introduction of direct-style async/await and comprehensive AsyncShift support
This change introduces the \CpsDirect\ opaque type and \asynchronized\/\reifed\ functions, enabling a direct-style programming mode where computations are automatically wrapped in monadic form without explicit \async\ blocks. It also adds a comprehensive \AsyncShift\ typeclass system with given instances for standard library collections (List, Map, Seq, Option, Either, Try, etc.), allowing \await\ expressions inside higher-order methods like \map\ and \flatMap\. Additionally, new typeclasses \CpsPreprocessor\ and \CpsRuntimeAwait\ are added to support advanced use cases like monad-specific preprocessing and runtime-based await handling for high-order functions.
shared/src/main/scala/cps · high confidence
New Loom-based runtime await implementations
The JVM Loom addon now includes specific runtime await implementations for Java's CompletableFuture and Scala's Future, leveraging virtual threads via the blocking construct. This change introduces the LoomRuntimeAwait trait and its concrete implementations (CompletableFutureRuntimeAwait and FutureLoomRuntimeAwait) to handle asynchronous operations more efficiently within the CPS runtime.
jvm-loom-addon/src/main/scala/cps/runtime · high confidence
New SIP-22 compatibility interface via FutureAsync
A new \FutureAsync\ object has been added to the \cps.compat\ package to provide a SIP-22-compatible interface for asynchronous code. Users can now import \cps.compat.FutureAsync\ (or the \sip22\ alias) to access \async\ and \await\ methods that leverage the \FutureContext\ and \CpsAsyncMonad\ abstractions, replacing the previous requirement to import \cps.\*\ for this specific compatibility mode.
shared/src/main/scala/cps/compat · high confidence
New cps.syntax package with for-comprehension and short await support
A new \cps.syntax\ package has been introduced, providing \ForSyntax\ and a short \!\ operator for \await\. \ForSyntax\ enables for-comprehension syntax on generic monad-wrapped values by extending them with \flatMap\ and \map\ methods that rely on a \CpsMonad\ context. Additionally, the package defines a transparent inline \unary\_!\ extension method that serves as a concise synonym for \await\, useful when automatic coloring is not supported or the default syntax is too verbose; this requires both a \CpsMonadContext\ and a \CpsMonadConversion\ to be available.
shared/src/main/scala/cps/syntax · high confidence
New macro forest implementation for CPS transformation
The CPS macro system now uses a new 'forest' architecture in \shared/src/main/scala/cps/macros/forest\ to transform TASTy trees. This introduces dedicated transformers for core language constructs, including \ApplyTransform\ for method calls, \AwaitTreeTransform\ for \await\ expressions, \BlockTransform\ for code blocks, \IfTransform\ for conditionals, and \MatchTreeTransform\ for pattern matching. It also adds specialized handling for control flow, such as \BreaksTreeTransform\ for \break\/\breakable\ and \NonLocalReturnsTreeTransform\ for \returning\/\throwReturn\, ensuring these are correctly shifted within async contexts.
shared/src/main/scala/cps/macros/forest · high confidence
New stack-safe monad implementations for Identity, Either, Iterable, and TailRec
The library now provides dedicated CPS monad instances for several standard Scala types, each featuring a stack-safe \tailRecM\ implementation to prevent stack overflow during deep recursive computations. Users can now use \cps\ syntax with \Identity\ (via \CpsIdentityMonad\), \Either\ (via \EitherCpsMonad\ and \EitherCpsTryMonad\ with configurable error mapping), generic \Iterable\ collections (via \IterableCpsMonad\), and \scala.util.control.TailCalls.TailRec\ (via \TailRecCpsMonad\). These additions expand the range of data structures that can be seamlessly integrated into asynchronous control-flow blocks without risking runtime stack errors.
shared/src/main/scala/cps/monads · high confidence
Support for awaiting JavaScript Promises via Future conversion
The library now allows users to await JavaScript Promises directly within CPS blocks. This is achieved by introducing a \CpsMonadConversion\ instance in the \cps.monads\ package that automatically converts \js.Promise\ values to Scala \Future\s, enabling seamless interoperability with existing CPS await logic. Additionally, a stub for \FutureRuntimeAwait\ has been added to prepare for future integration with Scala 3.8's native \js.await\, though it remains disabled until deeper CPS transformation integration is resolved.
js/src/main/scala/cps/monads · high confidence
Support for break and non-local return in async blocks
The runtime now supports using \break\ and \return\ clauses inside asynchronous code blocks. This is implemented via new \BreaksAsyncShift\ and \NonLocalReturnsAsyncShift\ components that correctly handle the underlying control exceptions, ensuring that non-local exits behave as expected within CPS-transformed async contexts.
shared/src/main/scala/cps/runtime/util/control · high confidence
Architecture
Compiler plugin refactors CPS transformation into a structured 'forest' of typed AST nodes
The compiler plugin's internal architecture has been restructured to use a dedicated 'forest' package containing a hierarchy of typed transformation nodes (CpsTree, SyncCpsTree, AsyncCpsTree, etc.) and specialized transformers (ApplyTransform, InlinedTransform). This change replaces the previous flat or ad-hoc tree handling with a robust, type-safe representation of the Continuation-Passing Style (CPS) transformed Abstract Syntax Tree, enabling more precise handling of async boundaries, direct contexts, and nested inlining within the plugin.
repository · high confidence
Behavioural changes
Added scaffolding files to enforce compiler plugin usage
New scaffolding files (AdopDenotations, Brackets, DeferredShift, requiringCpsCompilerPlugin) were added to the shared plugin module. These files define functions annotated with @compileTimeOnly to ensure that the dotty-cps-async compiler plugin is enabled; if the plugin is missing, users will receive compile-time errors when attempting to use direct context functions or other CPS-specific APIs.
shared/src/main/scala/cps/plugin/scaffolding · high confidence
Improved macro transformation robustness and error handling
The macro infrastructure now includes a new TransformUtil module that enhances how the compiler handles code transformations. This update introduces a workaround for a Scala 3 compiler issue (scala3\#17445) to preserve Select name kinds during tree transformations, preventing symbol mismatch errors. It also adds logic to correctly track and resolve owners within CPS trees and improves the handling of non-local returns. These changes result in more stable compilation and better positioning of error messages when using the async macros.
shared/src/main/scala/cps/macros/common · high confidence
Introduces two-stage async transformation with optional preprocessing
The \Async\ macro now employs a two-stage approach for transforming asynchronous code. In the first stage, a transparent inline check looks for an optional \CpsPreprocessor\ typeclass; if one is present, the expression is preprocessed before the second stage (the actual CPS transformation) runs. This allows users to inject custom preprocessing logic into async blocks without modifying the core transformation logic. The implementation also distinguishes between a compiler-plugin path and a pure-macro path, ensuring that preprocessing is handled correctly in both modes.
shared/src/main/scala/cps/macros · high confidence
New macro scopes for CPS application argument handling
The macro system now includes new internal scopes (ApplicationHelper, MethodParamsDescriptorScope) to manage method parameter descriptors and argument building for CPS applications. These changes introduce support for detecting CpsDirect types and handling context parameters, which are prerequisites for the upcoming CpsDirect experimental feature.
shared/src/main/scala/cps/macros/forest/application · medium confidence
Project governance, build configuration, and documentation overhaul
This release introduces significant structural and documentation updates to the project. The license has been switched to Apache 2.0, accompanied by the addition of a CITATION.cff file for proper academic referencing and a CODE\_OF\_CONDUCT.md to establish community standards. Build reliability is improved by adding a .sbtopts file that configures the JVM with 8GB of heap memory and G1GC to prevent garbage collection thrashing during Scala Native builds, alongside a .scalafmt.conf for consistent code formatting. The repository now includes a .gitignore file to exclude IDE and build artifacts, and the README has been updated with detailed usage highlights, links to presentations, and a humanitarian appeal.
(repo-wide) · high confidence
Refactor internal CPS transformation architecture
The internal implementation of the CPS transformation engine has been restructured. The previous monolithic \Async\ object and associated result types (\CpsExprResult\, \CpsChunk\) have been removed in favor of a new modular architecture using \CpsExpr\, \CpsChunkBuilder\, and \TransformationContext\. This change consolidates transformation logic, simplifies the handling of async expressions and value discarding, and removes obsolete traits like \AsyncMetaMonad\ and \FutureMetaMonad\ from the public API surface, streamlining how the library processes asynchronous code.
src/main/scala/cps · high confidence
Refactored CPS forest transformers to use CpsChunkBuilder
The internal implementation of the CPS transformation forest has been refactored to replace the previous \CpsExprResult\-based approach with a new \CpsChunkBuilder\ abstraction. This change consolidates how asynchronous code blocks, function applications, and value definitions are constructed, simplifying the transformation logic for blocks, applies, and identifiers while ensuring consistent handling of async monads across the codebase.
src/main/scala/cps/forest · high confidence
Test coverage
Add Scala.js test case for async/await with compiler plugin; Added CLI test cases for Scala 3.7.1 compatibility and macro assertions; Added JVM tests for LogicT monad and stack-safety guarantees; Added JVM tests for stack trace reporting accuracy; Added JVM-only test infrastructure for structured concurrency and cancellation; Added JVM-specific test utilities for futures and timers; Added JVM-specific tests for ComputationBound, async channels, and Future integration; Added Scala.js test suite for CPS async/await and JS interop; Added compiler-plugin test cases for async dynamic, Future range filtering, and stream fold/scan operations; Added comprehensive test coverage for ComputationBound async transformations; Added dummy test configuration for macro testing; Added inline async function test case; Added test case for async calls within async blocks; Added test case for concurrent async fetch operations; Added test case for inline direct context functions; Added test case for nested async operations; Added test cases for CPS plugin bridge rewriting; Added test cases for CPS plugin with higher-order functions; Added test cases for async/await patterns and extension methods; Added test cases for compiler crash and test runner logic; Added test cases for compiler-plugin error detection when CPS plugin is missing; Added test cases for direct context inclusion in CpsMonadContextInclusion; Added test cases for do-while loop transformation; Added test cases for exception handling in async CPS blocks; Added test cases for lazy effect execution in the compiler plugin; Added test cases for match expressions with async selectors; Added test cases for shifted extension methods and async control flow; Added test coverage for AsyncList and AsyncIterator operations; Added test coverage for CPS Loom transformations and runtime behaviors; Added test coverage for CPS plugin features; Added test coverage for async stream merging, exception handling, and timed awaits; Added test coverage for concurrent example patterns; Added test data for CPS await functionality; Added test data for JSDirect-style async compilation; Added test data for Try/catch/finally support in the CPS compiler plugin; Added test data for abstract method handling in CPS plugin; Added test data for direct and inline direct reference types; Added test data for direct-context reference transformations; Added test file for CPS transformation utilities; Added test file for GSoC 2023 snippets; Added test file for Gopherlike CPS patterns; Added test for Using resource management in async computations; Added test for async try-catch in match expressions; Added test for direct context extensions in async context; Added test for direct reference extension in CPS plugin; Added test for exception handling in try blocks within async computations; Added test for fold operation on shifted functions with F\[\_\] result; Added test for inline extensions in direct context functions; Added test for inlining direct functions within macros; Added test for lambda typed as partial functions in iterable operations; Added test for nested async/await with Option monad; Added test for non-local returns in ComputationBound async blocks; Added test for resource interop with PureEffect; Added test for resource management with context inclusion; Added test helper for MyList data structure; Added test infrastructure and examples for the chessboard domain; Added test infrastructure and test cases for the gopherlike2 CPS implementation; Added test infrastructure and unit tests for the PureEffect monad; Added test infrastructure for compiler plugin validation; Added test infrastructure for validating CpsPreprocessor behavior; Added test scaffolding for Process-like CPS context; Added test suite for CPS gopher-like concurrency primitives; Added test suite for LogicT monad transformer implementations; Added test suite for SIP-22 async compatibility; Added test suite for compiler plugin support of Java Loom virtual threads; Added test suite for logic unification1 components; Added test suite for logical unification2 infrastructure; Added test suite for the Logic module's monad transformers and backtracking implementations; Added test suite for the Logic monad and LogicStream; Added test utilities for JS platform; Added test utilities for exception handling and time-based operations; Added test utilities for time-based operations in Scala Native; Added tests for CPS context resolution and deferred cleanup; Added tests for CPS-integrated LazyStream monad; Added tests for ComputationBound runtime await behavior on JVM Loom; Added tests for CpsPreprocessor functionality; Added tests for DBIO print behavior and Free monad structure; Added tests for FutureWithDeadline and DeadlineContext; Added tests for Scala Native CPS runtime support; Added tests for compiler plugin integration and direct CPS execution; Added tests for select loop simplification and context handling; Added utest-like assertion macro and test suite; Compiler plugin test: deny assignment of CpsDirect values; Expanded test coverage for CPS transformation features; New compiler-plugin test infrastructure and test suite.
Dependencies
Upgrade to Scala 3.3.8 and Scala.js 1.22.0
The build system has been upgraded to use Scala 3.3.8 as the primary compiler version, replacing the previous 0.21.0-RC1 snapshot. Additionally, the Scala.js ecosystem dependencies have been updated, specifically bumping the Scala.js linker and the Node.js environment plugin to version 1.22.0 and 1.6.0 respectively, ensuring compatibility with the newer Scala version and modern tooling.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Baseline
- First survey — no prior run to compare against. CAI 60.
Lenses
- Code Health 78
- Architecture 97
- Maturity 46
- Readiness 63
- Security 75
Changes since last survey
- 300 commits — 255 feature/other, 45 fixes
By area
- (root) — 71 commits
- shared/src — 70 commits
- (repo) — 30 commits
- docs/BasicUsage.rst — 24 commits
- compiler-plugin/src — 20 commits
- native/src — 12 commits
- project/plugins.sbt — 12 commits
- logic/shared — 11 commits
- project/build.properties — 9 commits
- compiler-plugin/testdata — 7 commits
- docs/changelogs — 7 commits
- js/src — 6 commits
- .github/workflows — 4 commits
- jvm/src — 4 commits
- docs/References.md — 2 commits
- tests-cli/t2026_02_10_default_getter — 2 commits
- .vscode/settings.json — 1 commit
- docs/DeprecatedFeatures.rst — 1 commit
- docs/HighOrderFunctions.rst — 1 commit
- docs/Integrations.rst — 1 commit
Notable commits
- fix: jvm: fix possible data reca in AsyncList.take
- fix: native: fixed shared access to bufer in AsynList.take
- fix: #99 -- fixed case when opaque type have no type arguments
- fix: attempt to fix potential race condition
- fix: attempt to recreate incomplete bug-reports in progress
- fix: berrer formatting fix
- fix: fix #105
- fix: fix #112
- fix: fix 3.5.0 warnings
- fix: fixed #100
- fix: fixed #107
- fix: fixed compilation of compil;er-plugin after upgrade to scala-js 1.20
- fix: fixed determination of incorrect owner
- fix: fixed incorrect ordering of events in TestTimer queue in scala-native
- fix: fixed incorrect temporary vla generartion for direct-context-arg
- fix: fixed js version in compilerplugin test
- fix: fixed possible read from finished stream in native
- fix: fixed potential bug in js stream, when we reading from finished stream
- fix: revert to 3.3.3 in master
- fix: Add CpsLazyT monad transformer and fix observer fold stack safety
- …and 280 more
Architecture
- 0 containers · 1 bounded contexts · 0 dependency edges (baseline)
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
dotty-cps-async/dotty-cps-async was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 20 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 4fe67d96ee125199843e4d1709ee8c2373f24cae — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-b51f968c9b10.