In my opinion defextend is fine the way it is, it has its similarities to CLOS's defmethod, which I would avidly abuse in my earlier lisp days.
The positive thing about adding a tagged predicate dispatch table, if implemented into "isa", would be the illusion of any object being a particular "type", provided it satisfies the predicate. In reality, the true type of the object would be cons or sym or whatever its value is.
One simple idea: The int/num difference could theoretically be moved into arc codespace via deftag. Primarily leave the number type "num" internally, but deduce if a number is an "int" via the tags table.
Example:
(deftag int
(and (isa _ 'num)
(is _ (round _))))
(isa 1.5 'int) => nil
(isa 1 'int) => t
One cool thing you could do is define tags for something like an object descriptor, or a class. Store whatever you need in cons cells, along with maybe a symbol at the head named "class:" or something, with "slots:" or "methods:" in that class. This could easily be checked if a particular cons resembles a "[class]" structured cons via a predicate, right? So deftag a predicate for "class". Then check if your object is a class-structed cons via "isa".