From 0c35131baed83543fefafebdbbe65d06cdce9cfc Mon Sep 17 00:00:00 2001 From: Nick Anderson Date: Thu, 11 Jun 2026 16:01:22 -0500 Subject: [PATCH] Documented the classes promise cancel attribute Added a reference section for the new 'cancel' attribute of classes promises, which undefines the promiser class when its class expression evaluates to true. Notes the evaluation-when-already-defined behaviour, hard-class protection, and mutual exclusion with the class-defining attributes. Ticket: CFE-4686 Co-Authored-By: Claude Opus 4.8 (1M context) --- .../reference/promise-types/classes.markdown | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/content/reference/promise-types/classes.markdown b/content/reference/promise-types/classes.markdown index f6f517e20..07d164ad8 100644 --- a/content/reference/promise-types/classes.markdown +++ b/content/reference/promise-types/classes.markdown @@ -100,6 +100,60 @@ If an expression contains a mixture of different object types that need to be ANDed together, this list form is more convenient than providing an expression. +### cancel + +**Description:** Undefine the promiser class when this string expression of +classes evaluates to true + +Undefine the class on the left-hand side if the class expression on the +right-hand side evaluates to true. This is the inverse of +[`expression`][classes#expression]: where `expression` defines a class, +`cancel` removes one that is already defined. + +The right-hand side is an ordinary class expression, so it may be a class name, +a compound expression, or the return value of a function that returns a class, +such as `fileexists()`. + +Unlike the class-defining attributes, a `cancel` promise is evaluated **even +when the promiser class is already defined** — that is precisely when it has +work to do. If the cancel expression is true the class is undefined. If the +expression is false, or the class is not currently defined, the promise makes +no change. Reserved hard classes (such as `linux` or `cfengine`) cannot be +undefined and are left in place with a warning. + +`cancel` is mutually exclusive with the class-defining attributes (`expression`, +`and`, `or`, `not`, `xor`, `dist`, `select_class`); combining it with any of +them is an `Irreconcilable constraints` error. + +**Type:** `class` + +**Allowed input range:** `[a-zA-Z0-9_!@@$|.()\[\]{}:]+` + +**Example:** + +```cf3 {skip TODO} +classes: + + # Undefine 'maintenance' once the maintenance window has passed + "maintenance" cancel => "maintenance_window_over"; + + # Undefine 'have_config' if the file no longer exists + "have_config" cancel => not(fileexists("/etc/myapp.conf")); +``` + +**Notes:** + +A class may be defined again later in the same agent execution (for example by +a class-defining promise evaluated in a later pass). `cancel` therefore does not +guarantee that a class stays undefined for the remainder of the run; it +undefines the class at the point the promise is evaluated. + +**History:** + +- Introduced in CFEngine 3.28.0. + +**See also:** [`expression` classes attribute][classes#expression], [`cancel_kept`, `cancel_repaired` and `cancel_notkept` in classes body][Promise types#cancel_kept] + ### dist **Description:** Generate a probabilistic class distribution