anchor.diff:  
   (defparameter *apology-regex* (cl-ppcre:create-scanner "^(Colleen:\\s*)?(Sorry for|I apologize for|I'm sorry for)\\s+(breaking|violating|breaching|not minding|disregarding|saying)?\\s*(the\\s+)?(\\w+).*" :case-insensitive-mode T))
   (define-handler (privmsg-event event) ()
  -  (let ((name-format (format NIL "~a/~a" (name (server event)) (nick event)))
  -        (server-format (format NIL "~a/~a" (name (server event)) (channel event))))
  -    (unless (cl-ppcre:register-groups-bind (NIL NIL NIL NIL name) (*apology-regex* (message event))
  -              (let ((rule (gethash name (rules module))))
  -                (when (and rule (find server-format (active-on rule) :test #'string-equal))
  -                  (if (gethash name-format (users-on-probation rule))
  -                      (progn
  -                        (v:info :rules "~a is apologizing for ~a" (nick event) name)
  -                        (remhash name-format (users-on-probation rule))
  -                        (respond event (rule-format event rule (probation rule) (apology-msg rule))))
  -                      (respond event "~a: You don't need to apologize for ~a, silly!" (nick event) (name rule))))
  -                T))
  -      
  -      (loop for rule being the hash-value of (rules module)
  -         if (and (find server-format (active-on rule) :test #'string-equal)
  -                 (cl-ppcre:scan (regex rule) (string-downcase (message event))))
  -         do 
  -           (let ((probation-count (gethash name-format (users-on-probation rule))))
  -             (unless probation-count
  -               (setf probation-count (probation rule)))
  -             (setf probation-count (1- probation-count))
  -
  -             (if (> 0 probation-count)
  -                 (let ((message (rule-format event rule probation-count (punish-msg rule))))
  -                   (v:warn :rules "~a violated rule ~a" (nick event) (name rule))
  -                   (remhash name-format (users-on-probation rule))
  -                   (case (rule-type rule)
  -                     (:KICK (irc:kick (channel event) (nick event) :reason message))
  -                     (:BAN (irc:channel-mode (channel event) "+b" :extra (nick event))
  -                           (irc:kick (channel event) (nick event) :reason message))
  -                     (:KILL (irc:kill (nick event) message))
  -                     (:MUTE (irc:channel-mode (channel event) "-v" :extra (nick event))
  -                            (respond event message))
  -                     (:SCOLD (respond event message))
  -                     (:REWARD (respond event message))
  -                     (T (respond event "WTF?"))))
  -                 (progn
  -                   (v:warn :rules "~a breached rule ~a" (nick event) (name rule))
  -                   (setf (gethash name-format (users-on-probation rule)) probation-count)
  -                   (respond event (rule-format event rule probation-count (breach-msg rule))))))))))
  +  (when (not (find (format NIL "~a/~a" (string-upcase (name (server event))) (string-upcase (nick event)))
  +                   (whitelist module) :test #'string-equal))
  +    (let ((name-format (format NIL "~a/~a" (name (server event)) (nick event)))
  +          (server-format (format NIL "~a/~a" (name (server event)) (channel event))))
  +      (unless (cl-ppcre:register-groups-bind (NIL NIL NIL NIL name) (*apology-regex* (message event))
  +                (let ((rule (gethash name (rules module))))
  +                  (when (and rule (find server-format (active-on rule) :test #'string-equal))
  +                    (if (gethash name-format (users-on-probation rule))
  +                        (progn
  +                          (v:info :rules "~a is apologizing for ~a" (nick event) name)
  +                          (remhash name-format (users-on-probation rule))
  +                          (respond event (rule-format event rule (probation rule) (apology-msg rule))))
  +                        (respond event "~a: You don't need to apologize for ~a, silly!" (nick event) (name rule))))
  +                  T))
  +        
  +        (loop for rule being the hash-value of (rules module)
  +           if (and (find server-format (active-on rule) :test #'string-equal)
  +                   (cl-ppcre:scan (regex rule) (string-downcase (message event))))
  +           do 
  +             (let ((probation-count (gethash name-format (users-on-probation rule))))
  +               (unless probation-count
  +                 (setf probation-count (probation rule)))
  +               (setf probation-count (1- probation-count))
  +
  +               (if (> 0 probation-count)
  +                   (let ((message (rule-format event rule probation-count (punish-msg rule))))
  +                     (v:warn :rules "~a violated rule ~a" (nick event) (name rule))
  +                     (remhash name-format (users-on-probation rule))
  +                     (case (rule-type rule)
  +                       (:KICK (irc:kick (channel event) (nick event) :reason message))
  +                       (:BAN (irc:channel-mode (channel event) "+b" :extra (nick event))
  +                             (irc:kick (channel event) (nick event) :reason message))
  +                       (:KILL (irc:kill (nick event) message))
  +                       (:MUTE (irc:channel-mode (channel event) "-v" :extra (nick event))
  +                              (respond event message))
  +                       (:SCOLD (respond event message))
  +                       (:REWARD (respond event message))
  +                       (T (respond event "WTF?"))))
  +                   (progn
  +                     (v:warn :rules "~a breached rule ~a" (nick event) (name rule))
  +                     (setf (gethash name-format (users-on-probation rule)) probation-count)
  +                     (respond event (rule-format event rule probation-count (breach-msg rule)))))))))))
   
   (define-group rules)
   
  
positive.code: (in-package :org.tymoonnext.colleen.mod.rules)
  
  (define-module rules () 
    ((%rules :initform (make-hash-table :test 'equalp) :accessor rules))
    (:documentation "Primitive rule enforcement module."))
  
  (defparameter *types* '(:KICK :BAN :KILL :MUTE :SCOLD :REWARD))
  
negative.code:                      :apology-msg (gethash "apology-msg" object)
                       :punish-msg (gethash "punish-msg" object)
                       :active-on (gethash "active-on" object))))
          (v:info :rules "Loaded ~d rules." (hash-table-count data)))))
    (setf (whitelist rules) (config-tree :rules :whitelist)))
  
  (defmethod stop ((rules rules))
    (with-open-file (stream *save-file* :direction :output :if-exists :supersede :if-does-not-exist :create)
      (yason:encode (rules rules) stream)
      (v:info :rules "Saved ~d rules." (hash-table-count (rules rules))))
    (setf (config-tree :rules :whitelist) (whitelist rules)))
  
  (defun rule-format (event rule probation-count message)
    (format-message event message
  