You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2021/03/04 07:23:24 UTC

[isis] branch ISIS-2444 updated: ISIS-2564: rationalizing mixee interfaces

This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch ISIS-2444
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/ISIS-2444 by this push:
     new de1a88b  ISIS-2564: rationalizing mixee interfaces
de1a88b is described below

commit de1a88b2931f7d8a98705c6aa5462aefdc58bee5
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Thu Mar 4 07:22:25 2021 +0000

    ISIS-2564: rationalizing mixee interfaces
---
 .../index/mixins/dto/hooks/Dto_see-also.adoc}      |  26 +--
 .../hooks/Object_downloadLayoutXml_see-also.adoc}  |  12 +-
 .../layout/hooks/Object_openRestApi_see-also.adoc} |  16 +-
 .../hooks/Object_rebuildMetamodel_see-also.adoc}   |  11 +-
 .../system/hooks/HasInteractionId_see-also.adoc}   |  13 +-
 .../updates/hooks/WithUpdatedAt_usage-notes.adoc}  |  35 ++--
 .../hooks/WithUpdatedByAndAt_usage-notes.adoc}     |  10 +-
 .../updates/hooks/WithUpdatedBy_usage-notes.adoc}  |  13 +-
 .../hooks/GridService_020-examples-and-usage.adoc  |   2 +-
 .../hooks/Execution_020-examples-and-usage.adoc    |   2 +-
 .../hooks/JaxbService_020-examples-and-usage.adoc  |   6 +-
 .../LayoutService_020-examples-and-usage.adoc      |   2 +-
 .../impl/mixins/HasUniqueId_command.adoc           |   2 +-
 .../applib-classes/pages/layout/menubars.adoc      |   3 -
 .../applib-classes/pages/mixees-and-mixins.adoc    |  96 +++++++++++
 .../roles-mixins-contributees/contributee.adoc     |  38 +----
 .../pages/roles-mixins-contributees/mixins.adoc    |  58 ++++++-
 .../roles-mixins-contributees/mixins/Dto.adoc      |  66 -------
 .../roles-mixins-contributees/mixins/Object.adoc   | 115 -------------
 .../mixins/Persistable.adoc                        |  59 -------
 .../roles/HoldsUpdatedAt.adoc                      |  46 -----
 .../roles/HoldsUpdatedBy.adoc                      |  21 ---
 .../applib-classes/partials/module-nav.adoc        |   3 +-
 .../modules/ROOT/pages/2020/2.0.0-M4/relnotes.adoc |   2 +-
 .../pages/overview/types-of-domain-objects.adoc    |   2 +-
 .../modules/fun/pages/ui/object-layout.adoc        |   4 +-
 .../modules/fun/pages/view-models/UNUSED-dto.adoc  | 190 ---------------------
 .../org/apache/isis/applib/mixins/dto/Dto.java     |  22 +++
 .../DtoMixinConstants.java}                        |   7 +-
 .../isis/applib/mixins/dto/Dto_downloadXml.java    |  18 +-
 .../isis/applib/mixins/dto/Dto_downloadXsd.java    |  35 ++--
 .../applib/mixins/layout/LayoutMixinConstants.java |  16 +-
 .../mixins/layout/Object_downloadLayoutXml.java    |  10 +-
 .../applib/mixins/layout/Object_openRestApi.java   |   6 +-
 .../mixins/layout/Object_rebuildMetamodel.java     |   7 +-
 .../metamodel/Object_downloadMetamodelXml.java     |   9 +-
 .../mixins/metamodel/Object_objectIdentifier.java  |   4 +-
 .../applib/mixins/metamodel/Object_objectType.java |   4 +-
 .../isis/applib/mixins/security}/HasUsername.java  |  22 ++-
 .../system}/DomainChangeRecord.java                |  24 ++-
 .../DomainChangeRecord_openTargetObject.java       |  10 +-
 .../applib/mixins/system/HasInteractionId.java     |  12 +-
 .../applib/mixins/system/HasTransactionId.java     |  60 +++++++
 .../isis/applib/mixins/updates/OnUpdatedAt.java    |   8 +-
 .../isis/applib/mixins/updates/OnUpdatedBy.java    |  17 +-
 .../applib/mixins/updates/OnUpdatedByAndAt.java    |  15 +-
 .../RepresentsInteractionMemberExecution.java      |  42 -----
 .../isis/applib/services/command/Command.java      |  12 +-
 .../isis/applib/services/iactn/Interaction.java    |  23 +--
 .../isis/applib/services/iactn/Sequence.java       |  36 ----
 .../isis/applib/services/iactn/SequenceType.java   |  53 ++++++
 .../services/publishing/spi/EntityChanges.java     |  10 +-
 .../isis/applib/services/xactn/TransactionId.java  |  19 ++-
 .../applib/util/schema/InteractionDtoUtils.java    |   2 +-
 .../isis/commons/having/HasUpdatedByAndAt.java     |  25 ---
 .../interaction/session/InteractionSession.java    |  40 ++---
 .../core/interaction/session/IsisInteraction.java  |  14 +-
 .../action/ActionAnnotationFacetFactory.java       |  32 ++--
 .../DomainObjectAnnotationFacetFactory.java        |   8 +-
 .../property/PropertyAnnotationFacetFactory.java   |  10 +-
 .../metamodel/inspect/Object_inspectMetamodel.java |   4 +-
 .../grid/bootstrap3/GridSystemServiceBS3.java      |  64 +++----
 .../specloader/specimpl/ObjectMemberAbstract.java  |  12 +-
 .../action/ActionAnnotationFacetFactoryTest.java   |  12 +-
 ...notationFacetFactoryTest_commandPublishing.java |   8 +-
 ...tationFacetFactoryTest_executionPublishing.java |   8 +-
 .../DomainObjectAnnotationFacetFactoryTest.java    |  20 +--
 .../interaction/InteractionDtoFactoryDefault.java  |   6 +-
 .../wrapper/WrapperFactoryDefault.java             |  94 +++++-----
 .../changetracking/ChangingEntitiesFactory.java    |   6 +-
 .../EntityPropertyChangeFactory.java               |   8 +-
 .../changetracking/SimpleChangingEntities.java     |  10 +-
 .../changetracking/events/TimestampService.java    |  20 +--
 .../commandlog/impl/CommandSubscriberForJdo.java   |   4 +-
 .../extensions/commandlog/impl/jdo/CommandJdo.java |  18 +-
 .../impl/mixins/HasUniqueId_command.java           |  14 +-
 .../mixins/HasUsername_recentCommandsByUser.java   |   2 +-
 .../impl/mixins/Object_recentCommands.java         |   8 +-
 .../secondary/fetch/CommandFetcher.java            |   2 +-
 .../jobcallables/ReplicateAndRunCommands.java      |   4 +-
 .../adoc/modules/audit-trail/pages/about.adoc      |   2 +-
 .../secman/api/user/ApplicationUser.java           |   2 +-
 .../secman/model/dom/user/HasUsername_open.java    |  10 +-
 .../mixins/Persistable_datanucleusIdLong.java      |  13 +-
 .../mixins/Persistable_datanucleusVersionLong.java |  14 +-
 .../Persistable_datanucleusVersionTimestamp.java   |  14 +-
 .../mixins/Persistable_downloadJdoMetadata.java    |   8 +-
 .../testdomain/conf/Configuration_headless.java    |  28 +--
 .../testdomain/jdo/entities/JdoProductComment.java |  12 +-
 .../testdomain/jpa/entities/JpaProductComment.java |  14 +-
 .../wicket/viewer/mixins/Object_clearHints.java    |  25 +++
 91 files changed, 862 insertions(+), 1089 deletions(-)

diff --git a/antora/components/userguide/modules/fun/pages/view-models/UNUSED-dto.adoc b/antora/components/refguide-index/modules/applib/pages/index/mixins/dto/hooks/Dto_see-also.adoc
similarity index 90%
copy from antora/components/userguide/modules/fun/pages/view-models/UNUSED-dto.adoc
copy to antora/components/refguide-index/modules/applib/pages/index/mixins/dto/hooks/Dto_see-also.adoc
index 0e7843c..68ae699 100644
--- a/antora/components/userguide/modules/fun/pages/view-models/UNUSED-dto.adoc
+++ b/antora/components/refguide-index/modules/applib/pages/index/mixins/dto/hooks/Dto_see-also.adoc
@@ -1,15 +1,12 @@
-= DTOs
-
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
 :page-partial:
 
 
-WARNING: TODO: v2: move this to "beyond the basics"
 
-JAXB view models can also be used as DTOs.
-The examples in this section uses the DTO for `ToDoItem`.
+== Example
 
-This DTO is defined as follows:
+The examples in this section uses the DTO for a `ToDoItem` entity.
+The DTO is defined as follows:
 
 [source,java]
 ----
@@ -62,7 +59,7 @@ public class ToDoItemV1_1 implements Dto {                          // <.>
 
 
 [#versioning]
-== Versioning
+=== Versioning
 
 The whole point of using DTOs (in Apache Isis, at least) is to define a formal contact between two inter-operating but independent applications.
 Since the only thing we can predict about the future with any certainty is that one or both of these applications will change, we should version DTOs from the get-go.
@@ -183,8 +180,15 @@ This is an example of the link:https://leanpub.com/camel-design-patterns[VETRO p
 In our case we focus on the validation (to determine the nature of the inbound message, ie which action was invoked), and the enrich (callback to obtain a DTO with additional information required by the consumer).
 ====
 
-The (non-ASF) link:https://platform.incode.org[Incode Platform^]'s publishmq module provides an out-of-the-box solution of this design.
-It provides an implementation of the xref:refguide:applib:index/services/publishing/spi/ExecutionSubscriber.adoc[ExecutionSubscriber], but which simply publishes instances of xref:refguide:schema:ixn.adoc[InteractionDto] to an ActiveMQ queue.
-Camel (or similar) can then be hooked up to consume these events from this queue, and use a processor to parse the action memento to determine what has changed on the source system.
-Thereafter, a subsequent Camel processor can then call back to the source - via the xref:vro:ROOT:about.adoc[Restful Objects viewer] - to enrich the message with additional details using a DTO.
+//The (non-ASF) link:https://platform.incode.org[Incode Platform^]'s publishmq module provides an out-of-the-box solution of this design.
+//It provides an implementation of the xref:refguide:applib:index/services/publishing/spi/ExecutionSubscriber.adoc[ExecutionSubscriber], but which simply publishes instances of xref:refguide:schema:ixn.adoc[InteractionDto] to an ActiveMQ queue.
+//Camel (or similar) can then be hooked up to consume these events from this queue, and use a processor to parse the action memento to determine what has changed on the source system.
+//Thereafter, a subsequent Camel processor can then call back to the source - via the xref:vro:ROOT:about.adoc[Restful Objects viewer] - to enrich the message with additional details using a DTO.
+
+
+
+== See also
+
+* xref:refguide:applib:index/mixins/dto/Dto_downloadXml.adoc[Dto_downloadXml]
+* xref:refguide:applib:index/mixins/dto/Dto_downloadXsd.adoc[Dto_downloadXsd]
 
diff --git a/antora/components/refguide/modules/applib-classes/pages/i18n/TranslatableString_usage-notes.adoc b/antora/components/refguide-index/modules/applib/pages/index/mixins/layout/hooks/Object_downloadLayoutXml_see-also.adoc
similarity index 78%
copy from antora/components/refguide/modules/applib-classes/pages/i18n/TranslatableString_usage-notes.adoc
copy to antora/components/refguide-index/modules/applib/pages/index/mixins/layout/hooks/Object_downloadLayoutXml_see-also.adoc
index 1f96710..f22c1a9 100644
--- a/antora/components/refguide/modules/applib-classes/pages/i18n/TranslatableString_usage-notes.adoc
+++ b/antora/components/refguide-index/modules/applib/pages/index/mixins/layout/hooks/Object_downloadLayoutXml_see-also.adoc
@@ -1,17 +1,11 @@
-[[TranslatableString]]
-= `TranslatableString`
-
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
 :page-partial:
 
-WARNING: TODO: this content has not yet been updated for v2.0
-
-The `TranslatableString` utility class ...
-
-//
-See also xref:userguide:btb:i18n.adoc[user guide, i18n].
 
 
+== See also
 
+* the structure of the xref:userguide:fun:ui.adoc#object-layout[layout XML] is described in the user guide.
 
+* xref:refguide:applib:index/services/layout/LayoutService.adoc[LayoutService]
 
diff --git a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees.adoc b/antora/components/refguide-index/modules/applib/pages/index/mixins/layout/hooks/Object_openRestApi_see-also.adoc
similarity index 74%
rename from antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees.adoc
rename to antora/components/refguide-index/modules/applib/pages/index/mixins/layout/hooks/Object_openRestApi_see-also.adoc
index 332c235..376a280 100644
--- a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees.adoc
+++ b/antora/components/refguide-index/modules/applib/pages/index/mixins/layout/hooks/Object_openRestApi_see-also.adoc
@@ -1,9 +1,13 @@
-[#roles-mixins-and-contributees]
-= Roles, Mixins and Contributees
-
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
+:page-partial:
+
+
+
+== See also
+
+* xref:vro:ROOT:about.adoc[Restful Objects] viewer
 
+* xref:refguide:applib:index/services/bookmark/BookmarkService.adoc[BookmarkService]
++
+is used by the mixin to build the URL
 
-include::roles-mixins-contributees/roles.adoc[leveloffset=+1]
-include::roles-mixins-contributees/mixins.adoc[leveloffset=+1]
-include::roles-mixins-contributees/contributee.adoc[leveloffset=+1]
diff --git a/antora/components/refguide/modules/applib-classes/pages/i18n.adoc b/antora/components/refguide-index/modules/applib/pages/index/mixins/layout/hooks/Object_rebuildMetamodel_see-also.adoc
similarity index 78%
copy from antora/components/refguide/modules/applib-classes/pages/i18n.adoc
copy to antora/components/refguide-index/modules/applib/pages/index/mixins/layout/hooks/Object_rebuildMetamodel_see-also.adoc
index f5cacea..c23e487 100644
--- a/antora/components/refguide/modules/applib-classes/pages/i18n.adoc
+++ b/antora/components/refguide-index/modules/applib/pages/index/mixins/layout/hooks/Object_rebuildMetamodel_see-also.adoc
@@ -1,11 +1,12 @@
-[#i18n-support]
-= i18n support
-
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
 :page-partial:
 
 
-The `org.apache.isis.applib.services.i18n` package contains a single class to support i18n.
 
+== See also
+
+* xref:refguide:applib:index/services/metamodel/MetaModelService.adoc[MetaModelService]
 
-include::i18n/TranslatableString.adoc[leveloffset=+1]
+* xref:refguide:applib:index/services/grid/GridService.adoc[GridService]
++
+called to invalidate its caches.
diff --git a/antora/components/refguide/modules/applib-classes/pages/i18n/TranslatableString_usage-notes.adoc b/antora/components/refguide-index/modules/applib/pages/index/mixins/system/hooks/HasInteractionId_see-also.adoc
similarity index 69%
rename from antora/components/refguide/modules/applib-classes/pages/i18n/TranslatableString_usage-notes.adoc
rename to antora/components/refguide-index/modules/applib/pages/index/mixins/system/hooks/HasInteractionId_see-also.adoc
index 1f96710..556e8f9 100644
--- a/antora/components/refguide/modules/applib-classes/pages/i18n/TranslatableString_usage-notes.adoc
+++ b/antora/components/refguide-index/modules/applib/pages/index/mixins/system/hooks/HasInteractionId_see-also.adoc
@@ -1,17 +1,14 @@
-[[TranslatableString]]
-= `TranslatableString`
-
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
 :page-partial:
 
-WARNING: TODO: this content has not yet been updated for v2.0
-
-The `TranslatableString` utility class ...
 
-//
-See also xref:userguide:btb:i18n.adoc[user guide, i18n].
 
+== See also
 
+Some of the extension/mapping modules that have entities that implement this mixee are:
 
+* xref:security:audit-trail:about.adoc[Auditer] module: `AuditEntry` entity
+* xref:extensions:command-log:about.adoc[Command Log] module: `CommandJdo` entity
+* xref:mappings:outbox-publisher:about.adoc[Outbox Publisher] module: `OutboxEvent` entity
 
 
diff --git a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/roles/Timestampable.adoc b/antora/components/refguide-index/modules/applib/pages/index/mixins/updates/hooks/WithUpdatedAt_usage-notes.adoc
similarity index 63%
rename from antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/roles/Timestampable.adoc
rename to antora/components/refguide-index/modules/applib/pages/index/mixins/updates/hooks/WithUpdatedAt_usage-notes.adoc
index 1c79488..bb8b139 100644
--- a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/roles/Timestampable.adoc
+++ b/antora/components/refguide-index/modules/applib/pages/index/mixins/updates/hooks/WithUpdatedAt_usage-notes.adoc
@@ -1,28 +1,37 @@
-[[Timestampable]]
-= `Timestampable`
-
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
 :page-partial:
 
 
-The `Timestampable` role interface is a convenience that combines the xref:applib-classes:about.adoc#HoldsUpdatedAt[HoldsUpdatedAt] and xref:applib-classes:about.adoc#HoldsUpdatedBy[HoldsUpdatedBy] interfaces.
-It is defined as:
 
-// TODO: v2: use include::[]
+
+
+== Alternative approaches
+
+An alternative way to maintain a timestamp is to use JDO's `@Version` annotation.
+With this approach, it is the JDO/DataNucleus that maintains the version, rather than the framework's `TimestampService`.
+
+For example:
 
 [source,java]
 ----
-public interface Timestampable
-    extends HoldsUpdatedAt, HoldsUpdatedBy {
+@javax.jdo.annotations.Version(
+        strategy=VersionStrategy.DATE_TIME,
+        column="version")
+public class Customer {
+    ...
+    public java.sql.Timestamp getVersionSequence() {
+        return (java.sql.Timestamp) JDOHelper.getVersion(this);
+    }
 }
 ----
 
-The interface no additional methods of its own.
+== See also
 
+* xref:refguide:applib:index/services/clock/ClockService.adoc[ClockService]
++
+used to obtain the current time.
 
+* xref:refguide:applib:index/mixins/updates/OnUpdatedBy.adoc[OnUpdatedBy]
 
-== Alternatives
+* xref:refguide:applib:index/mixins/updates/OnUpdatedByAndAt.adoc[OnUpdatedByAndAt]
 
-An alternative way to maintain a timestamp is to use JDO's `@Version` annotation.
-With this approach, it is the JDO/DataNucleus that maintains the version, rather than the framework's `TimestampService`.
-See xref:applib-classes:about.adoc#HoldsUpdatedBy[HoldsUpdatedBy] for further details.
diff --git a/antora/components/refguide/modules/applib-classes/pages/i18n.adoc b/antora/components/refguide-index/modules/applib/pages/index/mixins/updates/hooks/WithUpdatedByAndAt_usage-notes.adoc
similarity index 81%
rename from antora/components/refguide/modules/applib-classes/pages/i18n.adoc
rename to antora/components/refguide-index/modules/applib/pages/index/mixins/updates/hooks/WithUpdatedByAndAt_usage-notes.adoc
index f5cacea..adec954 100644
--- a/antora/components/refguide/modules/applib-classes/pages/i18n.adoc
+++ b/antora/components/refguide-index/modules/applib/pages/index/mixins/updates/hooks/WithUpdatedByAndAt_usage-notes.adoc
@@ -1,11 +1,11 @@
-[#i18n-support]
-= i18n support
-
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
 :page-partial:
 
 
-The `org.apache.isis.applib.services.i18n` package contains a single class to support i18n.
 
+== See also
+
+* xref:refguide:applib:index/mixins/updates/OnUpdatedAt.adoc[OnUpdatedAt]
+
+* xref:refguide:applib:index/mixins/updates/OnUpdatedBy.adoc[OnUpdatedBy]
 
-include::i18n/TranslatableString.adoc[leveloffset=+1]
diff --git a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/roles.adoc b/antora/components/refguide-index/modules/applib/pages/index/mixins/updates/hooks/WithUpdatedBy_usage-notes.adoc
similarity index 70%
rename from antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/roles.adoc
rename to antora/components/refguide-index/modules/applib/pages/index/mixins/updates/hooks/WithUpdatedBy_usage-notes.adoc
index d2e1ad8..1f7706f 100644
--- a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/roles.adoc
+++ b/antora/components/refguide-index/modules/applib/pages/index/mixins/updates/hooks/WithUpdatedBy_usage-notes.adoc
@@ -1,14 +1,15 @@
-= Roles
-
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
 :page-partial:
 
 
-The interfaces listed in this chapter are role interfaces; they define a contract for the framework to interact with those domain objects that implement these interfaces.
 
+== See also
+
+* xref:refguide:applib:index/services/user/UserService.adoc[UserService]
++
+used to obtain the current user.
 
+* xref:refguide:applib:index/mixins/updates/OnUpdatedAt.adoc[OnUpdatedAt]
 
+* xref:refguide:applib:index/mixins/updates/OnUpdatedByAndAt.adoc[OnUpdatedByAndAt]
 
-include::roles/HoldsUpdatedAt.adoc[leveloffset=+1]
-include::roles/HoldsUpdatedBy.adoc[leveloffset=+1]
-include::roles/Timestampable.adoc[leveloffset=+1]
diff --git a/antora/components/refguide-index/modules/applib/pages/index/services/grid/hooks/GridService_020-examples-and-usage.adoc b/antora/components/refguide-index/modules/applib/pages/index/services/grid/hooks/GridService_020-examples-and-usage.adoc
index efd6a29..fe3260e 100644
--- a/antora/components/refguide-index/modules/applib/pages/index/services/grid/hooks/GridService_020-examples-and-usage.adoc
+++ b/antora/components/refguide-index/modules/applib/pages/index/services/grid/hooks/GridService_020-examples-and-usage.adoc
@@ -12,7 +12,7 @@ Dynamic reloading is disabled in production mode.
 
 == See also
 
-This service is called by xref:refguide:applib:index/services/layout/LayoutService.adoc[LayoutService], exposed in the UI through `LayoutServiceMenu` (to download the layout XML as a zip file for all domain objects) and the xref:applib-classes:roles-mixins-contributees/mixins.adoc#Object[downloadLayoutXml()] mixin (to download the layout XML for a single domain
+This service is called by xref:refguide:applib:index/services/layout/LayoutService.adoc[LayoutService], exposed in the UI through `LayoutServiceMenu` (to download the layout XML as a zip file for all domain objects) and the xref:applib-classes:mixins.adoc#java-lang-object[downloadLayoutXml()] mixin (to download the layout XML for a single domain
 object).
 
 This service delegates to:
diff --git a/antora/components/refguide-index/modules/applib/pages/index/services/iactn/hooks/Execution_020-examples-and-usage.adoc b/antora/components/refguide-index/modules/applib/pages/index/services/iactn/hooks/Execution_020-examples-and-usage.adoc
index 17af303..69233b7 100644
--- a/antora/components/refguide-index/modules/applib/pages/index/services/iactn/hooks/Execution_020-examples-and-usage.adoc
+++ b/antora/components/refguide-index/modules/applib/pages/index/services/iactn/hooks/Execution_020-examples-and-usage.adoc
@@ -12,7 +12,7 @@ This supports several use cases:
 
 ** they enable profiling of the running application (which actions are invoked then most often, what is their response time)
 
-** if auditing is configured (using xref:refguide:applib:index/services/publishing/spi/EntityPropertyChangeSubscriber.adoc[EntityPropertyChangeSubscriber]), they provide better audit information, since the parent xref:refguide:applib:index/services/iactn/Interaction.adoc[Interaction] captures the 'cause' of an interaction and can be correlated to the audit records (the "effect" of the interaction) by way of the xref:applib-classes:roles-mixins-contributees/contributee.adoc#HasUniqueId[un [...]
+** if auditing is configured (using xref:refguide:applib:index/services/publishing/spi/EntityPropertyChangeSubscriber.adoc[EntityPropertyChangeSubscriber]), they provide better audit information, since the parent xref:refguide:applib:index/services/iactn/Interaction.adoc[Interaction] captures the 'cause' of an interaction and can be correlated to the audit records (the "effect" of the interaction) by way of the xref:applib-classes:mixins.adoc[uniqueId] that both share.
 
 
 == See also
diff --git a/antora/components/refguide-index/modules/applib/pages/index/services/jaxb/hooks/JaxbService_020-examples-and-usage.adoc b/antora/components/refguide-index/modules/applib/pages/index/services/jaxb/hooks/JaxbService_020-examples-and-usage.adoc
index 7011001..d4bc8df 100644
--- a/antora/components/refguide-index/modules/applib/pages/index/services/jaxb/hooks/JaxbService_020-examples-and-usage.adoc
+++ b/antora/components/refguide-index/modules/applib/pages/index/services/jaxb/hooks/JaxbService_020-examples-and-usage.adoc
@@ -9,9 +9,5 @@
 This service is provided as a convenience for applications, but is also used internally by the framework to marshall xref:refguide:applib-ant:XmlRootElement.adoc[@XmlRootElement]-annotated
 xref:userguide:fun:overview.adoc#view-models[view models].
 
-The functionality to download XML and XSD schemas is also exposed in the UI through mixins of the xref:applib-classes:roles-mixins-contributees/mixins.adoc#Dto[Dto] interface.
+The functionality to download XML and XSD schemas is also exposed in the UI through mixins of the xref:applib-classes:mixins.adoc#Dto[Dto] interface.
 
-
-== See also
-
-* xref:refguide:applib:index/services/jaxb/IsisSchemas.adoc[IsisSchemas]
diff --git a/antora/components/refguide-index/modules/applib/pages/index/services/layout/hooks/LayoutService_020-examples-and-usage.adoc b/antora/components/refguide-index/modules/applib/pages/index/services/layout/hooks/LayoutService_020-examples-and-usage.adoc
index 2019b24..b6638cc 100644
--- a/antora/components/refguide-index/modules/applib/pages/index/services/layout/hooks/LayoutService_020-examples-and-usage.adoc
+++ b/antora/components/refguide-index/modules/applib/pages/index/services/layout/hooks/LayoutService_020-examples-and-usage.adoc
@@ -7,7 +7,7 @@
 
 The service's functionality is exposed in the UI through a mixin (per object) and a menu action (for all objects):
 
-* the xref:applib-classes:roles-mixins-contributees/mixins.adoc#Object[`Object` mixin] provides the ability to download the XML layout for any domain object (entity or view model).
+* the xref:applib-classes:mixins.adoc#java-lang-object[Object] mixin provides the ability to download the XML layout for any domain object (entity or view model).
 
 * the `LayoutServiceMenu` provides the ability to download all XML layouts as a single ZIP file (in any of the three styles).
 
diff --git a/antora/components/refguide-index/modules/extensions/pages/index/commandlog/impl/mixins/HasUniqueId_command.adoc b/antora/components/refguide-index/modules/extensions/pages/index/commandlog/impl/mixins/HasUniqueId_command.adoc
index 47f0171..72c8238 100644
--- a/antora/components/refguide-index/modules/extensions/pages/index/commandlog/impl/mixins/HasUniqueId_command.adoc
+++ b/antora/components/refguide-index/modules/extensions/pages/index/commandlog/impl/mixins/HasUniqueId_command.adoc
@@ -11,7 +11,7 @@ This mixin contributes a `command` action to any (non-command) implementation of
 class HasUniqueId_command {
   @Inject
 CommandJdoRepository commandServiceRepository;
-  HasUniqueId_command(final HasUniqueId hasUniqueId)
+  HasUniqueId_command(final HasUniqueId hasInteractionId)
   CommandJdo act()
   boolean hideAct()     // <.>
   String disableAct()
diff --git a/antora/components/refguide/modules/applib-classes/pages/layout/menubars.adoc b/antora/components/refguide/modules/applib-classes/pages/layout/menubars.adoc
index e08b493..f33c04a 100644
--- a/antora/components/refguide/modules/applib-classes/pages/layout/menubars.adoc
+++ b/antora/components/refguide/modules/applib-classes/pages/layout/menubars.adoc
@@ -49,7 +49,6 @@ The xref:vw:ROOT:about.adoc[Wicket viewer] renders a separator between each sect
 +
 consisting of one or many actions (``ServiceActionLayoutData``s)
 
-
 == Components
 
 The service action class reside in the `org.apache.isis.applib.layout.component` package, consisting of just:
@@ -62,8 +61,6 @@ which correspond to the xref:refguide:applib:index/annotation/ActionLayout.adoc[
 This is similar to `ActionLayoutData` (of the xref:applib-classes:layout.adoc[object layout] classes), however it also identifies the domain service to which it belongs.
 (This isn't required for the object layouts because the owner in that case is implicit).
 
-
-
 == Link
 
 The link classes reside in the `org.apache.isis.applib.layout.links` package, and consist of just the `Link` class.
diff --git a/antora/components/refguide/modules/applib-classes/pages/mixees-and-mixins.adoc b/antora/components/refguide/modules/applib-classes/pages/mixees-and-mixins.adoc
new file mode 100644
index 0000000..8dc3538
--- /dev/null
+++ b/antora/components/refguide/modules/applib-classes/pages/mixees-and-mixins.adoc
@@ -0,0 +1,96 @@
+= Mixees and Mixins
+
+:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
+:page-partial:
+
+
+This section defines a number of "mixee" interfaces that define a contract for some framework-defined mixins.
+
+[TIP]
+====
+See the xref:userguide:fun:overview.adoc#mixins[fundamentals user guide] for a discussion of mixins.
+====
+
+
+[#java-lang-object]
+== java.lang.Object
+
+The framework provides a number of mixins that contributes to `java.lang.Object` (in other words, to every domain object):
+
+* core
+** xref:refguide:applib:index/mixins/layout/Object_downloadLayoutXml.adoc[Object_downloadLayoutXml]
+** xref:refguide:applib:index/mixins/layout/Object_downloadLayoutXml.adoc[Object_downloadLayoutXml]
+
+* Wicket viewer:
+** xref:refguide:viewer:index/wicket/viewer/mixins/Object_clearHints.adoc[Object_clearHints]
+
+
+
+[[Dto]]
+== Dto
+
+JAXB view models can optionally implement the xref:refguide:applib:index/mixins/dto/Dto.adoc[Dto] interface.
+Two mixins contribute to this interface:
+
+* xref:refguide:applib:index/mixins/dto/Dto_downloadXml.adoc[Dto_downloadXml]
+* xref:refguide:applib:index/mixins/dto/Dto_downloadXsd.adoc[Dto_downloadXsd]
+
+These allow the view model/DTO to be seriailized, respectively, as XML and as the XSD schema for said XML.
+
+
+[[Persistable]]
+== Persistable
+
+
+All JDO domain entities implement the DataNucleus `Persistable` role interface as a result of the enhancer process (the fully qualified class name is `org.datanucleus.enhancement.Persistable`).
+
+Using this, the following mixins (actions and properties) are available for all JDO entities:
+
+* xref:refguide:persistence:index/jdo/datanucleus/mixins/Persistable_downloadJdoMetadata.adoc[Persistable_downloadJdoMetadata] (action)
+* xref:refguide:persistence:index/jdo/datanucleus/mixins/Persistable_datanucleusIdLong.adoc[Persistable_datanucleusIdLong] (property)
++
+only visible if the JDO entity has datastore identity, and the `id` field introduced by enhancing can be cast to `Long`.
+
+* xref:refguide:persistence:index/jdo/datanucleus/mixins/Persistable_datanucleusVersionLong.adoc[Persistable_datanucleusVersionLong] (property)
++
+only visible if the entity is annotated with `javax.jdo.annotations.Version` and the `version` field introduced by enhancing can be cast to `Long`.
+
+* xref:refguide:persistence:index/jdo/datanucleus/mixins/Persistable_datanucleusVersionTimestamp.adoc[Persistable_datanucleusVersionLong] (property)
++
+only visible if the entity is annotated with `javax.jdo.annotations.Version` and the `version` field introduced by enhancing can be cast to `java.sql.Timestamp`.
+
+As a developer you do not need to write any code to obtain the mixins that contribute to this interface.
+
+These mixin properties/actions are all associated with the "Metadata" fieldset.
+
+
+== Security
+
+Domain objects that are created, updated or otherwise associated with a user can implement the xref:refguide:applib:index/mixins/security/HasUsername.adoc[HasUsername] mixee interface.
+
+A number of extension modules related to security, such as xref:security:secman:about.adoc[SecMan] module, contribute to this interface.
+
+
+== System
+
+Domain objects that are associated to an xref:refguide:applib:index/services/iactn/Interaction.adoc[Interaction] or to a nested xref:refguide:applib:index/services/xactn/TransactionId.adoc[transaction] can express this relationship by implementing the xref:refguide:applib:index/mixins/system/HasInteractionId_see-also.adoc
+
+
+== Updates
+
+The following interfaces define a contract for the framework to update:
+
+* xref:refguide:applib:index/mixins/updates/OnUpdatedAt.adoc[OnUpdatedAt]
++
+For domain entities that keep track of when they were last updated.
+
+* xref:refguide:applib:index/mixins/updates/OnUpdatedBy.adoc[OnUpdatedBy]
++
+For domain entities that keep track of which user last updated them.
+
+* xref:refguide:applib:index/mixins/mixins/updates/OnUpdatedByAndAt.adoc[OnUpdatedByAndAt]
++
+Simply a combination of xref:refguide:applib:index/mixins/mixins/updates/OnUpdatedAt.adoc[HasUpdatedAt] and xref:refguide:applib:index/mixins/mixins/updates/OnUpdatedBy.adoc[HasUpdatedBy]
+
+Note that these are not quite the same thing as regular mixee interfaces, in that they do not expose getters to be leveraged by a mixin.
+Rather, these expose callback such that the framework can populate them at the appropriate juncture.
diff --git a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/contributee.adoc b/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/contributee.adoc
index 78ea5b3..59890ea 100644
--- a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/contributee.adoc
+++ b/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/contributee.adoc
@@ -6,49 +6,17 @@
 
 The interfaces listed in this chapter act as contributees; they allow domain services to contribute actions/properties/collections to any domain objects that implement these interfaces.
 
-[[HasUniqueId]]
-== `HasUniqueId`
 
-The `HasUniqueId` interface is a mix-in for any domain objects that are uniquely identified, in particular to represent a system-level request or interaction.
-The canonical usage is where the unique identifier is actually a transaction id, as implemented by auditing entries or commands, or for xref:refguide:applib:index/services/iactn/InteractionContext.adoc[Interaction]s persisted as published events.
 
-The interface is defined is:
-
-[source,java]
-----
-public interface HasUniqueId {
-    public UUID getUniqueId();                             // <.>
-    public void setUniqueId(final UUID uniqueId);
-}
-----
-<.> unique identifier (a GUID) of this request/interaction.
+== Usage Notes
 
-Some of the extension/mapping modules that have domain entity/ies that implement this interface are:
-
-* xref:security:audit-trail:about.adoc[Auditer] module: `AuditEntry` entity
-* xref:extensions:command-log:about.adoc[Command Log] module: `CommandJdo` entity
-* xref:mappings:outbox-publisher:about.adoc[Outbox Publisher] module: `OutboxEvent` entity
-
-[#RepresentsInteractionMemberExecution]
-== `RepresentsInteractionMemberExecution`
-
-The `RepresentsInteractionMemberExecution` interface is a sub-interface of `HasUniqueId` that also includes a sequence property:
-
-[source,java]
-----
-public interface RepresentsInteractionMemberExecution extends HasUniqueId {
-    int getSequence();
-}
-----
-
-Here the (inherited) `getTransactionId()` is intended to be interpreted as an interaction (cf xref:refguide:schema:ixn.adoc[InteractionDto]) that has at least one member execution (cf xref:refguide:schema:about.adoc#ixn/memberExecutionDto.adoc[memberExecutionDto]).
-
-If the interaction (almost certainly an action) calls other actions by way of xref:refguide:applib:index/services/wrapper/WrapperFactory.adoc[WrapperFactory]), then there may be several member executions, each with a unique sequence number, within the same transaction Id.
+If the interaction is an action that in turn calls other actions by way of xref:refguide:applib:index/services/wrapper/WrapperFactory.adoc[WrapperFactory]), then there may be several member executions, each with a unique sequence number, within the same transaction Id.
 
 The purpose of this interface is to allow mixins to be defined, though the framework itself defines none.
 
 Currently the only implementation of this interface is that for `PublishedObjects` applib interface as defined by the xref:refguide:applib:index/services/publishing/spi/ExecutionSubscriber.adoc[ExecutionSubscriber].
 
+
 [[HasUserName]]
 == `HasUsername`
 
diff --git a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/mixins.adoc b/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/mixins.adoc
index 158d569..60077ef 100644
--- a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/mixins.adoc
+++ b/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/mixins.adoc
@@ -1,10 +1,10 @@
-= Mixins
+= Mixins (and Mixees)
 
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
 :page-partial:
 
 
-This section defines a number of role interfaces that define a contract for some framework-defined mixins.
+This section defines a number of interfaces that define a contract for some framework-defined mixins.
 
 [TIP]
 ====
@@ -12,8 +12,56 @@ See the xref:userguide:fun:overview.adoc#mixins[fundamentals user guide] for a d
 ====
 
 
+[#java-lang-object]
+== java.lang.Object
+
+The framework provides a number of mixins that contributes to `java.lang.Object` (in other words, to every domain object):
+
+* core
+** xref:refguide:applib:index/mixins/layout/Object_downloadLayoutXml.adoc[Object_downloadLayoutXml]
+** xref:refguide:applib:index/mixins/layout/Object_downloadLayoutXml.adoc[Object_downloadLayoutXml]
+
+* Wicket viewer:
+** xref:refguide:viewer:index/wicket/viewer/mixins/Object_clearHints.adoc[Object_clearHints]
+
+
+
+[[Dto]]
+== Dto
+
+JAXB view models can optionally implement the `Dto` interface.
+Two mixins contribute to this interface:
+
+* xref:refguide:applib:index/mixins/dto/Dto_downloadXml.adoc[Dto_downloadXml]
+* xref:refguide:applib:index/mixins/dto/Dto_downloadXsd.adoc[Dto_downloadXsd]
+
+These allow the view model/DTO to be seriailized, respectively, as XML and as the XSD schema for said XML.
+
+
+[[Persistable]]
+== Persistable
+
+
+All JDO domain entities implement the DataNucleus `Persistable` role interface as a result of the enhancer process (the fully qualified class name is `org.datanucleus.enhancement.Persistable`).
+
+Using this, the following mixins (actions and properties) are available for all JDO entities:
+
+* xref:refguide:persistence:index/jdo/datanucleus/mixins/Persistable_downloadJdoMetadata.adoc[Persistable_downloadJdoMetadata] (action)
+* xref:refguide:persistence:index/jdo/datanucleus/mixins/Persistable_datanucleusIdLong.adoc[Persistable_datanucleusIdLong] (property)
++
+only visible if the JDO entity has datastore identity, and the `id` field introduced by enhancing can be cast to `Long`.
+
+* xref:refguide:persistence:index/jdo/datanucleus/mixins/Persistable_datanucleusVersionLong.adoc[Persistable_datanucleusVersionLong] (property)
++
+only visible if the entity is annotated with `javax.jdo.annotations.Version` and the `version` field introduced by enhancing can be cast to `Long`.
+
+* xref:refguide:persistence:index/jdo/datanucleus/mixins/Persistable_datanucleusVersionTimestamp.adoc[Persistable_datanucleusVersionLong] (property)
++
+only visible if the entity is annotated with `javax.jdo.annotations.Version` and the `version` field introduced by enhancing can be cast to `java.sql.Timestamp`.
+
+As a developer you do not need to write any code to obtain the mixins that contribute to this interface.
+
+These mixin properties/actions are all associated with the "Metadata" fieldset.
+
 
 
-include::mixins/Object.adoc[leveloffset=+1]
-include::mixins/Dto.adoc[leveloffset=+1]
-include::mixins/Persistable.adoc[leveloffset=+1]
diff --git a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/mixins/Dto.adoc b/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/mixins/Dto.adoc
deleted file mode 100644
index 39c41ae..0000000
--- a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/mixins/Dto.adoc
+++ /dev/null
@@ -1,66 +0,0 @@
-[[Dto]]
-= `Dto`
-
-:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
-:page-partial:
-
-
-The `Dto` role interface is intended to be implemented by JAXB-annotated view models, that is, annotated using
-xref:refguide:applib-ant:XmlRootElement.adoc[@XmlRootElement].
-It enables the ability to download the XML and XSD schema of those objects using two xref:userguide:fun:overview.adoc#mixins[mixins], `Dto_downloadXml` and `Dto_downloadXsd`.
-
-The interface is just a marker interface (with no members), and is defined as:
-
-[source,java]
-----
-public interface Dto { }
-----
-
-The `Dto_downloadXml` mixin defines the following action:
-
-// TODO: v2: use include::[]
-
-[source,java]
-----
-@Action
-public class Dto_downloadXml {
-
-    public Dto_downloadXml(final Dto dto) {     // <.>
-        // ...
-    }
-    public Object act(final String fileName) {  // <.>
-        // ...
-    }
-
-    // ...
-}
-----
-<.> (constructor) provided as an action to any class that (trivially) implements the `Dto` interface
-<.> The action's name is derived from the class name.
-
-This will return the XML text wrapped up in a xref:applib-classes:about.adoc#Clob[Clob].
-
-The `Dto_downloadXsd` mixin is similar:
-
-[source,java]
-----
-@Action
-public class Dto_downloadXsd {
-    public Dto_downloadXsd(final Dto dto) { /* ... */ }  // <.>
-    public Object act(                                   // <.>
-            final String fileName,
-            final IsisSchemes isisSchemas) { /* ... */ }
-}
-----
-<.> (constructor) provided as an action to any class that (trivially) implements the `Dto` interface
-<.> The action's name be derived from the class name.
-
-If the domain object's JAXB annotations reference only a single XSD schema then this will return that XML text as a xref:applib-classes:about.adoc#Clob[Clob] of that XSD.
-If there are multiple XSD schemas referenced then the action will return a zip of those schemas, wrapped up in a xref:applib-classes:about.adoc#Blob[Blob].
-The `IsisSchemas` parameter to the action can be used to optionally ignore the common xref:refguide:schema:about.adoc[Apache Isis schemas] (useful if there is only one other XSD schema referenced by the DTO).
-
-
-
-== Related Services
-
-The `Dto_downloadXml` and `Dto_downloadXsd` delegate to the xref:refguide:applib:index/services/jaxb/JaxbService.adoc[JaxbService] to actually generate the XML/XSD.
diff --git a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/mixins/Object.adoc b/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/mixins/Object.adoc
deleted file mode 100644
index 2ffea5b..0000000
--- a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/mixins/Object.adoc
+++ /dev/null
@@ -1,115 +0,0 @@
-[[Object]]
-= `Object`
-
-:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
-:page-partial:
-
-
-The framework provides a single mixin that contributes to simply `java.lang.Object`.
-It provides the ability to download the layout XML for any domain object (in practical terms: entities and view models).
-
-These mixin actions are all associated with the "Metadata" fieldset.
-A number of other xref:applib-classes:about.adoc#Persistable[mixins] also contribute properties or actions to the "Metadata" fieldset.
-
-
-
-[#clearHints]
-== `clearHints()`
-
-When a domain object is rendered the end-user can select different tabs, and for collections can sort the columns,
-navigate to second pages, or select different views of collections.
-If the user revisits that object, the xref:vw:ROOT:about.adoc[Wicket viewer] will remember these hints and render the domain object in the same state.
-These rendering hints are also included if the user copies the URL using the anchor link (to right hand of the object's title).
-
-The `Object_clearHints` mixin provides the ability for the end-user to discard these hints so that the object is
-rendered in its initial state:
-
-// TODO: v2: use include::[]
-
-[source,java]
-----
-public void clearHints() {
-    ...
-}
-----
-
-=== Related Services
-
-This mixin uses the xref:refguide:applib:index/services/hint/HintStore.adoc[HintStore] service to store and retrieve UI hints for each rendered object, per user.
-
-
-
-[#downloadlayoutxml]
-== `downloadLayoutXml()`
-
-The `Object_downloadLayoutXml` mixin provides an action to download the xref:userguide:fun:ui.adoc#object-layout[layout XML] for the current domain object.
-It has the following signature:
-
-// TODO: v2: use include::[]
-
-
-[source,java]
-----
-public Object downloadLayoutXml(
-    @ParameterLayout(named = "File name")
-    final String fileName,
-    final LayoutService.Style style) {          // <1>
-    ...
-}
-----
-<1> either current, complete, normalized or minimal.
-
-See the documentation on xref:userguide:fun:ui.adoc#object-layout[layout XML] and also
-the xref:refguide:applib:index/services/layout/LayoutService.adoc[LayoutService] for more information on these styles
-
-
-=== Related Services
-
-This mixin calls xref:refguide:applib:index/services/layout/LayoutService.adoc[LayoutService] to obtain the layout XML.
-
-
-
-
-[#rebuildMetamodel]
-== `rebuildMetamodel()`
-
-The `Object_rebuildMetamodel` mixin provides the ability to discard the current internal metamodel data (an instance of `ObjectSpecification`) for the domain class of the rendered object, and recreate from code and other sources (most notably, layout XML data).
-It has the following signature:
-
-// TODO: v2: use include::[]
-
-[source,java]
-----
-public void rebuildMetamodel() {
-    ...
-}
-----
-
-
-=== Related Services
-
-This mixin calls xref:refguide:applib:index/services/metamodel/MetaModelService.adoc[MetaModelService] and the xref:refguide:applib:index/services/grid/GridService.adoc[GridService] to invalidate their caches.
-
-
-
-
-
-== `openRestApi()`
-
-The `Object_openRestApi` mixin provides an action to navigate to the URL of the xref:vro:ROOT:about.adoc[Restful Objects resource] corresponding to the domain object.
-It has the following signature:
-
-// TODO: v2: use include::[]
-
-[source,java]
-----
-public URL openRestApi() { /* ... */ }
-----
-
-
-=== Related Services
-
-This mixin calls xref:refguide:applib:index/services/bookmark/BookmarkService.adoc[BookmarkService] to build the URL.
-
-
-
diff --git a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/mixins/Persistable.adoc b/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/mixins/Persistable.adoc
deleted file mode 100644
index eb20331..0000000
--- a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/mixins/Persistable.adoc
+++ /dev/null
@@ -1,59 +0,0 @@
-[[Persistable]]
-= `Persistable`
-
-:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
-:page-partial:
-
-
-All domain entities automatically implement the DataNucleus `Persistable` role interface as a result of the enhancer process (the fully qualified class name is `org.datanucleus.enhancement.Persistable`).
-So as a developer you do not need to write any code to obtain the mixins that contribute to this interface.
-
-These mixin properties/actions are all associated with the "Metadata" fieldset.
-A number of other xref:applib-classes:about.adoc#Object[mixins] also contribute properties or actions to the "Metadata" fieldset.
-
-
-
-[#downloadJdoMetadata]
-== `downloadJdoMetadata()`
-
-The `Persistable_downloadJdoMetadata` mixin provides an action which allows the JDO link:http://www.datanucleus.org/products/datanucleus/jdo/metadata_xml.html[class metadata] to be downloaded as XML.
-It has the following signature:
-
-// TODO: v2: use include::[]
-
-[source,java]
-----
-public Clob downloadJdoMetadata(                    // <.>
-
-    @ParameterLayout(named = ".jdo file name")
-    final String fileName) {
-        // ...
-    }
-
-    // ...
-}
-----
-<.> returns the XML text wrapped up in a xref:applib-classes:about.adoc#Clob[Clob].
-
-
-
-=== Related Services
-
-The mixin delegates to the xref:pjdo:ROOT:services/IsisJdoSupport.adoc[IsisJdoSupport] service to obtain a reference to the JDO `PersistenceManagerFactory`.
-
-
-[#datanucleusXxx]
-== `datanucleusXxx`
-
-The framework provides a number of mixins that expose the datanucleus Id and version of a persistable domain entity.
-Several implementations are provided to support different datatypes:
-
-* `Persistable_datanucleusIdLong` will expose the entity's id, assuming that the id is or can be cast to `java.lang.Long`.
-Otherwise the property will be hidden.
-
-* `Persistable_datanucleusVersionTimestamp` will expose the entity's version, assuming that the version is or can be cast to `java.sql.Timestamp`.
-Otherwise the property will be hidden.
-
-* `Persistable_datanucleusVersionLong` will expose the entity's version, assuming that the version is or can be cast to `java.lang.Long`.
-Otherwise the property will be hidden.
-
diff --git a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/roles/HoldsUpdatedAt.adoc b/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/roles/HoldsUpdatedAt.adoc
deleted file mode 100644
index 2f7481d..0000000
--- a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/roles/HoldsUpdatedAt.adoc
+++ /dev/null
@@ -1,46 +0,0 @@
-[[HoldsUpdatedAt]]
-= `HoldsUpdatedAt`
-
-:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
-:page-partial:
-
-
-The `HoldsUpdatedAt` role interface allows the (framework-provided) `TimestampService` to update each object with the current timestamp whenever it is modified in a transaction.
-
-The interface is defined as:
-
-// TODO: v2: use include::[]
-
-[source,java]
-----
-public interface HoldsUpdatedAt {
-    void setUpdatedAt(java.sql.Timestamp updatedAt);
-}
-----
-
-The current time is obtained from the xref:refguide:applib:index/services/clock/ClockService.adoc[ClockService].
-
-Entities that implement this interface often also implement xref:applib-classes:about.adoc#HoldsUpdatedBy[HoldsUpdatedBy] role interface; as a convenience the xref:applib-classes:about.adoc#Timestampable[Timestampable] interface combines the two roles.
-
-
-
-== Alternative approaches
-
-An alternative way to maintain a timestamp is to use JDO's `@Version` annotation.
-With this approach, it is the JDO/DataNucleus that maintains the version, rather than the framework's `TimestampService`.
-
-For example:
-
-[source,java]
-----
-@javax.jdo.annotations.Version(
-        strategy=VersionStrategy.DATE_TIME,
-        column="version")
-public class Customer {
-    ...
-    public java.sql.Timestamp getVersionSequence() {
-        return (java.sql.Timestamp) JDOHelper.getVersion(this);
-    }
-}
-----
-
diff --git a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/roles/HoldsUpdatedBy.adoc b/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/roles/HoldsUpdatedBy.adoc
deleted file mode 100644
index adaa9f9..0000000
--- a/antora/components/refguide/modules/applib-classes/pages/roles-mixins-contributees/roles/HoldsUpdatedBy.adoc
+++ /dev/null
@@ -1,21 +0,0 @@
-[[HoldsUpdatedBy]]
-= `HoldsUpdatedBy`
-
-:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
-:page-partial:
-
-
-The `HoldsUpdatedBy` role interface ...
-
-// TODO: v2: use include::[]
-
-[source,java]
-----
-public interface HoldsUpdatedBy {
-    void setUpdatedBy(String updatedBy);
-}
-----
-
-Entities that implement this interface often also implement xref:applib-classes:about.adoc#HoldsUpdatedAt[HoldsUpdatedAt] role interface; as a convenience the xref:applib-classes:about.adoc#Timestampable[Timestampable] interface combines the two roles.
-
-
diff --git a/antora/components/refguide/modules/applib-classes/partials/module-nav.adoc b/antora/components/refguide/modules/applib-classes/partials/module-nav.adoc
index a70b567..055402d 100644
--- a/antora/components/refguide/modules/applib-classes/partials/module-nav.adoc
+++ b/antora/components/refguide/modules/applib-classes/partials/module-nav.adoc
@@ -1,11 +1,10 @@
 
 * xref:applib-classes:about.adoc[Classes]
 ** xref:applib-classes:events.adoc[Events]
+** xref:applib-classes:mixees-and-mixins.adoc[Mixees and Mixins]
 ** xref:applib-classes:ViewModel.adoc[ViewModel] (interface)
 ** xref:applib-classes:value-types.adoc[Value Types]
 ** xref:applib-classes:spec.adoc[Specification pattern]
-** xref:applib-classes:i18n.adoc[i18n support]
-** xref:applib-classes:roles-mixins-contributees.adoc[Roles, Mixins and Contributees]
 ** xref:applib-classes:utility.adoc[Utility Classes]
 *** xref:applib:index/util/Enums.adoc[Enums]
 *** xref:applib:index/util/ObjectContracts.adoc[ObjectContracts]
diff --git a/antora/components/relnotes/modules/ROOT/pages/2020/2.0.0-M4/relnotes.adoc b/antora/components/relnotes/modules/ROOT/pages/2020/2.0.0-M4/relnotes.adoc
index d3518c0..50190e3 100644
--- a/antora/components/relnotes/modules/ROOT/pages/2020/2.0.0-M4/relnotes.adoc
+++ b/antora/components/relnotes/modules/ROOT/pages/2020/2.0.0-M4/relnotes.adoc
@@ -10,7 +10,7 @@ This is a further milestone release, consolidating the "re-platforming" of Apach
 Much of the emphasis in this release has been on stabilisation and regression testing.
 That said, there are some new features.
 The release includes support for a new (additional) link:https://cwiki.apache.org/confluence/display/ISIS/ActionParameters?focusedCommentId=158867933#comment-158867933[programming model for action parameters], allowing for more sophisticated management of parameters that interact with each other.
-On the flip side, support for contributed actions from domain services has been removed; use xref:refguide:applib-classes:roles-mixins-contributees/mixins.adoc[Mixins]instead.
+On the flip side, support for contributed actions from domain services has been removed; use xref:refguide:applib-classes:mixins.adoc[Mixins]instead.
 
 This release also has a reworking/simplification of the command service and background commands.
 This includes new extension modules to persist commands (xref:extensions:command-log:about.adoc[Command Log] and xref:extensions:command-replay:about.adoc[Command Replay], to assist regression testing.
diff --git a/antora/components/userguide/modules/fun/pages/overview/types-of-domain-objects.adoc b/antora/components/userguide/modules/fun/pages/overview/types-of-domain-objects.adoc
index 30040b0..2617744 100644
--- a/antora/components/userguide/modules/fun/pages/overview/types-of-domain-objects.adoc
+++ b/antora/components/userguide/modules/fun/pages/overview/types-of-domain-objects.adoc
@@ -214,7 +214,7 @@ These DTOs are still usable as "regular" view models; they will render in the xr
 In fact (as the xref:userguide:fun:view-models.adoc#jaxb[programming model] section below makes clear), these JAXB-annotated view models are in many regards the most powerful of all the alternative ways of writing view models.
 
 It's also worth noting that it is also possible to download the XML (or XSD) straight from the UI, useful during development.
-The view model simply needs to implement the xref:refguide:applib-cm:roles-mixins-contributees/mixins.adoc#Dto[Dto] marker interface; the framework has xref:refguide:applib-cm:roles-mixins-contributees/mixins.adoc#Dto[mixins] that contribute the download actions to the view model.
+The view model simply needs to implement the xref:refguide:applib:index/mixins/dto/Dto.adoc[Dto] marker interface; the framework has xref:refguide:applib-classes:mixins.adoc#Dto[mixins] that contribute the download actions to the view model.
 
 === For REST Clients
 
diff --git a/antora/components/userguide/modules/fun/pages/ui/object-layout.adoc b/antora/components/userguide/modules/fun/pages/ui/object-layout.adoc
index be54708..40299b0 100644
--- a/antora/components/userguide/modules/fun/pages/ui/object-layout.adoc
+++ b/antora/components/userguide/modules/fun/pages/ui/object-layout.adoc
@@ -14,7 +14,7 @@ File-based layouts offer a number of benefits:
 
 * UI hints can be provided for xref:userguide:fun:mixins.adoc[mixin] contributions that are synthesised at runtime.
 
-It is also possible to download an initial `.layout.xml` - capturing any existing layout metadata - using the xref:refguide:applib:index/services/layout/LayoutService.adoc[LayoutService] (exposed on the prototyping menu) or using a xref:refguide:applib-cm:roles-mixins-contributees/mixins.adoc#Object[mixin action] contributed to every domain object.
+It is also possible to download an initial `.layout.xml` - capturing any existing layout metadata - using the xref:refguide:applib:index/services/layout/LayoutService.adoc[LayoutService] (exposed on the prototyping menu) or using a xref:refguide:applib-classes:mixins.adoc#java-lang-object[mixin action] contributed to every domain object.
 
 There are some downsides, though:
 
@@ -279,5 +279,5 @@ You can then remove the `@MemberOrder` and `@Action#associateWith` annotations f
 * if you want to use layout XML file ONLY to describe the grid, then download the "minimal" version.
 The grid regions will be empty in this version, and the framework will use the `@MemberOrder` and `@Action#associateWith` annotations to bind object members to those regions.
 
-If you want to adjust the layout XML for a single domain object, then you can use the xref:refguide:applib-cm:roles-mixins-contributees/mixins.adoc#downloadlayoutxml[mixin action] (contributed to every domain object).
+If you want to adjust the layout XML for a single domain object, then you can use the xref:refguide:applib-classes:mixins.adoc#[mixin action] (contributed to every domain object).
 
diff --git a/antora/components/userguide/modules/fun/pages/view-models/UNUSED-dto.adoc b/antora/components/userguide/modules/fun/pages/view-models/UNUSED-dto.adoc
index 0e7843c..e69de29 100644
--- a/antora/components/userguide/modules/fun/pages/view-models/UNUSED-dto.adoc
+++ b/antora/components/userguide/modules/fun/pages/view-models/UNUSED-dto.adoc
@@ -1,190 +0,0 @@
-= DTOs
-
-:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
-:page-partial:
-
-
-WARNING: TODO: v2: move this to "beyond the basics"
-
-JAXB view models can also be used as DTOs.
-The examples in this section uses the DTO for `ToDoItem`.
-
-This DTO is defined as follows:
-
-[source,java]
-----
-package todoapp.app.viewmodels.todoitem.v1;                         // <.>
-@XmlRootElement(name = "toDoItemDto")                               // <.>
-@XmlType(
-        propOrder = {                                               // <.>
-            "majorVersion", "minorVersion",
-            "description", "category", ...
-            "toDoItem", "similarItems"
-        }
-)
-@DomainObjectLayout(
-        titleUiEvent = TitleUiEvent.Doop.class                      // <.>
-)
-public class ToDoItemV1_1 implements Dto {                          // <.>
-    @XmlElement(required = true, defaultValue = "1")                // <.>
-    public final String getMajorVersion() { return "1"; }
-    @XmlElement(required = true, defaultValue = "1")                // <.>
-    public String getMinorVersion() { return "1"; }
-
-    @XmlElement(required = true)                                    // <.>
-    @Getter @Setter
-    protected String description;
-    @XmlElement(required = true)
-    @Getter @Setter
-    protected String category;
-    ...
-
-    @Getter @Setter                                                 // <.>
-    protected ToDoItem toDoItem;
-    @XmlElementWrapper                                              // <.>
-    @XmlElement(name = "todoItem")
-    @Getter @Setter
-    protected List<ToDoItem> similarItems = Lists.newArrayList();
-}
-----
-<.> package name encodes major version; see discussion on xref:userguide:fun:view-models.adoc#versioning[versioning]
-<.> identifies this class as a view model and defines the root element for JAXB serialization
-<.> all properties in the class must be listed; (they can be ignored using `@XmlTransient`)
-<.> demonstrating use of UI events for a subscriber to provide the DTO's title; see xref:refguide:applib:index/annotation/DomainObjectLayout.adoc#titleUiEvent[@DomainObjectLayout#titleUiEvent()].
-<.> class name encodes (major and) minor version; see discussion on xref:userguide:fun:view-models.adoc#versioning[versioning]
-<.> again, see discussion on xref:userguide:fun:view-models.adoc#versioning[versioning]
-<.> again, see discussion on xref:userguide:fun:view-models.adoc#versioning[versioning]
-<.> simple scalar properties
-<.> reference to a persistent entity; discussed xref:userguide:fun:view-models.adoc#referencing-domain-entities[here]
-<.> reference to a collection of persistent entities; again discussed xref:userguide:fun:view-models.adoc#referencing-domain-entities[here]
-
-
-
-
-[#versioning]
-== Versioning
-
-The whole point of using DTOs (in Apache Isis, at least) is to define a formal contact between two inter-operating but independent applications.
-Since the only thing we can predict about the future with any certainty is that one or both of these applications will change, we should version DTOs from the get-go.
-This allows us to make changes going forward without unnecessarily breaking existing consumers of the data.
-
-[NOTE]
-====
-There are several ways that versioning might be accomplished; we base our guidelines on this link:http://www.xfront.com/Versioning.pdf[article] taken from Roger Costello's blog, well worth a read.
-====
-
-We can distinguish two types of changes:
-
-* backwardly compatible changes
-* breaking changes.
-
-The XSD namespace should change only when there is a major/breaking change.
-If following link:http://semver.org[semantic versioning] that means when we bump the major version number v1, v2, etc.
-
-XML namespaces correspond (when using JAXB) to Java packages.
-We should therefore place our DTOs in a package that contains only the major number; this package will eventually contain a range of DTOs that are intended to be backwardly compatible with one another.
-The package should also have a `package-info.java`; it is this that declares the XSD namespace:
-
-[source,java]
-----
-@javax.xml.bind.annotation.XmlSchema(
-    namespace = "http://viewmodels.app.todoapp/todoitem/v1/Dto.xsd",    // <.>
-    xmlns = {
-        @javax.xml.bind.annotation.XmlNs(
-            namespaceURI = "http://isis.apache.org/schema/common",
-            prefix = "com"
-        )
-    },
-    elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED
-)
-package todoapp.app.viewmodels.todoitem.v1;                             // <.>
-----
-<.> the namespace URI, used by the DTO residing in this package.
-<.> the package in which the DTO resides.  Note that this contains only the major version.
-
-Although there is no requirement for the namespace URI to correspond to a physical URL, it should be unique.
-This usually means including a company domain name within the string.
-
-As noted above, this package will contain multiple DTO classes all with the same namespace; these represent a set of minor versions of the DTO, each subsequent one intended to be backwardly compatible with the previous.
-Since these DTO classes will all be in the same package (as per the advice above), the class should therefore include the minor version name:
-
-[source,java]
-----
-package todoapp.app.viewmodels.todoitem.v1;     // <1>
-...
-public class ToDoItemV1_1 implements Dto {      // <2>
-    ...
-}
-----
-<1> package contains the major version only
-<2> DTO class contains the (major and) minor version
-
-
-We also recommend that each DTO instance should also specify the version of the XSD schema that it is logically compatible with.
-Probably most consumers will not persist the DTOs; they will be processed and then discarded.
-However, it would be wrong to assume that is the case in all cases; some consumers might choose to persist the DTO (eg for replay at some later state).
-
-Thus:
-
-[source,java]
-----
-public class ToDoItemV1_1 implements Dto {
-    @XmlElement(required = true, defaultValue = "1")
-    public final String getMajorVersion() { return "1"; }   // <.>
-    @XmlElement(required = true, defaultValue = "1")
-    public String getMinorVersion() { return "1"; }         // <.>
-    ...
-}
-----
-<.> returns the major version (in sync with the package)
-<.> returns the minor version (in sync with the class name)
-
-These methods always return a hard-coded literal.
-Any instances serialized from these classes will implicitly "declare" the (major and) minor version of the schema with which they are compatible.
-If a consumer has a minimum version that it requires, it can therefore inspect the XML instance itself to determine if it is able to consume said XML.
-
-If a new (minor) version of a DTO is required, then we recommend copying-and-pasting the previous version, eg:
-
-[source,java]
-----
-public class ToDoItemV1_2 implements Dto {
-    @XmlElement(required = true, defaultValue = "1")
-    public final String getMajorVersion() { return "1"; }
-    @XmlElement(required = true, defaultValue = "2")
-    public String getMinorVersion() { return "2"; }
-    ...
-}
-----
-
-Obviously, only changes made must be backward compatible, eg new members must be optional.
-
-Alternatively, you might also consider simply editing the source file, ie renaming the class and bumping up the value returned by `getMinorVersion()`.
-
-
-
-
-
-
-=== DTO Consumers
-
-The actual consumers of DTOs will generally obtain the XML of the view models either by requesting the XML directly, eg using the xref:vro:ROOT:about.adoc[RestfulObjects viewer], or may have the XML sent to them asynchronously using an ESB such as Apache Camel.
-
-In the former case, the consumer requests the DTO by calling the REST API with the appropriate HTTP `Accept` header.
-An appropriate implementation of xref:refguide:applib:index/services/conmap/ContentMappingService.adoc[ContentMappingService] can then be used to return the appropriate DTO (as XML).
-
-For the latter case, one design is simply for the application to instantiate the view model, then call the xref:refguide:applib:index/services/jaxb/JaxbService.adoc[JaxbService] to obtain its corresponding XML.  This can then be published onto the ESB, for example using an http://activemq.apache.org[Apache ActiveMQ (TM)] queue.
-
-However, rather than try to push all the data that might be needed by any of these external systems in a single XML event (which would require anticipating all the requirements, likely a hopeless task), a better design is to publish only the fact that something of note has changed - ie, that an action on a domain object has been invoked - and then let the consumers call back to obtain other information if required.
-This can once again be done by calling the REST API with an appropriate HTTP `Accept` header.
-
-[TIP]
-====
-This is an example of the link:https://leanpub.com/camel-design-patterns[VETRO pattern] (validate, enrich, transform, route, operate).
-In our case we focus on the validation (to determine the nature of the inbound message, ie which action was invoked), and the enrich (callback to obtain a DTO with additional information required by the consumer).
-====
-
-The (non-ASF) link:https://platform.incode.org[Incode Platform^]'s publishmq module provides an out-of-the-box solution of this design.
-It provides an implementation of the xref:refguide:applib:index/services/publishing/spi/ExecutionSubscriber.adoc[ExecutionSubscriber], but which simply publishes instances of xref:refguide:schema:ixn.adoc[InteractionDto] to an ActiveMQ queue.
-Camel (or similar) can then be hooked up to consume these events from this queue, and use a processor to parse the action memento to determine what has changed on the source system.
-Thereafter, a subsequent Camel processor can then call back to the source - via the xref:vro:ROOT:about.adoc[Restful Objects viewer] - to enrich the message with additional details using a DTO.
-
diff --git a/api/applib/src/main/java/org/apache/isis/applib/mixins/dto/Dto.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/dto/Dto.java
index 31902e1..fa6faa2 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/mixins/dto/Dto.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/dto/Dto.java
@@ -19,6 +19,28 @@
 package org.apache.isis.applib.mixins.dto;
 
 /**
+ * Allows JAXB-annotated view models to act as a mixee in order that other
+ * modules (and the core framework) can contribute behaviour.
+ *
+ * <p>
+ *     A JAXB view model is one annotated with
+ *     {@link javax.xml.bind.annotation.XmlRootElement}.
+ * </p>
+ *
+ * <p>
+ *     The two mixin behaviours contributed by the core framework are the
+ *     ability to download the view model as XML (using {@link Dto_downloadXml})
+ *     and to download the XSD schema for that XML (using
+ *     {@link Dto_downloadXsd}).
+ * </p>
+ *
+ * <p>
+ * The interface is just a marker interface (with no members).
+ * </p>
+ *
+ * @see Dto_downloadXml
+ * @see Dto_downloadXsd
+ *
  * @since 1.x {@index}
  */
 public interface Dto {
diff --git a/api/applib/src/main/java/org/apache/isis/applib/mixins/MixinConstants.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/dto/DtoMixinConstants.java
similarity index 88%
rename from api/applib/src/main/java/org/apache/isis/applib/mixins/MixinConstants.java
rename to api/applib/src/main/java/org/apache/isis/applib/mixins/dto/DtoMixinConstants.java
index acc3375..7d57226 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/mixins/MixinConstants.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/dto/DtoMixinConstants.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.applib.mixins;
+package org.apache.isis.applib.mixins.dto;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
@@ -25,11 +25,8 @@ import lombok.NoArgsConstructor;
  * @since 1.x {@index}
  */
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class MixinConstants {
+public final class DtoMixinConstants {
 
-    public static final String METADATA_LAYOUT_GROUPNAME = "metadata";
     public static final String FILENAME_PROPERTY_NAME = "File name";
     public static final String FILENAME_PROPERTY_DESCRIPTION = "File name extension can be omitted.";
-
-
 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/mixins/dto/Dto_downloadXml.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/dto/Dto_downloadXml.java
index 7cbc941..def3f21 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/mixins/dto/Dto_downloadXml.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/dto/Dto_downloadXml.java
@@ -26,7 +26,6 @@ import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.annotation.RestrictTo;
 import org.apache.isis.applib.annotation.SemanticsOf;
-import org.apache.isis.applib.mixins.MixinConstants;
 import org.apache.isis.applib.services.jaxb.JaxbService;
 import org.apache.isis.applib.value.Clob;
 import org.apache.isis.applib.value.NamedWithMimeType.CommonMimeType;
@@ -35,6 +34,15 @@ import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 /**
+ * Mixin that provides the ability to download a view model as XML.
+ *
+ * <p>
+ *  Requires that the view model is a JAXB view model, and implements the
+ *  {@link Dto} marker interface.
+ * </p>
+ *
+ * @see Dto_downloadXsd
+ *
  * @since 1.x {@index}
  */
 @Action(
@@ -59,22 +67,18 @@ public class Dto_downloadXml {
 
             // PARAM 0
             @ParameterLayout(
-                    named = MixinConstants.FILENAME_PROPERTY_NAME,
-                    describedAs = MixinConstants.FILENAME_PROPERTY_DESCRIPTION)
+                    named = DtoMixinConstants.FILENAME_PROPERTY_NAME,
+                    describedAs = DtoMixinConstants.FILENAME_PROPERTY_DESCRIPTION)
             final String fileName) {
 
         val xmlString = jaxbService.toXml(holder);
         return Clob.of(fileName, CommonMimeType.XML, xmlString);
     }
 
-    // -- PARAM 0
-
     public String default0Act() {
         return holder.getClass().getName();
     }
 
-    // -- DEPENDENCIES
-
     @Inject JaxbService jaxbService;
 
 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/mixins/dto/Dto_downloadXsd.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/dto/Dto_downloadXsd.java
index 513ffa2..305bafe 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/mixins/dto/Dto_downloadXsd.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/dto/Dto_downloadXsd.java
@@ -28,7 +28,6 @@ import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.annotation.RestrictTo;
 import org.apache.isis.applib.annotation.SemanticsOf;
-import org.apache.isis.applib.mixins.MixinConstants;
 import org.apache.isis.applib.services.jaxb.IsisSchemas;
 import org.apache.isis.applib.services.jaxb.JaxbService;
 import org.apache.isis.applib.services.message.MessageService;
@@ -41,6 +40,21 @@ import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 /**
+ * Mixin that provides the ability to download the XSD schema for a view model
+ * can be downloaded as XML.
+ *
+ * <p>
+ *  Requires that the view model is a JAXB view model, and implements the
+ *  {@link Dto} marker interface.
+ * </p>
+ *
+ * <p>
+ * If the domain object's JAXB annotations reference only a single XSD schema
+ * then this will return that XML text as a {@link Clob} of that XSD.
+ * If there are multiple XSD schemas referenced then the action will return a
+ * zip of those schemas, wrapped up in a {@link Blob}.
+ * </p>
+ *
  * @since 1.x {@index}
  */
 @Action(
@@ -59,16 +73,19 @@ public class Dto_downloadXsd {
     public static class ActionDomainEvent
     extends org.apache.isis.applib.IsisModuleApplib.ActionDomainEvent<Dto_downloadXsd> {}
 
+    /**
+     * The {@link IsisSchemas} parameter can be used to optionally ignore the
+     * common Apache Isis schemas; useful if there is only one other XSD schema
+     * referenced by the DTO.
+     */
     @MemberOrder(sequence = "500.2")
     public Object act(
 
-            // PARAM 0
             @ParameterLayout(
-                    named = MixinConstants.FILENAME_PROPERTY_NAME,
-                    describedAs = MixinConstants.FILENAME_PROPERTY_DESCRIPTION)
+                    named = DtoMixinConstants.FILENAME_PROPERTY_NAME,
+                    describedAs = DtoMixinConstants.FILENAME_PROPERTY_DESCRIPTION)
             final String fileName,
 
-            // PARAM 1
             final IsisSchemas isisSchemas) {
 
         val schemaMap = jaxbService.toXsd(holder, isisSchemas);
@@ -100,26 +117,18 @@ public class Dto_downloadXsd {
 
     }
 
-    // -- PARAM 0
-
     public String default0Act() {
         return holder.getClass().getName();
     }
 
-    // -- PARAM 1
-
     public IsisSchemas default1Act() {
         return IsisSchemas.IGNORE;
     }
 
-    // -- HELPER
-
     private static String zipEntryNameFor(final String namespaceUri) {
         return namespaceUri + ".xsd";
     }
 
-    // -- DEPENDENCIES
-
     @Inject MessageService messageService;
     @Inject JaxbService jaxbService;
 }
diff --git a/commons/src/main/java/org/apache/isis/commons/having/HasUniqueId.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/LayoutMixinConstants.java
similarity index 74%
copy from commons/src/main/java/org/apache/isis/commons/having/HasUniqueId.java
copy to api/applib/src/main/java/org/apache/isis/applib/mixins/layout/LayoutMixinConstants.java
index 305a35d..564adf7 100644
--- a/commons/src/main/java/org/apache/isis/commons/having/HasUniqueId.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/LayoutMixinConstants.java
@@ -16,19 +16,17 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.commons.having;
-
-import java.util.UUID;
+package org.apache.isis.applib.mixins.layout;
 
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
 
 /**
- * @since 2.0 {@index}
+ * @since 1.x {@index}
  */
-public interface HasUniqueId {
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class LayoutMixinConstants {
 
-    /**
-     * A unique identifier (a GUID).
-     */
-    UUID getUniqueId();
 
+    public static final String METADATA_LAYOUT_GROUPNAME = "metadata";
 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/Object_downloadLayoutXml.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/Object_downloadLayoutXml.java
index 44da4f2..39b05ab 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/Object_downloadLayoutXml.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/Object_downloadLayoutXml.java
@@ -26,7 +26,7 @@ import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.annotation.RestrictTo;
 import org.apache.isis.applib.annotation.SemanticsOf;
-import org.apache.isis.applib.mixins.MixinConstants;
+import org.apache.isis.applib.mixins.dto.DtoMixinConstants;
 import org.apache.isis.applib.services.layout.LayoutService;
 import org.apache.isis.applib.services.layout.Style;
 import org.apache.isis.applib.value.Clob;
@@ -36,6 +36,8 @@ import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 /**
+ * Provides a mixin to download the layout XML for any domain object.
+ *
  * @since 1.x {@index}
  */
 @Action(
@@ -55,11 +57,11 @@ public class Object_downloadLayoutXml {
 
     private final Object holder;
 
-    @MemberOrder(name = MixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "700.1")
+    @MemberOrder(name = LayoutMixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "700.1")
     public Object act(
             @ParameterLayout(
-                    named = MixinConstants.FILENAME_PROPERTY_NAME,
-                    describedAs = MixinConstants.FILENAME_PROPERTY_DESCRIPTION)
+                    named = DtoMixinConstants.FILENAME_PROPERTY_NAME,
+                    describedAs = DtoMixinConstants.FILENAME_PROPERTY_DESCRIPTION)
             final String fileName,
             final Style style) {
 
diff --git a/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/Object_openRestApi.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/Object_openRestApi.java
index 27ce79f..281d9ff 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/Object_openRestApi.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/Object_openRestApi.java
@@ -27,7 +27,6 @@ import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.RestrictTo;
 import org.apache.isis.applib.annotation.SemanticsOf;
-import org.apache.isis.applib.mixins.MixinConstants;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.applib.value.LocalResourcePath;
 
@@ -35,6 +34,9 @@ import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 /**
+ * Provides the ability to navigate to the corresponding URL of this domain
+ * object in the REST API provided by the <i>Restful Objects</i> viewer.
+ *
  * @since 1.x {@index}
  */
 @Action(
@@ -54,7 +56,7 @@ public class Object_openRestApi {
 
     private final Object holder;
 
-    @MemberOrder(name = MixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "750.1")
+    @MemberOrder(name = LayoutMixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "750.1")
     public LocalResourcePath act() {
         val bookmark = bookmarkService.bookmarkForElseThrow(holder);
         val objType = bookmark.getObjectType();
diff --git a/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/Object_rebuildMetamodel.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/Object_rebuildMetamodel.java
index 6e2ccd9..e95b307 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/Object_rebuildMetamodel.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/layout/Object_rebuildMetamodel.java
@@ -25,12 +25,15 @@ import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.RestrictTo;
 import org.apache.isis.applib.annotation.SemanticsOf;
-import org.apache.isis.applib.mixins.MixinConstants;
 import org.apache.isis.applib.services.metamodel.MetaModelService;
 
 import lombok.RequiredArgsConstructor;
 
 /**
+ *  Provides the ability to discard the current internal metamodel data for
+ *  the domain class of the rendered object, and recreate from code and other
+ *  sources (most notably, layout XML data).
+ *
  * @since 1.x {@index}
  */
 @Action(
@@ -50,7 +53,7 @@ public class Object_rebuildMetamodel {
 
     private final Object holder;
 
-    @MemberOrder(name = MixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "800.1")
+    @MemberOrder(name = LayoutMixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "800.1")
     public Object act() {
         metaModelService.rebuild(holder.getClass());
         return holder;
diff --git a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_downloadMetamodelXml.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_downloadMetamodelXml.java
index 74e95fb..65b2d82 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_downloadMetamodelXml.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_downloadMetamodelXml.java
@@ -28,7 +28,8 @@ import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.annotation.RestrictTo;
 import org.apache.isis.applib.annotation.SemanticsOf;
-import org.apache.isis.applib.mixins.MixinConstants;
+import org.apache.isis.applib.mixins.dto.DtoMixinConstants;
+import org.apache.isis.applib.mixins.layout.LayoutMixinConstants;
 import org.apache.isis.applib.services.jaxb.JaxbService;
 import org.apache.isis.applib.services.metamodel.Config;
 import org.apache.isis.applib.services.metamodel.MetaModelService;
@@ -59,13 +60,13 @@ public class Object_downloadMetamodelXml {
     public static class ActionDomainEvent
     extends org.apache.isis.applib.IsisModuleApplib.ActionDomainEvent<Object_downloadMetamodelXml> {}
 
-    @MemberOrder(name = MixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "700.2")
+    @MemberOrder(name = LayoutMixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "700.2")
     public Object act(
 
             // PARAM 0
             @ParameterLayout(
-                    named = MixinConstants.FILENAME_PROPERTY_NAME,
-                    describedAs = MixinConstants.FILENAME_PROPERTY_DESCRIPTION)
+                    named = DtoMixinConstants.FILENAME_PROPERTY_NAME,
+                    describedAs = DtoMixinConstants.FILENAME_PROPERTY_DESCRIPTION)
             final String fileName) {
 
         val pkg = holder.getClass().getPackage().getName();
diff --git a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectIdentifier.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectIdentifier.java
index 1f3d329..59dd462 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectIdentifier.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectIdentifier.java
@@ -24,7 +24,7 @@ import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.applib.mixins.MixinConstants;
+import org.apache.isis.applib.mixins.layout.LayoutMixinConstants;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.applib.services.metamodel.MetaModelService;
 import org.apache.isis.commons.internal.base._Strings;
@@ -49,7 +49,7 @@ public class Object_objectIdentifier {
     public static class ActionDomainEvent
     extends org.apache.isis.applib.IsisModuleApplib.ActionDomainEvent<Object_objectIdentifier> {}
 
-    @MemberOrder(name = MixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "700.2")
+    @MemberOrder(name = LayoutMixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "700.2")
     public String prop() {
         val bookmark = bookmarkService.bookmarkForElseThrow(this.holder);
         val sort = mmService.sortOf(bookmark, MetaModelService.Mode.RELAXED);
diff --git a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectType.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectType.java
index c2d2742..d67b983 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectType.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/metamodel/Object_objectType.java
@@ -24,7 +24,7 @@ import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.applib.mixins.MixinConstants;
+import org.apache.isis.applib.mixins.layout.LayoutMixinConstants;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
 
 import lombok.RequiredArgsConstructor;
@@ -45,7 +45,7 @@ public class Object_objectType {
     public static class ActionDomainEvent
     extends org.apache.isis.applib.IsisModuleApplib.ActionDomainEvent<Object_objectType> {}
 
-    @MemberOrder(name = MixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "700.1")
+    @MemberOrder(name = LayoutMixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "700.1")
     public String prop() {
         val bookmark = bookmarkService.bookmarkForElseThrow(this.holder);
         return bookmark.getObjectType();
diff --git a/commons/src/main/java/org/apache/isis/commons/having/HasUsername.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/security/HasUsername.java
similarity index 63%
rename from commons/src/main/java/org/apache/isis/commons/having/HasUsername.java
rename to api/applib/src/main/java/org/apache/isis/applib/mixins/security/HasUsername.java
index 5b03ac0..5e0bb2c 100644
--- a/commons/src/main/java/org/apache/isis/commons/having/HasUsername.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/security/HasUsername.java
@@ -16,22 +16,30 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.commons.having;
+package org.apache.isis.applib.mixins.security;
+
+import org.apache.isis.applib.mixins.updates.OnUpdatedBy;
 
 /**
- * Mix-in interface for objects (usually created by service implementations) that are be persistable,
- * and so can be associated with a username, usually of the user that has performed some operation.
+ * Allows domain objects that were created, updated or are otherwise associated
+ * with a named user to act as a mixee in order that other modules may
+ * contribute behaviour.
  *
  * <p>
- * Other services can then use this username as a means to contributed actions/collections to render such additional
- * information relating to the activities of the user.
- * 
+ *     The {@link OnUpdatedBy}
+ *     interface is for entities to be automatically updated by the
+ *     framework when persisted.
+ * </p>
+ *
+ * @see OnUpdatedBy
+ *
  * @since 2.0 {@index}
  */
 public interface HasUsername {
 
     /**
-     * The user that created this object.
+     * The user that created, updated or is otherwise associated with this
+     * object.
      */
     String getUsername();
 
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/DomainChangeRecord.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/system/DomainChangeRecord.java
similarity index 84%
rename from api/applib/src/main/java/org/apache/isis/applib/services/DomainChangeRecord.java
rename to api/applib/src/main/java/org/apache/isis/applib/mixins/system/DomainChangeRecord.java
index be89e37..6000935 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/DomainChangeRecord.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/system/DomainChangeRecord.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.applib.services;
+package org.apache.isis.applib.mixins.system;
 
 import java.sql.Timestamp;
 import java.util.UUID;
@@ -27,17 +27,23 @@ import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.commons.having.HasUniqueId;
-import org.apache.isis.commons.having.HasUsername;
+import org.apache.isis.applib.mixins.security.HasUsername;
 
 
 /**
- * An abstraction of some sort of recorded change to a domain object: commands, audit entries or published events.
- * 
+ * Allows domain objects that represents some sort of recorded change to a
+ * domain object (commands, audit entries, published interactions) to act
+ * as a mixee in order that other modules can contribute behaviour.
+ *
  * @since 2.0 {@index}
  */
-public interface DomainChangeRecord extends HasUniqueId, HasUsername {
+public interface DomainChangeRecord extends HasInteractionId, HasUsername {
 
+    /**
+     * Enumerates the different types of changes recognised.
+     *
+     * @since 2.0 {@index}
+     */
     enum ChangeType {
         COMMAND,
         AUDIT_ENTRY,
@@ -58,11 +64,13 @@ public interface DomainChangeRecord extends HasUniqueId, HasUsername {
 
 
     /**
-     * The unique identifier (a GUID) of the transaction in which this change occurred.
+     * The unique identifier (a GUID) of the
+     * {@link org.apache.isis.applib.services.iactn.Interaction} within which
+     * this change occurred.
      */
     @Property
     @MemberOrder(name="Identifiers",sequence = "50")
-    UUID getUniqueId();
+    UUID getInteractionId();
 
 
     /**
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/DomainChangeRecord_openTargetObject.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/system/DomainChangeRecord_openTargetObject.java
similarity index 90%
rename from api/applib/src/main/java/org/apache/isis/applib/services/DomainChangeRecord_openTargetObject.java
rename to api/applib/src/main/java/org/apache/isis/applib/mixins/system/DomainChangeRecord_openTargetObject.java
index dc506dc..470947d 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/DomainChangeRecord_openTargetObject.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/system/DomainChangeRecord_openTargetObject.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.applib.services;
+package org.apache.isis.applib.mixins.system;
 
 import javax.inject.Inject;
 
@@ -28,6 +28,14 @@ import org.apache.isis.applib.services.message.MessageService;
 import org.apache.isis.applib.services.metamodel.BeanSort;
 import org.apache.isis.applib.services.metamodel.MetaModelService;
 
+/**
+ * Provides the ability to navigate to a domain object from a
+ * {@link DomainChangeRecord} which only holds the domain object by way of
+ * a {@link DomainChangeRecord#getTarget() target}
+ * {@link org.apache.isis.applib.services.bookmark.Bookmark}.
+ *
+ * @since v2.0 {@index}
+ */
 @Action(
         semantics = SemanticsOf.SAFE
         , associateWith = "target"
diff --git a/commons/src/main/java/org/apache/isis/commons/having/HasUniqueId.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/system/HasInteractionId.java
similarity index 73%
rename from commons/src/main/java/org/apache/isis/commons/having/HasUniqueId.java
rename to api/applib/src/main/java/org/apache/isis/applib/mixins/system/HasInteractionId.java
index 305a35d..c58acb0 100644
--- a/commons/src/main/java/org/apache/isis/commons/having/HasUniqueId.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/system/HasInteractionId.java
@@ -16,19 +16,25 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.commons.having;
+package org.apache.isis.applib.mixins.system;
 
 import java.util.UUID;
 
+import org.apache.isis.applib.services.iactn.Interaction;
+
 
 /**
+ * Allows domain objects that represent or are associated with a system
+ * {@link Interaction} to act as a mixee in order that other modules can
+ * contribute behaviour.
+ *
  * @since 2.0 {@index}
  */
-public interface HasUniqueId {
+public interface HasInteractionId {
 
     /**
      * A unique identifier (a GUID).
      */
-    UUID getUniqueId();
+    UUID getInteractionId();
 
 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/mixins/system/HasTransactionId.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/system/HasTransactionId.java
new file mode 100644
index 0000000..5bea48a
--- /dev/null
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/system/HasTransactionId.java
@@ -0,0 +1,60 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.applib.mixins.system;
+
+import org.apache.isis.applib.mixins.system.HasInteractionId;
+import org.apache.isis.applib.services.iactn.SequenceType;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.schema.ixn.v2.InteractionDto;
+import org.apache.isis.schema.ixn.v2.MemberExecutionDto;
+
+/**
+ * Extends {@link HasInteractionId} to add a strictly monotonically increasing
+ * sequence number so that each transaction within the overall
+ * {@link org.apache.isis.applib.services.iactn.Interaction} has its own
+ * unique identity.
+ *
+ * <p>
+ *     In the vast majority of cases there will only be a single transaction
+ *     per {@link org.apache.isis.applib.services.iactn.Interaction}, but this
+ *     isn't <i>always</i> the case as domain objects may on occasion need to
+ *     explicitly manage transaction boundaries using
+ *     {@link org.apache.isis.applib.services.xactn.TransactionService}.
+ * </p>
+ *
+ * @since 2.0 {@index}
+ */
+public interface HasTransactionId extends HasInteractionId {
+
+    /**
+     * Holds the sequence number uniquely identifying the transaction number
+     * within the overall
+     * {@link org.apache.isis.applib.services.iactn.Interaction}.
+     *
+     * <p>
+     *     The values in this sequence are ultimately obtained from the non-API
+     *     method
+     *     {@link org.apache.isis.applib.services.iactn.Interaction#next(SequenceType)},
+     *     with a {@link SequenceType} of {@link SequenceType#TRANSACTION}.
+     * </p>
+     *
+     * @return
+     */
+    int getSequence();
+}
diff --git a/commons/src/main/java/org/apache/isis/commons/having/HasUpdatedAt.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/updates/OnUpdatedAt.java
similarity index 77%
rename from commons/src/main/java/org/apache/isis/commons/having/HasUpdatedAt.java
rename to api/applib/src/main/java/org/apache/isis/applib/mixins/updates/OnUpdatedAt.java
index 98054e1..db5a4cf 100644
--- a/commons/src/main/java/org/apache/isis/commons/having/HasUpdatedAt.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/updates/OnUpdatedAt.java
@@ -16,12 +16,16 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.commons.having;
+package org.apache.isis.applib.mixins.updates;
 
 /**
+ * Allows domain entities that keep track of when they were updated to be called
+ * by the (framework-provided) <code>TimestampService</code> whenever modified
+ * in a transaction.
+ *
  * @since 2.0 {@index}
  */
-public interface HasUpdatedAt {
+public interface OnUpdatedAt {
 
     void setUpdatedAt(java.sql.Timestamp updatedAt);
 
diff --git a/commons/src/main/java/org/apache/isis/commons/having/HasUpdatedBy.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/updates/OnUpdatedBy.java
similarity index 59%
copy from commons/src/main/java/org/apache/isis/commons/having/HasUpdatedBy.java
copy to api/applib/src/main/java/org/apache/isis/applib/mixins/updates/OnUpdatedBy.java
index fe95f0b..f8aebe9 100644
--- a/commons/src/main/java/org/apache/isis/commons/having/HasUpdatedBy.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/updates/OnUpdatedBy.java
@@ -16,12 +16,25 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.commons.having;
+package org.apache.isis.applib.mixins.updates;
 
 /**
+ * Allows domain entities that reference the user that updated them to be called
+ * by the (framework-provided) <code>TimestampService</code> whenever modified
+ * in a transaction with the current user.
+ *
+ * <p>
+ *     Note that this interface defines only a setter.  The
+ *     {@link org.apache.isis.applib.mixins.security.HasUsername} can be used
+ *     to expose this user name, allowing other modules to contribute behaviour
+ *     to that mixee.
+ * </p>
+ *
+ * @see org.apache.isis.applib.mixins.security.HasUsername
+ *
  * @since 2.0 {@index}
  */
-public interface HasUpdatedBy {
+public interface OnUpdatedBy {
 
     void setUpdatedBy(String updatedBy);
 
diff --git a/commons/src/main/java/org/apache/isis/commons/having/HasUpdatedBy.java b/api/applib/src/main/java/org/apache/isis/applib/mixins/updates/OnUpdatedByAndAt.java
similarity index 76%
rename from commons/src/main/java/org/apache/isis/commons/having/HasUpdatedBy.java
rename to api/applib/src/main/java/org/apache/isis/applib/mixins/updates/OnUpdatedByAndAt.java
index fe95f0b..577afd8 100644
--- a/commons/src/main/java/org/apache/isis/commons/having/HasUpdatedBy.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/mixins/updates/OnUpdatedByAndAt.java
@@ -16,13 +16,16 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.commons.having;
+package org.apache.isis.applib.mixins.updates;
 
 /**
- * @since 2.0 {@index}
+ * Combines {@link OnUpdatedBy} and {@link OnUpdatedAt}, as these are often
+ * implemented together.
+ *
+ * @since 2.x {@index}
  */
-public interface HasUpdatedBy {
-
-    void setUpdatedBy(String updatedBy);
-
+public interface OnUpdatedByAndAt
+extends
+        OnUpdatedBy,
+        OnUpdatedAt {
 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/RepresentsInteractionMemberExecution.java b/api/applib/src/main/java/org/apache/isis/applib/services/RepresentsInteractionMemberExecution.java
deleted file mode 100644
index 485ba6c..0000000
--- a/api/applib/src/main/java/org/apache/isis/applib/services/RepresentsInteractionMemberExecution.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.applib.services;
-
-import org.apache.isis.applib.services.wrapper.WrapperFactory;
-import org.apache.isis.commons.having.HasUniqueId;
-import org.apache.isis.schema.ixn.v2.InteractionDto;
-import org.apache.isis.schema.ixn.v2.MemberExecutionDto;
-
-/**
- * Extends {@link HasUniqueId}, where the {@link HasUniqueId#getUniqueId()} is interpreted as an
- * interaction (cf {@link InteractionDto}) that has at least one member execution (cf
- * {@link MemberExecutionDto}) 
- * and may (by way of {@link WrapperFactory}) contain
- * several.
- *
- * <p>
- *     Examples could include SPI services that persist published events and status messages.
- * </p>
- * 
- * @since 2.0 {@index}
- */
-public interface RepresentsInteractionMemberExecution extends HasUniqueId {
-
-    int getSequence();
-}
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/command/Command.java b/api/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
index 5f4b385..a508a3f 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
@@ -23,6 +23,7 @@ import java.util.UUID;
 
 import org.apache.isis.applib.events.domain.ActionDomainEvent;
 import org.apache.isis.applib.jaxb.JavaSqlXMLGregorianCalendarMarshalling;
+import org.apache.isis.applib.mixins.system.HasInteractionId;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.commanddto.HasCommandDto;
 import org.apache.isis.applib.services.iactn.Execution;
@@ -31,8 +32,7 @@ import org.apache.isis.applib.services.publishing.spi.CommandSubscriber;
 import org.apache.isis.applib.services.wrapper.WrapperFactory;
 import org.apache.isis.applib.services.wrapper.control.AsyncControl;
 import org.apache.isis.commons.functional.Result;
-import org.apache.isis.commons.having.HasUniqueId;
-import org.apache.isis.commons.having.HasUsername;
+import org.apache.isis.applib.mixins.security.HasUsername;
 import org.apache.isis.schema.cmd.v2.CommandDto;
 
 import lombok.Getter;
@@ -78,7 +78,7 @@ import lombok.extern.log4j.Log4j2;
 @RequiredArgsConstructor
 @ToString
 @Log4j2
-public class Command implements HasUniqueId, HasUsername, HasCommandDto {
+public class Command implements HasInteractionId, HasUsername, HasCommandDto {
 
     /**
      * Unique identifier for the command.
@@ -89,7 +89,7 @@ public class Command implements HasUniqueId, HasUsername, HasCommandDto {
      */
     @Getter
         (onMethod_ = {@Override})
-    private final UUID uniqueId;
+    private final UUID interactionId;
 
     /**
      * The user that created the command.
@@ -128,7 +128,7 @@ public class Command implements HasUniqueId, HasUsername, HasCommandDto {
      *     expected to have {@link CommandDto#getTransactionId()},
      *     {@link CommandDto#getUser()}, {@link CommandDto#getTimestamp()},
      *     {@link CommandDto#getTargets()} and {@link CommandDto#getMember()}
-     *     to be populated.  The {@link #getUniqueId()}, {@link #getUsername()},
+     *     to be populated.  The {@link #getInteractionId()}, {@link #getUsername()},
      *     {@link #getTimestamp()} and {@link #getTarget()} are all derived
      *     from the provided {@link CommandDto}.
      * </p>
@@ -267,7 +267,7 @@ public class Command implements HasUniqueId, HasUsername, HasCommandDto {
             Command.this.commandDto = commandDto;
 
             // even though redundant, but must ensure commandUniqueId == dtoUniqueId
-            val commandUniqueId = Command.this.getUniqueId().toString();
+            val commandUniqueId = Command.this.getInteractionId().toString();
             val dtoUniqueId = commandDto.getTransactionId();
 
             if(!commandUniqueId.equals(dtoUniqueId)) {
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/iactn/Interaction.java b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/Interaction.java
index ea68a44..f953a37 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/iactn/Interaction.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/Interaction.java
@@ -19,18 +19,10 @@
 
 package org.apache.isis.applib.services.iactn;
 
-import java.util.List;
 import java.util.UUID;
 
-import org.apache.isis.applib.events.domain.ActionDomainEvent;
-import org.apache.isis.applib.events.domain.PropertyDomainEvent;
 import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.commons.having.HasUniqueId;
-import org.apache.isis.schema.common.v2.InteractionType;
-import org.apache.isis.schema.ixn.v2.ActionInvocationDto;
-import org.apache.isis.schema.ixn.v2.PropertyEditDto;
-
-import lombok.Getter;
+import org.apache.isis.applib.mixins.system.HasInteractionId;
 
 /**
  * Represents an action invocation or property modification, resulting in some
@@ -60,11 +52,11 @@ import lombok.Getter;
  *
  * @since 1.x revised for 2.0 {@index}
  */
-public interface Interaction extends HasUniqueId {
+public interface Interaction extends HasInteractionId {
 
     /**
      * The unique identifier of this interaction (inherited from
-     * {@link HasUniqueId})
+     * {@link HasInteractionId})
      *
      * <p>
      *     This can be used to correlate audit records and transactions
@@ -74,7 +66,7 @@ public interface Interaction extends HasUniqueId {
      * @return
      */
     @Override
-    UUID getUniqueId();
+    UUID getInteractionId();
 
     /**
      * Represents the <i>intention</i> to perform this interaction.
@@ -94,12 +86,9 @@ public interface Interaction extends HasUniqueId {
 
 
     /**
-     * Generates numbers in a named sequence.
-     *
-     * The name of the sequence can be arbitrary, though note that the framework also uses this capability to
-     * generate sequence numbers corresponding to the sequences enumerated by the {@link Sequence} enum.
+     * Framework use only: generates numbers for a named sequence type.
      */
-    int next(final String sequenceId);
+    int next(final SequenceType sequenceType);
 
 
 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/iactn/Sequence.java b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/Sequence.java
deleted file mode 100644
index 5f1de87..0000000
--- a/api/applib/src/main/java/org/apache/isis/applib/services/iactn/Sequence.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.apache.isis.applib.services.iactn;
-
-import org.apache.isis.applib.services.wrapper.WrapperFactory;
-
-/**
- * Enumerates the different reasons why multiple occurrences of a certain type might occur within a single
- * (top-level) interaction.
- *
- * @since 1.x {@index}
- */
-public enum Sequence {
-
-    /**
-     * Each interaction is either an action invocation or a property edit.  There could be multiple of these,
-     * typically as the result of a nested calls using the {@link WrapperFactory}.  Another reason is
-     * support for bulk action invocations within a single transaction.
-     */
-    INTERACTION,
-
-    /**
-     * For objects: multiple such could be dirtied and thus published as separate events.  For actions
-     * invocations/property edits : multiple sub-invocations could occur if sub-invocations are made through the
-     * {@link WrapperFactory}.
-     */
-    PUBLISHED_EVENT,
-
-    /**
-     * There may be multiple transactions within a given interaction.
-     */
-    TRANSACTION,
-    ;
-
-    public String id() {
-        return Sequence.class.getName() + "#" + name();
-    }
-}
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/iactn/SequenceType.java b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/SequenceType.java
new file mode 100644
index 0000000..64baa23
--- /dev/null
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/SequenceType.java
@@ -0,0 +1,53 @@
+package org.apache.isis.applib.services.iactn;
+
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+
+/**
+ * Enumerates the different reasons for a sequence of occurrences within a
+ * single (top-level) {@link Interaction}.
+ *
+ * @since 1.x {@index}
+ */
+public enum SequenceType {
+
+    /**
+     * Numbers the executions (an action invocation or property edit) within
+     * a given {@link Interaction}.
+     *
+     * <p>
+     * Each {@link Interaction} is initiated by an execution of action
+     * invocation or a property edit.  Thereafter there could be multiple
+     * other executions as the result of nested calls using the
+     * {@link WrapperFactory}.
+     * </p>
+     *
+     * <p>
+     * Another possible reason is support for bulk action invocations.
+     * </p>
+     *
+     * @see Interaction
+     * @see WrapperFactory
+     */
+    EXECUTION,
+
+
+    /**
+     * Numbers the transactions within a given {@link Interaction}.
+     *
+     * <p>
+     * Each {@link Interaction} is executed within the context of a transaction, but
+     * the (occasionally) the transaction may be committed and a new one
+     * started as the result of the domain object using the
+     * {@link org.apache.isis.applib.services.xactn.TransactionService}.
+     * </p>
+     *
+     * @see Interaction
+     * @see org.apache.isis.applib.services.xactn.TransactionService
+     */
+    TRANSACTION,
+    ;
+
+    public String id() {
+        return SequenceType.class.getName() + "#" + name();
+    }
+}
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/publishing/spi/EntityChanges.java b/api/applib/src/main/java/org/apache/isis/applib/services/publishing/spi/EntityChanges.java
index ff772de..4f62685 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/publishing/spi/EntityChanges.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/publishing/spi/EntityChanges.java
@@ -21,8 +21,8 @@ package org.apache.isis.applib.services.publishing.spi;
 import java.sql.Timestamp;
 import java.util.UUID;
 
-import org.apache.isis.commons.having.HasUniqueId;
-import org.apache.isis.commons.having.HasUsername;
+import org.apache.isis.applib.mixins.system.HasInteractionId;
+import org.apache.isis.applib.mixins.security.HasUsername;
 import org.apache.isis.schema.chg.v2.ChangesDto;
 
 /**
@@ -37,15 +37,15 @@ import org.apache.isis.schema.chg.v2.ChangesDto;
  * @since 2.0 {@index}
  */
 public interface EntityChanges
-        extends HasUniqueId,
+        extends HasInteractionId,
                 HasUsername {
 
     /**
-     * inherited from {@link HasUniqueId}, correlates back to the unique
+     * inherited from {@link HasInteractionId}, correlates back to the unique
      * identifier of the transaction in which these objects were changed.
      */
     @Override
-    UUID getUniqueId();
+    UUID getInteractionId();
 
     /**
      * Inherited from {@link HasUsername}, is the user that initiated the
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionId.java b/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionId.java
index 7a749fc..b28e128 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionId.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionId.java
@@ -20,7 +20,8 @@ package org.apache.isis.applib.services.xactn;
 
 import java.util.UUID;
 
-import org.apache.isis.commons.having.HasUniqueId;
+import org.apache.isis.applib.mixins.system.HasInteractionId;
+import org.apache.isis.applib.mixins.system.HasTransactionId;
 
 import lombok.Value;
 
@@ -31,7 +32,7 @@ import lombok.Value;
  * <p>
  *     The transaction and
  *     {@link org.apache.isis.applib.services.iactn.Interaction} are associated
- *     by the {@link #getUniqueId() uniqueId}.
+ *     by the {@link #getInteractionId() uniqueId}.
  * </p>
  *
  * <p>
@@ -41,17 +42,27 @@ import lombok.Value;
  * @since 2.0 {@index}
  */
 @Value(staticConstructor = "of")
-public class TransactionId implements HasUniqueId {
+public class TransactionId implements HasTransactionId {
 
     /**
      * The unique identifier of the outer
      * {@link org.apache.isis.applib.services.iactn.Interaction}.
+     *
+     * <p>
+     *     Together with {@link #getSequence()}, this makes up the
+     *     implementation of {@link org.apache.isis.applib.mixins.system.HasTransactionId}
+     * </p>
      */
-    UUID uniqueId;
+    UUID interactionId;
 
     /**
      * Identifies the transaction (there could be multiple) within the
      * {@link org.apache.isis.applib.services.iactn.Interaction}.
+     *
+     * <p>
+     *     Together with {@link #getInteractionId()}, this makes up the
+     *     implementation of {@link org.apache.isis.applib.mixins.system.HasTransactionId}
+     * </p>
      */
     int sequence;
 
diff --git a/api/applib/src/main/java/org/apache/isis/applib/util/schema/InteractionDtoUtils.java b/api/applib/src/main/java/org/apache/isis/applib/util/schema/InteractionDtoUtils.java
index ace463d..3e12a27 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/util/schema/InteractionDtoUtils.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/util/schema/InteractionDtoUtils.java
@@ -198,7 +198,7 @@ public final class InteractionDtoUtils {
             final Execution<?, ?> execution,
             final MemberExecutionDto executionDto) {
         final Interaction interaction = execution.getInteraction();
-        final String transactionId = interaction.getUniqueId().toString();
+        final String transactionId = interaction.getInteractionId().toString();
 
         return InteractionDtoUtils.newInteractionDto(transactionId, executionDto);
     }
diff --git a/commons/src/main/java/org/apache/isis/commons/having/HasUpdatedByAndAt.java b/commons/src/main/java/org/apache/isis/commons/having/HasUpdatedByAndAt.java
deleted file mode 100644
index 8ad59ef..0000000
--- a/commons/src/main/java/org/apache/isis/commons/having/HasUpdatedByAndAt.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.commons.having;
-
-public interface HasUpdatedByAndAt 
-extends 
-    HasUpdatedBy, 
-    HasUpdatedAt {
-}
diff --git a/core/interaction/src/main/java/org/apache/isis/core/interaction/session/InteractionSession.java b/core/interaction/src/main/java/org/apache/isis/core/interaction/session/InteractionSession.java
index 43d6aca..386855b 100644
--- a/core/interaction/src/main/java/org/apache/isis/core/interaction/session/InteractionSession.java
+++ b/core/interaction/src/main/java/org/apache/isis/core/interaction/session/InteractionSession.java
@@ -24,8 +24,8 @@ import java.util.Map;
 import java.util.UUID;
 import java.util.function.Function;
 
+import org.apache.isis.applib.mixins.system.HasInteractionId;
 import org.apache.isis.applib.services.iactn.Interaction;
-import org.apache.isis.commons.having.HasUniqueId;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.commons.ToString;
@@ -51,10 +51,10 @@ import lombok.Setter;
  * @see InteractionFactory
  */
 public class InteractionSession
-implements HasUniqueId {
+implements HasInteractionId {
 
     @Getter private final long startedAtSystemNanos;
-    
+
     /**
      * The {@link MessageBroker} that holds messages for this session.
      */
@@ -64,7 +64,7 @@ implements HasUniqueId {
      * The {@link MetaModelContext} that holds services for this session.
      */
     @Getter private final MetaModelContext metaModelContext;
-    
+
     public InteractionSession(
             @NonNull final MetaModelContext mmc) {
 
@@ -89,21 +89,21 @@ implements HasUniqueId {
 //    }
 
     // -- INTERACTION ON CLOSE HANDLER
-    
+
     @Setter private Runnable onClose;
-    
+
     // -- INTERACTION SCOPED SESSION ATTRIBUTE
-    
+
     private Map<Class<?>, Object> attributes = null;
     private boolean closed = false;
-	
+
 	@Getter private Interaction interaction;
 
     /** add type specific session data */
     public <T> T putAttribute(Class<? super T> type, T value) {
         return _Casts.uncheckedCast(attributes().put(type, value));
     }
-    
+
     /** conditionally add type specific session data */
     public <T> T computeAttributeIfAbsent(Class<? super T> type, Function<Class<?>, ? extends T> mappingFunction) {
         return _Casts.uncheckedCast(attributes().computeIfAbsent(type, mappingFunction));
@@ -115,14 +115,14 @@ implements HasUniqueId {
                 ? _Casts.uncheckedCast(attributes.get(type))
                 : null;
     }
-    
+
     /** remove type specific session data */
     public void removeAttribute(Class<?> type) {
         if(attributes!=null) {
             attributes.remove(type);
         }
     }
-    
+
     /** Do not use, is called by the framework internally. */
     public void close() {
         if(onClose!=null) {
@@ -132,7 +132,7 @@ implements HasUniqueId {
         attributes = null;
         closed = true;
     }
-    
+
 //    /**
 //     * Copies all attributes to the target session.
 //     * @param target
@@ -143,24 +143,24 @@ implements HasUniqueId {
 //        }
 //        target.attributes().putAll(attributes);
 //    }
-    
+
     private Map<Class<?>, Object> attributes() {
         if(closed) {
             throw _Exceptions.illegalState(
                     "IsisInteraction was already closed, cannot access UserData any longer.");
         }
-        return (attributes==null) 
-                ? attributes = new HashMap<>() 
+        return (attributes==null)
+                ? attributes = new HashMap<>()
                 : attributes;
     }
-    
+
     @Override
-    public UUID getUniqueId() {
-        return getInteraction().getUniqueId();
+    public UUID getInteractionId() {
+        return getInteraction().getInteractionId();
     }
-    
+
     // -- TO STRING
-    
+
     @Override
     public String toString() {
         final ToString asString = new ToString(this);
diff --git a/core/interaction/src/main/java/org/apache/isis/core/interaction/session/IsisInteraction.java b/core/interaction/src/main/java/org/apache/isis/core/interaction/session/IsisInteraction.java
index e5024c1..5481416 100644
--- a/core/interaction/src/main/java/org/apache/isis/core/interaction/session/IsisInteraction.java
+++ b/core/interaction/src/main/java/org/apache/isis/core/interaction/session/IsisInteraction.java
@@ -29,6 +29,7 @@ import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.applib.services.iactn.ActionInvocation;
 import org.apache.isis.applib.services.iactn.Execution;
 import org.apache.isis.applib.services.iactn.PropertyEdit;
+import org.apache.isis.applib.services.iactn.SequenceType;
 import org.apache.isis.applib.services.metrics.MetricsService;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.collections._Maps;
@@ -51,8 +52,8 @@ public class IsisInteraction implements InternalInteraction {
     private final Command command;
 
     @Override
-    public UUID getUniqueId() {
-        return command.getUniqueId();
+    public UUID getInteractionId() {
+        return command.getInteractionId();
     }
 
     private final List<Execution<?,?>> executionGraphs = _Lists.newArrayList();
@@ -199,17 +200,16 @@ public class IsisInteraction implements InternalInteraction {
         currentExecution = newExecution;
     }
 
-    private final Map<String, LongAdder> maxBySequence = _Maps.newHashMap();
+    private final Map<SequenceType, LongAdder> maxBySequence = _Maps.newHashMap();
 
     @Override
-    public int next(final String sequenceId) {
-
-        final LongAdder adder = maxBySequence.computeIfAbsent(sequenceId, this::newAdder);
+    public int next(final SequenceType sequenceType) {
+        final LongAdder adder = maxBySequence.computeIfAbsent(sequenceType, this::newAdder);
         adder.increment();
         return adder.intValue();
     }
 
-    private LongAdder newAdder(String ignore) {
+    private LongAdder newAdder(final SequenceType ignore) {
         final LongAdder adder = new LongAdder();
         adder.decrement();
         return adder;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
index e26d837..9af7fff 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
@@ -23,7 +23,7 @@ import java.util.Optional;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.events.domain.ActionDomainEvent;
-import org.apache.isis.commons.having.HasUniqueId;
+import org.apache.isis.applib.mixins.system.HasInteractionId;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Collections;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
@@ -59,9 +59,9 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
 
     @Override
     public void process(final ProcessMethodContext processMethodContext) {
-        
+
         val actionIfAny = processMethodContext.synthesizeOnMethodOrMixinType(Action.class);
-        
+
         processExplicit(processMethodContext, actionIfAny);
         processInvocation(processMethodContext, actionIfAny);
         processHidden(processMethodContext, actionIfAny);
@@ -76,7 +76,7 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
 
         processTypeOf(processMethodContext, actionIfAny);
         processAssociateWith(processMethodContext, actionIfAny);
-        
+
         processFileAccept(processMethodContext, actionIfAny);
     }
 
@@ -107,7 +107,7 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
             //
             // Set up ActionDomainEventFacet, which will act as the hiding/disabling/validating advisor
             //
-            
+
 
             // search for @Action(domainEvent=...), else use the default event type
             val actionDomainEventFacet =
@@ -154,7 +154,7 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
     private static Class<? extends ActionDomainEvent<?>> defaultFromDomainObjectIfRequired(
             final ObjectSpecification typeSpec,
             final Class<? extends ActionDomainEvent<?>> actionDomainEventType) {
-        
+
         if (actionDomainEventType == ActionDomainEvent.Default.class) {
             val typeFromDomainObject =
                     typeSpec.getFacet(ActionDomainEventDefaultFacetForDomainObjectAnnotation.class);
@@ -179,7 +179,7 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
         // search for @Action(restrictTo=...)
         val facet = PrototypeFacetForActionAnnotation.create(actionIfAny, facetedMethod,
                 ()->super.getSystemEnvironment().getDeploymentType());
-        
+
         super.addFacet(facet);
     }
 
@@ -193,7 +193,7 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
     }
 
     void processCommandPublishing(
-            final ProcessMethodContext processMethodContext, 
+            final ProcessMethodContext processMethodContext,
             final Optional<Action> actionIfAny) {
 
         val facetedMethod = processMethodContext.getFacetHolder();
@@ -201,8 +201,8 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
         //
         // this rule inspired by a similar rule for auditing and publishing, see DomainObjectAnnotationFacetFactory
         //
-        if(HasUniqueId.class.isAssignableFrom(processMethodContext.getCls())) {
-            // do not install on any implementation of HasUniqueId
+        if(HasInteractionId.class.isAssignableFrom(processMethodContext.getCls())) {
+            // do not install on any implementation of HasInteractionId
             // (ie commands, audit entries, published events).
             return;
         }
@@ -215,17 +215,17 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
     }
 
     void processExecutionPublishing(
-            final ProcessMethodContext processMethodContext, 
+            final ProcessMethodContext processMethodContext,
             final Optional<Action> actionIfAny) {
 
         val facetedMethod = processMethodContext.getFacetHolder();
-        
+
         //
         // this rule inspired by a similar rule for auditing and publishing, see DomainObjectAnnotationFacetFactory
         // and for commands, see above
         //
-        if(HasUniqueId.class.isAssignableFrom(processMethodContext.getCls())) {
-            // do not install on any implementation of HasUniqueId
+        if(HasInteractionId.class.isAssignableFrom(processMethodContext.getCls())) {
+            // do not install on any implementation of HasInteractionId
             // (ie commands, audit entries, published events).
             return;
         }
@@ -278,10 +278,10 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract {
                         new AssociatedWithFacetForActionAnnotation(associateWith, facetedMethod));
             }
         });
-        
+
 
     }
-    
+
     void processFileAccept(final ProcessMethodContext processMethodContext, Optional<Action> actionIfAny) {
 
         val holder = processMethodContext.getFacetHolder();
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
index a19bad6..43ded7d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
@@ -40,7 +40,7 @@ import org.apache.isis.applib.events.lifecycle.ObjectRemovingEvent;
 import org.apache.isis.applib.events.lifecycle.ObjectUpdatedEvent;
 import org.apache.isis.applib.events.lifecycle.ObjectUpdatingEvent;
 import org.apache.isis.applib.id.LogicalType;
-import org.apache.isis.commons.having.HasUniqueId;
+import org.apache.isis.applib.mixins.system.HasInteractionId;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.collections._Multimaps;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
@@ -135,8 +135,8 @@ implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory
         // this rule originally implemented only in AuditableFacetFromConfigurationFactory
         // but think should apply in general
         //
-        if(HasUniqueId.class.isAssignableFrom(cls)) {
-            // do not install on any implementation of HasUniqueId
+        if(HasInteractionId.class.isAssignableFrom(cls)) {
+            // do not install on any implementation of HasInteractionId
             // (ie commands, audit entries, published events).
             return;
         }
@@ -295,7 +295,7 @@ implements MetaModelRefiner, PostConstructMethodCache, ObjectSpecIdFacetFactory
 
             val mixinFacet = MixinFacetForDomainObjectAnnotation
                     .create(mixinDomainObjectIfAny, cls, facetHolder, getServiceInjector(), mixinTypeValidator);
-            
+
             super.addFacet(mixinFacet);
         }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
index 57f46f1..fe2ded9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
@@ -27,7 +27,7 @@ import javax.validation.constraints.Pattern;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.events.domain.PropertyDomainEvent;
-import org.apache.isis.commons.having.HasUniqueId;
+import org.apache.isis.applib.mixins.system.HasInteractionId;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
@@ -242,8 +242,8 @@ implements MetaModelRefiner {
         //
         // this rule inspired by a similar rule for auditing and publishing, see DomainObjectAnnotationFacetFactory
         //
-        if(HasUniqueId.class.isAssignableFrom(processMethodContext.getCls())) {
-            // do not install on any implementation of HasUniqueId
+        if(HasInteractionId.class.isAssignableFrom(processMethodContext.getCls())) {
+            // do not install on any implementation of HasInteractionId
             // (ie commands, audit entries, published events).
             return;
         }
@@ -277,8 +277,8 @@ implements MetaModelRefiner {
         // this rule inspired by a similar rule for auditing and publishing, see DomainObjectAnnotationFacetFactory
         // and for commands, see above
         //
-        if(HasUniqueId.class.isAssignableFrom(processMethodContext.getCls())) {
-            // do not install on any implementation of HasUniqueId
+        if(HasInteractionId.class.isAssignableFrom(processMethodContext.getCls())) {
+            // do not install on any implementation of HasInteractionId
             // (ie commands, audit entries, published events).
             return;
         }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/inspect/Object_inspectMetamodel.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/inspect/Object_inspectMetamodel.java
index 4c37567..2efd0dc 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/inspect/Object_inspectMetamodel.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/inspect/Object_inspectMetamodel.java
@@ -29,7 +29,7 @@ import org.apache.isis.applib.annotation.RestrictTo;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.graph.tree.TreeNode;
 import org.apache.isis.applib.graph.tree.TreePath;
-import org.apache.isis.applib.mixins.MixinConstants;
+import org.apache.isis.applib.mixins.layout.LayoutMixinConstants;
 import org.apache.isis.applib.services.metamodel.Config;
 import org.apache.isis.applib.services.metamodel.MetaModelService;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
@@ -57,7 +57,7 @@ public class Object_inspectMetamodel {
     public static class ActionDomainEvent
     extends org.apache.isis.applib.IsisModuleApplib.ActionDomainEvent<Object_inspectMetamodel> {}
 
-    @MemberOrder(name = MixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "700.2.1")
+    @MemberOrder(name = LayoutMixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "700.2.1")
     public Object act() {
 
         val pkg = holder.getClass().getPackage().getName();
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridSystemServiceBS3.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridSystemServiceBS3.java
index 3d28ceb..a85d73d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridSystemServiceBS3.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/bootstrap3/GridSystemServiceBS3.java
@@ -50,7 +50,7 @@ import org.apache.isis.applib.layout.grid.bootstrap3.BS3Row;
 import org.apache.isis.applib.layout.grid.bootstrap3.BS3Tab;
 import org.apache.isis.applib.layout.grid.bootstrap3.BS3TabGroup;
 import org.apache.isis.applib.layout.grid.bootstrap3.Size;
-import org.apache.isis.applib.mixins.MixinConstants;
+import org.apache.isis.applib.mixins.layout.LayoutMixinConstants;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Lists;
@@ -86,7 +86,7 @@ public class GridSystemServiceBS3 extends GridSystemServiceAbstract<BS3Grid> {
 
     public static final String TNS = "http://isis.apache.org/applib/layout/grid/bootstrap3";
     public static final String SCHEMA_LOCATION = "http://isis.apache.org/applib/layout/grid/bootstrap3/bootstrap3.xsd";
-    
+
     @Inject private GridReaderUsingJaxb gridReader;
 
     public GridSystemServiceBS3() {
@@ -188,15 +188,15 @@ public class GridSystemServiceBS3 extends GridSystemServiceAbstract<BS3Grid> {
         if(!gridModelIfValid.isPresent()) { // only present if valid
             return false;
         }
-        val gridModel = gridModelIfValid.get(); 
-        
+        val gridModel = gridModelIfValid.get();
+
         val layoutDataFactory = LayoutDataFactory.of(objectSpec);
 
-        // * surplus ... those defined in the grid model but not available with the meta-model 
-        // * missing ... those available with the meta-model but missing in the grid-model 
+        // * surplus ... those defined in the grid model but not available with the meta-model
+        // * missing ... those available with the meta-model but missing in the grid-model
         // (missing properties will be added to the first field-set of the specified column)
-        
-        val surplusAndMissingPropertyIds = 
+
+        val surplusAndMissingPropertyIds =
                 surplusAndMissing(propertyLayoutDataById.keySet(),  oneToOneAssociationById.keySet());
         val surplusPropertyIds = surplusAndMissingPropertyIds.getSurplus();
         val missingPropertyIds = surplusAndMissingPropertyIds.getMissing();
@@ -206,10 +206,10 @@ public class GridSystemServiceBS3 extends GridSystemServiceAbstract<BS3Grid> {
         }
 
         // catalog which associations are bound to an existing field-set
-        // so that (below) we can determine which missing property IDs are not unbound vs 
+        // so that (below) we can determine which missing property IDs are not unbound vs
         // which should be included in the field-set that they are bound to.
         val boundAssociationIdsByFieldSetId = _Maps.<String, Set<String>>newHashMap();
-        
+
         for (val fieldSet : gridModel.fieldSets()) {
             val fieldSetId = fieldSet.getId();
             Set<String> boundAssociationIds = boundAssociationIdsByFieldSetId.get(fieldSetId);
@@ -234,7 +234,7 @@ public class GridSystemServiceBS3 extends GridSystemServiceAbstract<BS3Grid> {
                     Set<String> boundAssociationIds =
                             boundAssociationIdsByFieldSetId.computeIfAbsent(id, k -> _Sets.newLinkedHashSet());
                     boundAssociationIds.add(otoa.getId());
-                } else if(id.equals(MixinConstants.METADATA_LAYOUT_GROUPNAME)) {
+                } else if(id.equals(LayoutMixinConstants.METADATA_LAYOUT_GROUPNAME)) {
                     unboundMetadataContributingIds.add(otoa.getId());
                 }
             }
@@ -252,7 +252,7 @@ public class GridSystemServiceBS3 extends GridSystemServiceAbstract<BS3Grid> {
             for (final String fieldSetId : boundAssociationIdsByFieldSetId.keySet()) {
                 val fieldSet = gridModel.getFieldSet(fieldSetId);
                 val associationIds = boundAssociationIdsByFieldSetId.get(fieldSetId);
-                
+
                 val associations1To1Ids =
                         associationIds.stream()
                         .map(oneToOneAssociationById::get)
@@ -262,7 +262,7 @@ public class GridSystemServiceBS3 extends GridSystemServiceAbstract<BS3Grid> {
                         .collect(Collectors.toList());
 
                 addPropertiesTo(
-                        fieldSet, 
+                        fieldSet,
                         associations1To1Ids,
                         layoutDataFactory::createPropertyLayoutData,
                         propertyLayoutDataById::put);
@@ -292,26 +292,26 @@ public class GridSystemServiceBS3 extends GridSystemServiceAbstract<BS3Grid> {
         }
 
         if(!missingCollectionIds.isEmpty()) {
-            final List<OneToManyAssociation> sortedCollections = 
+            final List<OneToManyAssociation> sortedCollections =
                     _Lists.map(missingCollectionIds, oneToManyAssociationById::get);
-            
+
             sortedCollections.sort(ObjectMember.Comparators.byMemberOrderSequence());
 
-            final List<String> sortedMissingCollectionIds = 
+            final List<String> sortedMissingCollectionIds =
                     _Lists.map(sortedCollections, ObjectAssociation::getId);
 
             final BS3TabGroup bs3TabGroup = gridModel.getTabGroupForUnreferencedCollectionsRef();
             if(bs3TabGroup != null) {
                 addCollectionsTo(
-                        bs3TabGroup, 
-                        sortedMissingCollectionIds, 
+                        bs3TabGroup,
+                        sortedMissingCollectionIds,
                         objectSpec,
                         layoutDataFactory::createCollectionLayoutData);
             } else {
                 final BS3Col bs3Col = gridModel.getColForUnreferencedCollectionsRef();
                 if(bs3Col != null) {
                     addCollectionsTo(
-                        bs3Col, 
+                        bs3Col,
                         sortedMissingCollectionIds,
                         layoutDataFactory::createCollectionLayoutData,
                         collectionLayoutDataById::put);
@@ -324,12 +324,12 @@ public class GridSystemServiceBS3 extends GridSystemServiceAbstract<BS3Grid> {
                 surplusAndMissing(actionLayoutDataById.keySet(), objectActionById.keySet());
         val surplusActionIds = surplusAndMissingActionIds.getSurplus();
         val possiblyMissingActionIds = surplusAndMissingActionIds.getMissing();
-        
+
         final List<String> associatedActionIds = _Lists.newArrayList();
 
-        final List<ObjectAction> sortedPossiblyMissingActions = 
+        final List<ObjectAction> sortedPossiblyMissingActions =
                 _Lists.map(possiblyMissingActionIds, objectActionById::get);
-        
+
         sortedPossiblyMissingActions.sort(ObjectMember.Comparators.byMemberOrderSequence());
 
         final List<String> sortedPossiblyMissingActionIds =
@@ -421,14 +421,14 @@ public class GridSystemServiceBS3 extends GridSystemServiceAbstract<BS3Grid> {
             if(bs3Col != null) {
                 addActionsTo(
                         bs3Col,
-                        missingActionIds, 
+                        missingActionIds,
                         layoutDataFactory::createActionLayoutData,
                         actionLayoutDataById::put);
             } else {
                 final FieldSet fieldSet = gridModel.getFieldSetForUnreferencedActionsRef();
                 if(fieldSet != null) {
                     addActionsTo(
-                            fieldSet, 
+                            fieldSet,
                             missingActionIds,
                             layoutDataFactory::createActionLayoutData,
                             actionLayoutDataById::put);
@@ -444,12 +444,12 @@ public class GridSystemServiceBS3 extends GridSystemServiceAbstract<BS3Grid> {
             final Collection<String> propertyIds,
             final Function<String, PropertyLayoutData> layoutFactory,
             final BiConsumer<String, PropertyLayoutData> onNewLayoutData) {
-        
+
         final Set<String> existingIds =
                 stream(fieldSet.getProperties())
                 .map(PropertyLayoutData::getId)
                 .collect(Collectors.toSet());
-        
+
         for (final String propertyId : propertyIds) {
             if(existingIds.contains(propertyId)) {
                 continue;
@@ -466,7 +466,7 @@ public class GridSystemServiceBS3 extends GridSystemServiceAbstract<BS3Grid> {
             final Collection<String> collectionIds,
             final Function<String, CollectionLayoutData> layoutFactory,
             final BiConsumer<String, CollectionLayoutData> onNewLayoutData) {
-        
+
         for (final String collectionId : collectionIds) {
             val collectionLayoutData = layoutFactory.apply(collectionId);
             tabRowCol.getCollections().add(collectionLayoutData);
@@ -479,7 +479,7 @@ public class GridSystemServiceBS3 extends GridSystemServiceAbstract<BS3Grid> {
             final Collection<String> collectionIds,
             final ObjectSpecification objectSpec,
             final Function<String, CollectionLayoutData> layoutFactory) {
-        
+
         for (final String collectionId : collectionIds) {
             final BS3Tab bs3Tab = new BS3Tab();
             bs3Tab.setName(objectSpec.getAssociationElseFail(collectionId).getName());
@@ -506,7 +506,7 @@ public class GridSystemServiceBS3 extends GridSystemServiceAbstract<BS3Grid> {
             final Collection<String> actionIds,
             final Function<String, ActionLayoutData> layoutFactory,
             final BiConsumer<String, ActionLayoutData> onNewLayoutData) {
-        
+
         for (String actionId : actionIds) {
             val actionLayoutData = layoutFactory.apply(actionId);
             addActionTo(bs3Col, actionLayoutData);
@@ -519,7 +519,7 @@ public class GridSystemServiceBS3 extends GridSystemServiceAbstract<BS3Grid> {
             final Collection<String> actionIds,
             final Function<String, ActionLayoutData> layoutFactory,
             final BiConsumer<String, ActionLayoutData> onNewLayoutData) {
-        
+
         for (String actionId : actionIds) {
             val actionLayoutData = layoutFactory.apply(actionId);
             addActionTo(fieldSet, actionLayoutData);
@@ -530,7 +530,7 @@ public class GridSystemServiceBS3 extends GridSystemServiceAbstract<BS3Grid> {
     private void addActionTo(
             final ActionLayoutDataOwner owner,
             final ActionLayoutData actionLayoutData) {
-        
+
         List<ActionLayoutData> actions = owner.getActions();
         if(actions == null) {
             owner.setActions(actions = _Lists.newArrayList());
@@ -547,7 +547,7 @@ public class GridSystemServiceBS3 extends GridSystemServiceAbstract<BS3Grid> {
         return Character.toLowerCase(c) + str.substring(1).replaceAll("\\s+", "");
     }
 
-        
+
 
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
index fc96481..9fd36d3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
@@ -57,11 +57,11 @@ import org.apache.isis.schema.cmd.v2.CommandDto;
 import lombok.NonNull;
 import lombok.val;
 
-public abstract class ObjectMemberAbstract 
+public abstract class ObjectMemberAbstract
 implements ObjectMember, HasMetaModelContext, HasFacetHolder {
 
     protected ObjectSpecification specificationOf(final Class<?> type) {
-        return type != null 
+        return type != null
                 ? getMetaModelContext().getSpecificationLoader().loadSpecification(type)
                 : null;
     }
@@ -181,7 +181,7 @@ implements ObjectMember, HasMetaModelContext, HasFacetHolder {
             final ManagedObject target,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
-        
+
         val visibilityContext = createVisibleInteractionContext(target, interactionInitiatedBy, where);
         return InteractionUtils.isVisibleResult(this, visibilityContext).createConsent();
     }
@@ -211,7 +211,7 @@ implements ObjectMember, HasMetaModelContext, HasFacetHolder {
             final ManagedObject target,
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
-        
+
         val usabilityContext = createUsableInteractionContext(target, interactionInitiatedBy, where);
         return InteractionUtils.isUsableResult(this, usabilityContext).createConsent();
     }
@@ -245,7 +245,7 @@ implements ObjectMember, HasMetaModelContext, HasFacetHolder {
     ManagedObject mixinAdapterFor(
             @NonNull final Class<?> mixinType,
             @NonNull final ManagedObject mixedInAdapter) {
-        
+
         val spec = getSpecificationLoader().loadSpecification(mixinType);
         val mixinFacet = spec.getFacet(MixinFacet.class);
         val mixinPojo = mixinFacet.instantiate(Objects.requireNonNull(mixedInAdapter.getPojo()));
@@ -325,7 +325,7 @@ implements ObjectMember, HasMetaModelContext, HasFacetHolder {
             // guard here to prevent subsequent mixin actions from
             // trampling over the command's DTO
         } else {
-            val dto = commandDtoFactory.apply(command.getUniqueId());
+            val dto = commandDtoFactory.apply(command.getInteractionId());
             command.updater().setCommandDto(dto);
         }
 
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest.java
index da0ce28..b393e80 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest.java
@@ -27,7 +27,7 @@ import org.jmock.auto.Mock;
 import org.junit.After;
 import org.junit.Before;
 
-import org.apache.isis.commons.having.HasUniqueId;
+import org.apache.isis.applib.mixins.system.HasInteractionId;
 import org.apache.isis.core.config.metamodel.facets.PublishingPolicies;
 import org.apache.isis.core.metamodel.facets.AbstractFacetFactoryJUnit4TestCase;
 import org.apache.isis.core.metamodel.facets.object.domainobject.domainevents.ActionDomainEventDefaultFacetForDomainObjectAnnotation;
@@ -54,7 +54,7 @@ public class ActionAnnotationFacetFactoryTest extends AbstractFacetFactoryJUnit4
         context.checking(new Expectations() {{
             allowing(mockSpecificationLoader).loadSpecification(cls);
             will(returnValue(mockTypeSpec));
-            
+
             allowing(mockSpecificationLoader).loadSpecification(returnType);
             will(returnValue(mockReturnTypeSpec));
         }});
@@ -78,7 +78,7 @@ public class ActionAnnotationFacetFactoryTest extends AbstractFacetFactoryJUnit4
         }});
 
         actionMethod = findMethod(Customer.class, "someAction");
-        
+
     }
 
     @Override
@@ -92,18 +92,18 @@ public class ActionAnnotationFacetFactoryTest extends AbstractFacetFactoryJUnit4
         }
     }
 
-    class SomeHasUniqueId implements HasUniqueId {
+    class SomeHasInteractionId implements HasInteractionId {
         public void someAction() {
         }
 
         @Override
-        public UUID getUniqueId() {
+        public UUID getInteractionId() {
             return null;
         }
 
 
     }
-    
+
     void allowingPublishingConfigurationToReturn(PublishingPolicies.ActionPublishingPolicy value) {
         val config = metaModelContext.getConfiguration();
         config.getApplib().getAnnotation().getAction().setExecutionPublishing(value);
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_commandPublishing.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_commandPublishing.java
index 0cbea06..0fcaa0f 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_commandPublishing.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_commandPublishing.java
@@ -42,14 +42,14 @@ public class ActionAnnotationFacetFactoryTest_commandPublishing extends ActionAn
         val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
         facetFactory.processCommandPublishing(processMethodContext, actionIfAny);
     }
-    
+
     @Test
     public void given_HasUniqueId_thenIgnored() {
         // given
-        final Method actionMethod = findMethod(SomeHasUniqueId.class, "someAction");
+        final Method actionMethod = findMethod(SomeHasInteractionId.class, "someAction");
 
         // when
-        processCommandPublishing(facetFactory, new ProcessMethodContext(SomeHasUniqueId.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processCommandPublishing(facetFactory, new ProcessMethodContext(SomeHasInteractionId.class, null, actionMethod, mockMethodRemover, facetedMethod));
 
         // then
         assertFalse(CommandPublishingFacet.isPublishingEnabled(facetedMethod));
@@ -114,4 +114,4 @@ public class ActionAnnotationFacetFactoryTest_commandPublishing extends ActionAn
 
 
 
-}
\ No newline at end of file
+}
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_executionPublishing.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_executionPublishing.java
index 8af3a67..b822d5b 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_executionPublishing.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_executionPublishing.java
@@ -46,13 +46,13 @@ public class ActionAnnotationFacetFactoryTest_executionPublishing extends Action
         val actionIfAny = processMethodContext.synthesizeOnMethod(Action.class);
         facetFactory.processExecutionPublishing(processMethodContext, actionIfAny);
     }
-    
+
     @Test
     public void given_HasUniqueId_thenIgnored() {
 
-        final Method actionMethod = findMethod(SomeHasUniqueId.class, "someAction");
+        final Method actionMethod = findMethod(SomeHasInteractionId.class, "someAction");
 
-        processExecutionPublishing(facetFactory, new ProcessMethodContext(SomeHasUniqueId.class, null, actionMethod, mockMethodRemover, facetedMethod));
+        processExecutionPublishing(facetFactory, new ProcessMethodContext(SomeHasInteractionId.class, null, actionMethod, mockMethodRemover, facetedMethod));
 
         assertFalse(ExecutionPublishingFacet.isPublishingEnabled(facetedMethod));
 
@@ -304,4 +304,4 @@ public class ActionAnnotationFacetFactoryTest_executionPublishing extends Action
         assertFalse(ExecutionPublishingFacet.isPublishingEnabled(facetedMethod));
     }
 
-}
\ No newline at end of file
+}
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
index b83261b..00e485f 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
@@ -34,7 +34,7 @@ import static org.junit.Assert.assertFalse;
 
 import org.apache.isis.applib.annotation.Bounding;
 import org.apache.isis.applib.annotation.DomainObject;
-import org.apache.isis.commons.having.HasUniqueId;
+import org.apache.isis.applib.mixins.system.HasInteractionId;
 import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.core.config.metamodel.facets.EditingObjectsConfiguration;
 import org.apache.isis.core.config.metamodel.facets.PublishingPolicies;
@@ -81,22 +81,22 @@ public class DomainObjectAnnotationFacetFactoryTest extends AbstractFacetFactory
     }
 
 
-    class SomeHasUniqueId implements HasUniqueId {
+    class SomeHasInteractionId implements HasInteractionId {
 
         @Override
-        public UUID getUniqueId() {
+        public UUID getInteractionId() {
             return null;
         }
 
     }
-    
+
     void allowingEntityChangePublishingToReturn(PublishingPolicies.EntityChangePublishingPolicy value) {
         if(value!=null) {
             val config = super.metaModelContext.getConfiguration();
             config.getApplib().getAnnotation().getDomainObject().setEntityChangePublishing(value);
         }
     }
-    
+
     void allowingObjectsEditingToReturn(EditingObjectsConfiguration value) {
         if(value!=null) {
             final IsisConfiguration config = super.metaModelContext.getConfiguration();
@@ -127,7 +127,7 @@ public class DomainObjectAnnotationFacetFactoryTest extends AbstractFacetFactory
 
             allowingEntityChangePublishingToReturn(PublishingPolicies.EntityChangePublishingPolicy.ALL);
 
-            facetFactory.processEntityChangePublishing(new ProcessClassContext(HasUniqueId.class, mockMethodRemover, facetHolder));
+            facetFactory.processEntityChangePublishing(new ProcessClassContext(HasInteractionId.class, mockMethodRemover, facetHolder));
 
             final Facet facet = facetHolder.getFacet(EntityChangePublishingFacet.class);
             Assert.assertNull(facet);
@@ -157,7 +157,7 @@ public class DomainObjectAnnotationFacetFactoryTest extends AbstractFacetFactory
                 facetFactory.process(new ProcessClassContext(DomainObjectAnnotationFacetFactoryTest.Customer.class, mockMethodRemover, facetHolder));
 
                 final EntityChangePublishingFacet facet = facetHolder.getFacet(EntityChangePublishingFacet.class);
-                Assert.assertNull(facet); 
+                Assert.assertNull(facet);
 
                 expectNoMethodsRemoved();
             }
@@ -292,7 +292,7 @@ public class DomainObjectAnnotationFacetFactoryTest extends AbstractFacetFactory
         public void whenDomainObjectAndAutoCompleteRepository() {
 
             facetFactory.process(new ProcessClassContext(
-                    CustomerWithDomainObjectAndAutoCompleteRepository.class, mockMethodRemover, facetHolder)); 
+                    CustomerWithDomainObjectAndAutoCompleteRepository.class, mockMethodRemover, facetHolder));
 
             final Facet facet = facetHolder.getFacet(AutoCompleteFacet.class);
             Assert.assertNotNull(facet);
@@ -503,7 +503,7 @@ public class DomainObjectAnnotationFacetFactoryTest extends AbstractFacetFactory
                         CustomerWithDomainObjectAndEditingSetToEnabled.class, mockMethodRemover, facetHolder));
 
                 final ImmutableFacet facet = facetHolder.getFacet(ImmutableFacet.class);
-                Assert.assertNull(facet); 
+                Assert.assertNull(facet);
 
                 expectNoMethodsRemoved();
             }
@@ -662,4 +662,4 @@ public class DomainObjectAnnotationFacetFactoryTest extends AbstractFacetFactory
     }
 
 
-}
\ No newline at end of file
+}
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/interaction/InteractionDtoFactoryDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/interaction/InteractionDtoFactoryDefault.java
index 6c98a3c..5d3247c 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/interaction/InteractionDtoFactoryDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/interaction/InteractionDtoFactoryDefault.java
@@ -34,7 +34,7 @@ import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.applib.services.iactn.Interaction;
 import org.apache.isis.applib.services.iactn.InteractionContext;
-import org.apache.isis.applib.services.iactn.Sequence;
+import org.apache.isis.applib.services.iactn.SequenceType;
 import org.apache.isis.applib.services.user.UserService;
 import org.apache.isis.applib.util.schema.CommandDtoUtils;
 import org.apache.isis.applib.util.schema.InteractionDtoUtils;
@@ -83,7 +83,7 @@ public class InteractionDtoFactoryDefault implements InteractionDtoFactory {
                 "action's parameter count and provided argument count must match");
 
         final Interaction interaction = interactionContextProvider.get().currentInteractionElseFail();
-        final int nextEventSequence = interaction.next(Sequence.INTERACTION.id());
+        final int nextEventSequence = interaction.next(SequenceType.EXECUTION);
 
         final Bookmark targetBookmark = targetAdapter.getRootOid()
                 .map(RootOid::asBookmark)
@@ -128,7 +128,7 @@ public class InteractionDtoFactoryDefault implements InteractionDtoFactory {
 
         final Interaction interaction = interactionContextProvider.get().currentInteractionElseFail();
 
-        final int nextEventSequence = interaction.next(Sequence.INTERACTION.id());
+        final int nextEventSequence = interaction.next(SequenceType.EXECUTION);
 
         final Bookmark targetBookmark = targetAdapter.getRootOid()
                 .map(RootOid::asBookmark)
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
index a2f8454..220c8d0 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
@@ -116,7 +116,7 @@ import lombok.val;
 @Qualifier("Default")
 //@Log4j2
 public class WrapperFactoryDefault implements WrapperFactory {
-    
+
     @Inject InteractionTracker interactionTracker;
     @Inject FactoryService factoryService;
     @Inject MetaModelContext metaModelContext;
@@ -130,13 +130,13 @@ public class WrapperFactoryDefault implements WrapperFactory {
     private final Map<Class<? extends InteractionEvent>, InteractionEventDispatcher>
         dispatchersByEventClass = new HashMap<>();
     private ProxyContextHandler proxyContextHandler;
-    
+
     @PostConstruct
     public void init() {
 
         val proxyCreator = new ProxyCreator(proxyFactoryService);
         proxyContextHandler = new ProxyContextHandler(proxyCreator);
-        
+
         putDispatcher(ObjectTitleEvent.class, InteractionListener::objectTitleRead);
         putDispatcher(PropertyVisibilityEvent.class, InteractionListener::propertyVisible);
         putDispatcher(PropertyUsabilityEvent.class, InteractionListener::propertyUsable);
@@ -156,7 +156,7 @@ public class WrapperFactoryDefault implements WrapperFactory {
     }
 
     // -- WRAPPING
-    
+
     @Override
     public <T> T wrap(
             final @NonNull T domainObject) {
@@ -167,8 +167,8 @@ public class WrapperFactoryDefault implements WrapperFactory {
     public <T> T wrap(
             final @NonNull T domainObject,
             final @NonNull SyncControl syncControl) {
-        
-        // skip in support of JUnit tests, that don't inject a SpecificationLoader 
+
+        // skip in support of JUnit tests, that don't inject a SpecificationLoader
         if(specificationLoader!=null) {
             val spec = specificationLoader.loadSpecification(domainObject.getClass());
             if(spec.isMixin()) {
@@ -176,12 +176,12 @@ public class WrapperFactoryDefault implements WrapperFactory {
                         + "use WrapperFactory.wrapMixin(...) instead");
             }
         }
-        
+
         if (isWrapper(domainObject)) {
             val wrapperObject = (WrappingObject) domainObject;
             val executionMode = wrapperObject.__isis_executionModes();
             if(equivalent(executionMode, syncControl.getExecutionModes())) {
-                return domainObject;    
+                return domainObject;
             }
             val underlyingDomainObject = wrapperObject.__isis_wrapped();
             return _Casts.uncheckedCast(createProxy(underlyingDomainObject, syncControl));
@@ -199,29 +199,29 @@ public class WrapperFactoryDefault implements WrapperFactory {
 
     @Override
     public <T> T wrapMixin(
-            final @NonNull Class<T> mixinClass, 
+            final @NonNull Class<T> mixinClass,
             final @NonNull Object mixee) {
         return wrapMixin(mixinClass, mixee, control());
     }
 
     @Override
     public <T> T wrapMixin(
-            final @NonNull Class<T> mixinClass, 
-            final @NonNull Object mixee, 
+            final @NonNull Class<T> mixinClass,
+            final @NonNull Object mixee,
             final @NonNull SyncControl syncControl) {
-        
+
         T mixin = factoryService.mixin(mixinClass, mixee);
-        
+
         if (isWrapper(mixee)) {
             val wrapperObject = (WrappingObject) mixee;
             val executionMode = wrapperObject.__isis_executionModes();
             if(equivalent(executionMode, syncControl.getExecutionModes())) {
-                return mixin;    
+                return mixin;
             }
             val underlyingMixee = wrapperObject.__isis_wrapped();
             return _Casts.uncheckedCast(createMixinProxy(underlyingMixee, mixin, syncControl));
         }
-        
+
         return createMixinProxy(mixee, mixin, syncControl);
     }
 
@@ -229,7 +229,7 @@ public class WrapperFactoryDefault implements WrapperFactory {
         val objAdapter = adaptAndGuardAgainstWrappingNotSupported(domainObject);
         return proxyContextHandler.proxy(domainObject, objAdapter, syncControl);
     }
-    
+
     protected <T> T createMixinProxy(Object mixee, T mixin, SyncControl syncControl) {
         val mixeeAdapter = adaptAndGuardAgainstWrappingNotSupported(mixee);
         val mixinAdapter = adaptAndGuardAgainstWrappingNotSupported(mixin);
@@ -264,7 +264,7 @@ public class WrapperFactoryDefault implements WrapperFactory {
             throw _Exceptions.illegalArgument("cannot wrap a mixin instance directly, "
                     + "use WrapperFactory.asyncWrapMixin(...) instead");
         }
-        
+
         val proxyFactory = proxyFactoryService
                 .<T>factory(_Casts.uncheckedCast(domainObject.getClass()), WrappingObject.class);
 
@@ -281,7 +281,7 @@ public class WrapperFactoryDefault implements WrapperFactory {
                             domainObject,
                             null, // mixeeAdapter ignored
                             targetAdapter,
-                            control().withNoExecute(), 
+                            control().withNoExecute(),
                             null);
                     doih.invoke(null, method, args);
                 }
@@ -304,15 +304,15 @@ public class WrapperFactoryDefault implements WrapperFactory {
 
     @Override
     public <T, R> T asyncWrapMixin(
-            final @NonNull Class<T> mixinClass, 
-            final @NonNull Object mixee, 
+            final @NonNull Class<T> mixinClass,
+            final @NonNull Object mixee,
             final @NonNull AsyncControl<R> asyncControl) {
 
         T mixin = factoryService.mixin(mixinClass, mixee);
-        
+
         val mixeeAdapter = adaptAndGuardAgainstWrappingNotSupported(mixee);
         val mixinAdapter = adaptAndGuardAgainstWrappingNotSupported(mixin);
-        
+
         val proxyFactory = proxyFactoryService
                 .factory(mixinClass, new Class[]{WrappingObject.class}, new Class[]{mixee.getClass()});
 
@@ -329,8 +329,8 @@ public class WrapperFactoryDefault implements WrapperFactory {
                     val doih = new DomainObjectInvocationHandler<>(
                             mixin,
                             mixeeAdapter,
-                            mixinAdapter, 
-                            control().withNoExecute(), 
+                            mixinAdapter,
+                            control().withNoExecute(),
                             null);
                     doih.invoke(null, method, args);
                 }
@@ -357,7 +357,7 @@ public class WrapperFactoryDefault implements WrapperFactory {
         val interactionLayer = currentInteractionLayer();
         val asyncAuth = authFrom(asyncControl, interactionLayer.getAuthentication());
         val command = interactionContextProvider.get().currentInteractionElseFail().getCommand();
-        val commandUniqueId = command.getUniqueId();
+        val commandUniqueId = command.getInteractionId();
 
         val targetAdapter = memberAndTarget.getTarget();
         val method = memberAndTarget.getMethod();
@@ -389,10 +389,10 @@ public class WrapperFactoryDefault implements WrapperFactory {
         val executorService = asyncControl.getExecutorService();
         val future = executorService.submit(
                 new ExecCommand<R>(
-                        asyncAuth, 
-                        commandDto, 
-                        asyncControl.getReturnType(), 
-                        command, 
+                        asyncAuth,
+                        commandDto,
+                        asyncControl.getReturnType(),
+                        command,
                         serviceInjector)
         );
 
@@ -402,14 +402,14 @@ public class WrapperFactoryDefault implements WrapperFactory {
     }
 
     private MemberAndTarget memberAndTargetForRegular(
-            final Method method, 
+            final Method method,
             final ManagedObject targetAdapter) {
-        
+
         val objectMember = targetAdapter.getSpecification().getMember(method).orElse(null);
         if(objectMember == null) {
             return MemberAndTarget.notFound();
         }
-        
+
         if (objectMember instanceof OneToOneAssociation) {
             return MemberAndTarget.foundProperty((OneToOneAssociation) objectMember, targetAdapter, method);
         }
@@ -423,8 +423,8 @@ public class WrapperFactoryDefault implements WrapperFactory {
     }
 
     private <T> MemberAndTarget memberAndTargetForMixin(
-            final Method method, 
-            final T mixedIn, 
+            final Method method,
+            final T mixedIn,
             final ManagedObject mixinAdapter) {
 
         val mixinMember = mixinAdapter.getSpecification().getMember(method).orElse(null);
@@ -454,9 +454,9 @@ public class WrapperFactoryDefault implements WrapperFactory {
     }
 
     private static <R> Authentication authFrom(AsyncControl<R> asyncControl, Authentication auth) {
-    
+
         val executionContext = auth.getExecutionContext();
-        
+
         val newExecutionContext = ExecutionContext.builder()
         .clock(Optional.ofNullable(asyncControl.getClock())
                 .orElseGet(executionContext::getClock))
@@ -467,9 +467,9 @@ public class WrapperFactoryDefault implements WrapperFactory {
         .user(Optional.ofNullable(asyncControl.getUser())
                 .orElseGet(executionContext::getUser))
         .build();
-        
+
         return auth.withExecutionContext(newExecutionContext);
-        
+
     }
 
     @Data
@@ -540,27 +540,27 @@ public class WrapperFactoryDefault implements WrapperFactory {
         }
         dispatcher.dispatch(interactionEvent);
     }
-    
+
     // -- HELPER - CHECK WRAPPING SUPPORTED
-    
+
     private ManagedObject adaptAndGuardAgainstWrappingNotSupported(
             final @NonNull Object domainObject) {
-        
+
         val adapter = currentObjectManager().adapt(domainObject);
         if(ManagedObjects.isNullOrUnspecifiedOrEmpty(adapter)
                 || !adapter.getSpecification().getBeanSort().isWrappingSupported()) {
-            throw _Exceptions.illegalArgument("Cannot wrap an object of type %s", 
+            throw _Exceptions.illegalArgument("Cannot wrap an object of type %s",
                     domainObject.getClass().getName());
         }
-        
+
         return adapter;
     }
-    
+
     // -- HELPER - SETUP
-    
+
     private <T extends InteractionEvent> void putDispatcher(
             Class<T> type, BiConsumer<InteractionListener, T> onDispatch) {
-    
+
         val dispatcher = new InteractionEventDispatcherTypeSafe<T>() {
             @Override
             public void dispatchTypeSafe(T interactionEvent) {
@@ -569,7 +569,7 @@ public class WrapperFactoryDefault implements WrapperFactory {
                 }
             }
         };
-        
+
         dispatchersByEventClass.put(type, dispatcher);
     }
 
diff --git a/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/ChangingEntitiesFactory.java b/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/ChangingEntitiesFactory.java
index a223383..d09894a 100644
--- a/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/ChangingEntitiesFactory.java
+++ b/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/ChangingEntitiesFactory.java
@@ -28,7 +28,7 @@ import javax.annotation.Nullable;
 import org.apache.isis.applib.annotation.EntityChangeKind;
 import org.apache.isis.applib.jaxb.JavaSqlXMLGregorianCalendarMarshalling;
 import org.apache.isis.applib.services.iactn.Interaction;
-import org.apache.isis.applib.services.iactn.Sequence;
+import org.apache.isis.applib.services.iactn.SequenceType;
 import org.apache.isis.applib.services.publishing.spi.EntityChanges;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.collections._Maps;
@@ -84,8 +84,8 @@ class ChangingEntitiesFactory {
             final int numberEntityPropertiesModified,
             final Map<ManagedObject, EntityChangeKind> changeKindByEnlistedAdapter) {
 
-        val uniqueId = interaction.getUniqueId();
-        final int nextEventSequence = interaction.next(Sequence.INTERACTION.id());
+        val uniqueId = interaction.getInteractionId();
+        final int nextEventSequence = interaction.next(SequenceType.TRANSACTION);
 
         return new SimpleChangingEntities(
                     uniqueId, nextEventSequence,
diff --git a/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/EntityPropertyChangeFactory.java b/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/EntityPropertyChangeFactory.java
index c00aab0..2a8a554 100644
--- a/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/EntityPropertyChangeFactory.java
+++ b/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/EntityPropertyChangeFactory.java
@@ -30,13 +30,13 @@ import lombok.experimental.UtilityClass;
 
 @UtilityClass
 class EntityPropertyChangeFactory {
-    
+
     public static EntityPropertyChange createEntityPropertyChange(
             final java.sql.Timestamp timestamp,
             final String user,
             final TransactionId txId,
             final PropertyChangeRecord propertyChangeRecord) {
-        
+
         val adapterAndProperty = propertyChangeRecord.getAdapterAndProperty();
         val spec = adapterAndProperty.getAdapter().getSpecification();
 
@@ -50,11 +50,11 @@ class EntityPropertyChangeFactory {
 
         final String targetClass = CommandUtil.targetClassNameFor(spec);
 
-        final UUID transactionId = txId.getUniqueId();
+        final UUID transactionId = txId.getInteractionId();
         final int sequence = txId.getSequence();
 
         return EntityPropertyChange.of(
-                transactionId, sequence, targetClass, target, 
+                transactionId, sequence, targetClass, target,
                 memberId, propertyId, preValue, postValue, user, timestamp);
     }
 }
diff --git a/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/SimpleChangingEntities.java b/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/SimpleChangingEntities.java
index 5d55742..30c87d3 100644
--- a/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/SimpleChangingEntities.java
+++ b/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/SimpleChangingEntities.java
@@ -23,7 +23,7 @@ import java.sql.Timestamp;
 import java.util.UUID;
 import java.util.function.Supplier;
 
-import org.apache.isis.applib.services.RepresentsInteractionMemberExecution;
+import org.apache.isis.applib.mixins.system.HasTransactionId;
 import org.apache.isis.applib.services.publishing.spi.EntityChanges;
 import org.apache.isis.schema.chg.v2.ChangesDto;
 
@@ -34,7 +34,7 @@ import lombok.ToString;
  * Captures which objects were created, updated or deleted in the course of a transaction.
  */
 @ToString
-class SimpleChangingEntities implements EntityChanges, RepresentsInteractionMemberExecution {
+class SimpleChangingEntities implements EntityChanges, HasTransactionId {
 
     private UUID transactionUuid;
     private final int sequence;
@@ -43,7 +43,7 @@ class SimpleChangingEntities implements EntityChanges, RepresentsInteractionMemb
     private final int numberEntitiesLoaded;
     private final int numberEntityPropertiesModified;
     private final Supplier<ChangesDto> changesDtoSupplier;
-    
+
     public SimpleChangingEntities(
             final @NonNull UUID transactionUuid,
             final int sequence,
@@ -63,7 +63,7 @@ class SimpleChangingEntities implements EntityChanges, RepresentsInteractionMemb
     }
 
     @Override
-    public UUID getUniqueId() {
+    public UUID getInteractionId() {
         return transactionUuid;
     }
 
@@ -73,7 +73,7 @@ class SimpleChangingEntities implements EntityChanges, RepresentsInteractionMemb
     }
 
     /**
-     * The date/time at which this set of enlisted objects was created 
+     * The date/time at which this set of enlisted objects was created
      * (approx the completion time of the transaction).
      */
     @Override
diff --git a/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/events/TimestampService.java b/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/events/TimestampService.java
index 4039b19..1a0ad38 100644
--- a/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/events/TimestampService.java
+++ b/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/events/TimestampService.java
@@ -30,8 +30,8 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.services.clock.ClockService;
 import org.apache.isis.applib.services.user.UserService;
-import org.apache.isis.commons.having.HasUpdatedAt;
-import org.apache.isis.commons.having.HasUpdatedBy;
+import org.apache.isis.applib.mixins.updates.OnUpdatedAt;
+import org.apache.isis.applib.mixins.updates.OnUpdatedBy;
 
 import lombok.val;
 
@@ -44,20 +44,20 @@ public class TimestampService {
 
     @Inject private UserService userService;
     @Inject private ClockService clockService;
-    
+
     @EventListener(PreStoreEvent.class)
     public void onPreStore(PreStoreEvent event) {
 
         val persistableObject = event.getPersistableObject();
 
-        if(persistableObject instanceof HasUpdatedBy) {
-            ((HasUpdatedBy)persistableObject).setUpdatedBy(userService.currentUserNameElseNobody());
+        if(persistableObject instanceof OnUpdatedBy) {
+            ((OnUpdatedBy)persistableObject).setUpdatedBy(userService.currentUserNameElseNobody());
         }
-        
-        if(persistableObject instanceof HasUpdatedAt) {
-            ((HasUpdatedAt)persistableObject).setUpdatedAt(clockService.getClock().javaSqlTimestamp());
+
+        if(persistableObject instanceof OnUpdatedAt) {
+            ((OnUpdatedAt)persistableObject).setUpdatedAt(clockService.getClock().javaSqlTimestamp());
         }
-        
+
     }
 
-}
\ No newline at end of file
+}
diff --git a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/CommandSubscriberForJdo.java b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/CommandSubscriberForJdo.java
index 2d6c84a..61dd61a 100644
--- a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/CommandSubscriberForJdo.java
+++ b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/CommandSubscriberForJdo.java
@@ -57,7 +57,7 @@ public class CommandSubscriberForJdo implements CommandSubscriber {
         }
 
         val existingCommandJdoIfAny =
-                commandJdoRepository.findByUniqueId(command.getUniqueId());
+                commandJdoRepository.findByUniqueId(command.getInteractionId());
         if(existingCommandJdoIfAny.isPresent()) {
             if(log.isDebugEnabled()) {
                 // this isn't expected to happen ... we just log the fact if it does
@@ -75,7 +75,7 @@ public class CommandSubscriberForJdo implements CommandSubscriber {
             val parentJdo =
                 parent != null
                     ? commandJdoRepository
-                        .findByUniqueId(parent.getUniqueId())
+                        .findByUniqueId(parent.getInteractionId())
                         .orElse(null)
                     : null;
             commandJdo.setParent(parentJdo);
diff --git a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.java b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.java
index 2b64bc2..dfaf900 100644
--- a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.java
+++ b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.java
@@ -43,7 +43,7 @@ import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.jaxb.JavaSqlXMLGregorianCalendarMarshalling;
-import org.apache.isis.applib.services.DomainChangeRecord;
+import org.apache.isis.applib.mixins.system.DomainChangeRecord;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.applib.services.command.CommandOutcomeHandler;
@@ -117,7 +117,7 @@ import lombok.val;
             value="SELECT "
                     + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE target == :target "
-                    + "&& timestamp >= :from " 
+                    + "&& timestamp >= :from "
                     + "&& timestamp <= :to "
                     + "ORDER BY this.timestamp DESC"),
     @javax.jdo.annotations.Query(
@@ -144,7 +144,7 @@ import lombok.val;
             name="findByTimestampBetween",
             value="SELECT "
                     + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
-                    + "WHERE timestamp >= :from " 
+                    + "WHERE timestamp >= :from "
                     + "&&    timestamp <= :to "
                     + "ORDER BY this.timestamp DESC"),
     @javax.jdo.annotations.Query(
@@ -272,8 +272,8 @@ public class CommandJdo
      * @param command
      */
     public CommandJdo(final Command command) {
-        
-        setUniqueIdStr(command.getUniqueId().toString());
+
+        setUniqueIdStr(command.getInteractionId().toString());
         setUsername(command.getUsername());
         setTimestamp(command.getTimestamp());
 
@@ -374,7 +374,7 @@ public class CommandJdo
     @Getter @Setter
     private String uniqueIdStr;
     @Programmatic
-    public UUID getUniqueId() {return UUID.fromString(getUniqueIdStr());}
+    public UUID getInteractionId() {return UUID.fromString(getUniqueIdStr());}
 
 
     public static class UsernameDomainEvent extends PropertyDomainEvent<String> { }
@@ -492,7 +492,7 @@ public class CommandJdo
     public static class DurationDomainEvent extends PropertyDomainEvent<BigDecimal> { }
     /**
      * The number of seconds (to 3 decimal places) that this interaction lasted.
-     * 
+     *
      * <p>
      * Populated only if it has {@link #getCompletedAt() completed}.
      */
@@ -594,7 +594,7 @@ public class CommandJdo
     @Override
     public String toString() {
         return ObjectContracts
-                .toString("uniqueId", CommandJdo::getUniqueId)
+                .toString("uniqueId", CommandJdo::getInteractionId)
                 .thenToString("username", CommandJdo::getUsername)
                 .thenToString("timestamp", CommandJdo::getTimestamp)
                 .thenToString("target", CommandJdo::getTarget)
@@ -631,7 +631,7 @@ public class CommandJdo
                 CommandJdo.this.setResult(resultBookmark.getValue().orElse(null));
                 CommandJdo.this.setException(resultBookmark.getFailure().orElse(null));
             }
-            
+
         };
     }
 
diff --git a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/HasUniqueId_command.java b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/HasUniqueId_command.java
index ba8aa7d..5fa9843 100644
--- a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/HasUniqueId_command.java
+++ b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/HasUniqueId_command.java
@@ -26,7 +26,7 @@ import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.commons.having.HasUniqueId;
+import org.apache.isis.applib.mixins.system.HasInteractionId;
 import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
 import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
 import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
@@ -34,7 +34,7 @@ import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
 
 /**
  * This mixin contributes a <tt>command</tt> action to any (non-command) implementation of
- * {@link org.apache.isis.commons.having.HasUniqueId}; that is: audit entries, and published events.  Thus, it
+ * {@link HasInteractionId}; that is: audit entries, and published events.  Thus, it
  * is possible to navigate from the effect back to the cause.
  *
  * @since 2.0 {@index}
@@ -48,9 +48,9 @@ public class HasUniqueId_command {
     public static class ActionDomainEvent
             extends IsisModuleExtCommandLogImpl.ActionDomainEvent<HasUniqueId_command> { }
 
-    private final HasUniqueId hasUniqueId;
-    public HasUniqueId_command(final HasUniqueId hasUniqueId) {
-        this.hasUniqueId = hasUniqueId;
+    private final HasInteractionId hasInteractionId;
+    public HasUniqueId_command(final HasInteractionId hasInteractionId) {
+        this.hasInteractionId = hasInteractionId;
     }
 
 
@@ -63,14 +63,14 @@ public class HasUniqueId_command {
      * {@link Command#getParent() parent} property.
      */
     public boolean hideAct() {
-        return (hasUniqueId instanceof CommandJdo);
+        return (hasInteractionId instanceof CommandJdo);
     }
     public String disableAct() {
         return findCommand() == null ? "No command found for unique Id": null;
     }
 
     private CommandJdo findCommand() {
-        final UUID transactionId = hasUniqueId.getUniqueId();
+        final UUID transactionId = hasInteractionId.getInteractionId();
         return commandServiceRepository
                 .findByUniqueId(transactionId)
                 .orElse(null);
diff --git a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/HasUsername_recentCommandsByUser.java b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/HasUsername_recentCommandsByUser.java
index 944f156..8f31362 100644
--- a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/HasUsername_recentCommandsByUser.java
+++ b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/HasUsername_recentCommandsByUser.java
@@ -26,7 +26,7 @@ import javax.inject.Inject;
 import org.apache.isis.applib.annotation.Collection;
 import org.apache.isis.applib.annotation.CollectionLayout;
 import org.apache.isis.applib.annotation.MemberOrder;
-import org.apache.isis.commons.having.HasUsername;
+import org.apache.isis.applib.mixins.security.HasUsername;
 import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
 import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
 import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
diff --git a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/Object_recentCommands.java b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/Object_recentCommands.java
index 8e68c15..8f7a0c0 100644
--- a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/Object_recentCommands.java
+++ b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/Object_recentCommands.java
@@ -27,9 +27,9 @@ import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.RestrictTo;
 import org.apache.isis.applib.annotation.SemanticsOf;
+import org.apache.isis.applib.mixins.system.HasInteractionId;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
-import org.apache.isis.commons.having.HasUniqueId;
 import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
 import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
 import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
@@ -40,7 +40,7 @@ import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
 
 /**
  * This mixin contributes a <tt>recentCommands</tt> action to any domain object
- * (unless also {@link HasUniqueId} - commands don't themselves have commands).
+ * (unless also {@link HasInteractionId} - commands don't themselves have commands).
  */
 @Action(
     semantics = SemanticsOf.SAFE,
@@ -67,11 +67,11 @@ public class Object_recentCommands {
         return commandServiceRepository.findRecentByTarget(bookmark);
     }
     /**
-     * Hide if the contributee is itself {@link HasUniqueId}
+     * Hide if the contributee is itself {@link HasInteractionId}
      * (commands don't have commands).
      */
     public boolean hideAct() {
-        return (domainObject instanceof HasUniqueId);
+        return (domainObject instanceof HasInteractionId);
     }
 
     @Inject CommandJdoRepository commandServiceRepository;
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/fetch/CommandFetcher.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/fetch/CommandFetcher.java
index d5a1c0b..6f1b820 100644
--- a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/fetch/CommandFetcher.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/fetch/CommandFetcher.java
@@ -87,7 +87,7 @@ public class CommandFetcher {
     private CommandsDto fetchCommands(final CommandJdo previousHwmIfAny)
             throws StatusException {
 
-        final UUID transactionId = previousHwmIfAny != null ? previousHwmIfAny.getUniqueId() : null;
+        final UUID transactionId = previousHwmIfAny != null ? previousHwmIfAny.getInteractionId() : null;
 
         log.debug("finding commands on primary ...");
 
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java
index b0ea9b0..e3403353 100644
--- a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java
@@ -95,7 +95,7 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
                     // give up if there was a failure; admin will need to fix issue and retry
                     if (hwm.getReplayState() != null &&
                             hwm.getReplayState().isFailed()) {
-                        log.info("Command {} hit replay error", hwm.getUniqueId());
+                        log.info("Command {} hit replay error", hwm.getInteractionId());
                         return;
                     }
                 } else {
@@ -133,7 +133,7 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
 
         commandsToReplay.forEach(commandJdo -> {
 
-            log.info("replaying {}", commandJdo.getUniqueId());
+            log.info("replaying {}", commandJdo.getInteractionId());
 
             //
             // run command
diff --git a/extensions/security/audit-trail/adoc/modules/audit-trail/pages/about.adoc b/extensions/security/audit-trail/adoc/modules/audit-trail/pages/about.adoc
index 648797e..7f48744 100644
--- a/extensions/security/audit-trail/adoc/modules/audit-trail/pages/about.adoc
+++ b/extensions/security/audit-trail/adoc/modules/audit-trail/pages/about.adoc
@@ -15,7 +15,7 @@ The module also provides:
 * `AuditingServiceRepository` service to to search for persisted `AuditEntry``s.
 None of its actions are visible in the user interface (they are all `@Programmatic`).
 
-* `AuditingServiceContributions` which contributes collections to the xref:refguide:applib-cm:roles-mixins-contributees/contributee.adoc#HasUniqueId[HasUniqueId] interface.
+* `AuditingServiceContributions` which contributes collections to the xref:refguide:applib-classes:mixins.adoc[HasUniqueId] interface.
 This will therefore display all audit entries that occurred in a given request/transaction, in other words whenever a command, a published event or another audit entry is displayed.
 
 These services can be activated by updating the `pom.xml` and updating the `AppManifest#getModules()` method.
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUser.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUser.java
index 6e321e5..279a432 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUser.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/ApplicationUser.java
@@ -20,7 +20,7 @@ package org.apache.isis.extensions.secman.api.user;
 
 import java.util.Set;
 
-import org.apache.isis.commons.having.HasUsername;
+import org.apache.isis.applib.mixins.security.HasUsername;
 import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionValueSet;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/HasUsername_open.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/HasUsername_open.java
index 0222e45..efa462d 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/HasUsername_open.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/user/HasUsername_open.java
@@ -24,7 +24,7 @@ import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.i18n.TranslatableString;
-import org.apache.isis.commons.having.HasUsername;
+import org.apache.isis.applib.mixins.security.HasUsername;
 import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.user.ApplicationUser;
 import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
@@ -39,12 +39,12 @@ import lombok.RequiredArgsConstructor;
 public class HasUsername_open {
 
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
-    
+
     private final HasUsername target;
 
     public static class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<HasUsername_open> {}
 
-    
+
     @MemberOrder(name = "User", sequence = "1") // associate with a 'User' property (if any)
     public ApplicationUser act() {
         if (target == null || target.getUsername() == null) {
@@ -52,7 +52,7 @@ public class HasUsername_open {
         }
         return applicationUserRepository.findByUsername(target.getUsername()).orElse(null);
     }
-    
+
     public boolean hideAct() {
         return target instanceof ApplicationUser;
     }
@@ -63,6 +63,6 @@ public class HasUsername_open {
         }
         return null;
     }
-    
+
 
 }
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_datanucleusIdLong.java b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_datanucleusIdLong.java
index 06ac469..87413d1 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_datanucleusIdLong.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_datanucleusIdLong.java
@@ -27,11 +27,20 @@ import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.applib.mixins.MixinConstants;
+import org.apache.isis.applib.mixins.layout.LayoutMixinConstants;
 
 import lombok.RequiredArgsConstructor;
 
 /**
+ * Contributes the value of the id (introduced by enhancing) as a property.
+ *
+ * <p>
+ * Only visible if the id can be cast to a long.
+ * </p>
+ *
+ * @see Persistable_datanucleusVersionLong
+ * @see Persistable_datanucleusVersionTimestamp
+ *
  * @since 2.0 {@index}
  */
 @Property(
@@ -49,7 +58,7 @@ public class Persistable_datanucleusIdLong {
     extends org.apache.isis.applib.IsisModuleApplib.PropertyDomainEvent
     <Persistable_datanucleusIdLong, Long> {}
 
-    @MemberOrder(name = MixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "800.1")
+    @MemberOrder(name = LayoutMixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "800.1")
     public Long prop() {
         final Object objectId = JDOHelper.getObjectId(persistable);
         if(objectId instanceof DatastoreId) {
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_datanucleusVersionLong.java b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_datanucleusVersionLong.java
index d49a3f6..0945867 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_datanucleusVersionLong.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_datanucleusVersionLong.java
@@ -26,11 +26,21 @@ import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.applib.mixins.MixinConstants;
+import org.apache.isis.applib.mixins.layout.LayoutMixinConstants;
 
 import lombok.RequiredArgsConstructor;
 
 /**
+ * Contributes the value of the version (introduced by enhancing, and used by
+ * the ORM for optimistic locking) as a property.
+ *
+ * <p>
+ * Only visible if the version can be cast to a long.
+ * </p>
+ *
+ * @see Persistable_datanucleusIdLong
+ * @see Persistable_datanucleusVersionTimestamp
+ *
  * @since 2.0 {@index}
  */
 @Property(
@@ -48,7 +58,7 @@ public class Persistable_datanucleusVersionLong {
     extends org.apache.isis.applib.IsisModuleApplib.PropertyDomainEvent
     <Persistable_datanucleusVersionLong, Long> {}
 
-    @MemberOrder(name = MixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "800.2")
+    @MemberOrder(name = LayoutMixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "800.2")
     public Long prop() {
         final Object version = JDOHelper.getVersion(persistable);
         return version != null && version instanceof Long ? (Long) version : null;
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_datanucleusVersionTimestamp.java b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_datanucleusVersionTimestamp.java
index e5ff509..d78a54b 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_datanucleusVersionTimestamp.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_datanucleusVersionTimestamp.java
@@ -26,11 +26,21 @@ import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.applib.mixins.MixinConstants;
+import org.apache.isis.applib.mixins.layout.LayoutMixinConstants;
 
 import lombok.RequiredArgsConstructor;
 
 /**
+ * Contributes the value of the version (introduced by enhancing, and used by
+ * the ORM for optimistic locking) as a property.
+ *
+ * <p>
+ * Only visible if the version can be cast to a {@link java.sql.Timestamp}.
+ * </p>
+ *
+ * @see Persistable_datanucleusIdLong
+ * @see Persistable_datanucleusVersionLong
+ *
  * @since 2.0 {@index}
  */
 @Property(
@@ -48,7 +58,7 @@ public class Persistable_datanucleusVersionTimestamp {
     extends org.apache.isis.applib.IsisModuleApplib.PropertyDomainEvent
     <Persistable_datanucleusVersionTimestamp, java.sql.Timestamp> {}
 
-    @MemberOrder(name = MixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "800.2")
+    @MemberOrder(name = LayoutMixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "800.2")
     public java.sql.Timestamp prop() {
         final Object version = JDOHelper.getVersion(persistable);
         return version != null && version instanceof java.sql.Timestamp ? (java.sql.Timestamp) version : null;
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_downloadJdoMetadata.java b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_downloadJdoMetadata.java
index 1c4e684..709e135 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_downloadJdoMetadata.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_downloadJdoMetadata.java
@@ -33,7 +33,7 @@ import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.annotation.RestrictTo;
 import org.apache.isis.applib.annotation.SemanticsOf;
-import org.apache.isis.applib.mixins.MixinConstants;
+import org.apache.isis.applib.mixins.layout.LayoutMixinConstants;
 import org.apache.isis.applib.value.Clob;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.persistence.jdo.applib.services.JdoSupportService;
@@ -41,6 +41,10 @@ import org.apache.isis.persistence.jdo.applib.services.JdoSupportService;
 import lombok.RequiredArgsConstructor;
 
 /**
+ * Provides the ability to download the JDO
+ * <a href="http://www.datanucleus.org/products/datanucleus/jdo/metadata_xml.html">class metadata</a>
+ * as XML.
+ *
  * @since 2.0 {@index}
  */
 @Action(
@@ -61,7 +65,7 @@ public class Persistable_downloadJdoMetadata {
 
     public static class ActionDomainEvent extends org.apache.isis.applib.IsisModuleApplib.ActionDomainEvent<Persistable_downloadJdoMetadata> {}
 
-    @MemberOrder(name = MixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "710.1")
+    @MemberOrder(name = LayoutMixinConstants.METADATA_LAYOUT_GROUPNAME, sequence = "710.1")
     public Clob act(
             @ParameterLayout(named = "File name")
             final String fileName) throws JAXBException, IOException {
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/conf/Configuration_headless.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/conf/Configuration_headless.java
index 57bd20f..8a2ffc3 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/conf/Configuration_headless.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/conf/Configuration_headless.java
@@ -67,20 +67,20 @@ public class Configuration_headless {
 
 //      private final Provider<InteractionContext> interactionContextProvider;
 //      private final CommandDispatcher commandDispatcher;
-        
+
         @Override
         public void beforeEnteringTransactionalBoundary(InteractionSession interactionSession) {
-            _Probe.errOut("Interaction HAS_STARTED conversationId=%s", interactionSession.getUniqueId());
+            _Probe.errOut("Interaction HAS_STARTED conversationId=%s", interactionSession.getInteractionId());
             setupCommandCreateIfMissing();
         }
-        
+
         @Override
         public void afterLeavingTransactionalBoundary(InteractionSession interactionSession) {
-            _Probe.errOut("Interaction IS_ENDING conversationId=%s", interactionSession.getUniqueId());
+            _Probe.errOut("Interaction IS_ENDING conversationId=%s", interactionSession.getInteractionId());
         }
-        
+
         public void setupCommandCreateIfMissing() {
-            
+
 //            val interactionContext = interactionContextProvider.get();
 //            @SuppressWarnings("unused")
 //            final Interaction interaction = Optional.ofNullable(interactionContext.getInteraction())
@@ -91,29 +91,29 @@ public class Configuration_headless {
 //                        return newInteraction;
 //                    });
         }
-        
+
     }
-    
+
     @Bean @Singleton
     public PlatformTransactionManager platformTransactionManager() {
         return new PlatformTransactionManager() {
-            
+
             @Override
             public void rollback(TransactionStatus status) throws TransactionException {
             }
-            
+
             @Override
             public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
                 return null;
             }
-            
+
             @Override
             public void commit(TransactionStatus status) throws TransactionException {
             }
         };
     }
-    
-    
+
+
     @Bean @Singleton
     public MetricsService metricsService() {
         return new MetricsService() {
@@ -132,4 +132,4 @@ public class Configuration_headless {
     }
 
 
-}
\ No newline at end of file
+}
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/jdo/entities/JdoProductComment.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/jdo/entities/JdoProductComment.java
index 0406a41..7868c23 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/jdo/entities/JdoProductComment.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/jdo/entities/JdoProductComment.java
@@ -27,7 +27,7 @@ import javax.jdo.annotations.PersistenceCapable;
 
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.Property;
-import org.apache.isis.commons.having.HasUpdatedByAndAt;
+import org.apache.isis.applib.mixins.updates.OnUpdatedByAndAt;
 
 import lombok.Getter;
 import lombok.Setter;
@@ -36,8 +36,8 @@ import lombok.Setter;
 @DatastoreIdentity(strategy=IdGeneratorStrategy.IDENTITY, column="id")
 @DomainObject(
         objectType = "testdomain.jdo.ProductComment")
-public class JdoProductComment implements HasUpdatedByAndAt {
-    
+public class JdoProductComment implements OnUpdatedByAndAt {
+
     @Property @Column(allowsNull = "false")
     @Getter @Setter private JdoProduct product;
 
@@ -45,12 +45,12 @@ public class JdoProductComment implements HasUpdatedByAndAt {
     @Getter @Setter private String comment;
 
     // -- TIMESTAMPABLE
-    
+
     @Property
     @Getter @Setter private String updatedBy;
-    
+
     @Property
     @Getter @Setter private Timestamp updatedAt;
 
-    
+
 }
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaProductComment.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaProductComment.java
index b98ad00..988befe 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaProductComment.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaProductComment.java
@@ -30,7 +30,7 @@ import javax.persistence.ManyToOne;
 
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.Property;
-import org.apache.isis.commons.having.HasUpdatedByAndAt;
+import org.apache.isis.applib.mixins.updates.OnUpdatedByAndAt;
 
 import lombok.Getter;
 import lombok.Setter;
@@ -38,15 +38,15 @@ import lombok.Setter;
 @Entity
 @DomainObject(
         objectType = "testdomain.jpa.ProductComment")
-public class JpaProductComment implements HasUpdatedByAndAt {
+public class JpaProductComment implements OnUpdatedByAndAt {
 
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     @Getter @Setter @Column(name = "id")
     private Long id;
-    
+
     // n:1 relation
-    @Property 
+    @Property
     @ManyToOne @JoinColumn(nullable = false)
     private @Getter @Setter JpaProduct product;
 
@@ -54,12 +54,12 @@ public class JpaProductComment implements HasUpdatedByAndAt {
     private @Getter @Setter String comment;
 
     // -- TIMESTAMPABLE
-    
+
     @Property
     private @Getter @Setter String updatedBy;
-    
+
     @Property
     private @Getter @Setter Timestamp updatedAt;
 
-    
+
 }
diff --git a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/mixins/Object_clearHints.java b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/mixins/Object_clearHints.java
index 7ea5ee8..06594d3 100644
--- a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/mixins/Object_clearHints.java
+++ b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/mixins/Object_clearHints.java
@@ -32,6 +32,31 @@ import org.apache.isis.viewer.wicket.viewer.services.HintStoreUsingWicketSession
 import lombok.RequiredArgsConstructor;
 import lombok.val;
 
+/**
+ * Provides the ability for the end-user to discard these UI hints so that the
+ * object is rendered in its initial state:
+ *
+ * <p>
+ * When a domain object is rendered the end-user can select different tabs,
+ * and for collections can sort the columns, navigate to second pages, or
+ * select different views of collections.
+ * If the user revisits that object, the Wicket viewer (at least) will remember
+ * these hints and render the domain object in the same state.
+ * </p>
+ *
+ * <p>
+ * These rendering hints are also included if the user copies the URL using
+ * the anchor link (to right hand of the object's title).
+ * </p>
+ *
+ * <p>
+ *     This mixin - contributed to <code>java.lang.Object</code> and therefore
+ *     to allo domain objects - provides the ability for the end user to clear
+ *     any hints that might have been set for the domain object being rendered.
+ * </p>
+ *
+ * @see HintStore {@index}
+ */
 @Action(
         domainEvent = Object_clearHints.ActionDomainEvent.class,
         semantics = SemanticsOf.IDEMPOTENT,