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/02/13 07:54:02 UTC

[isis] 02/02: ISIS-2444: moves Execution out of Interaction so no longer a nested class.

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

commit 360b43deb7f9a321106d4c120281cd11f5556d16
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Sat Feb 13 07:53:32 2021 +0000

    ISIS-2444: moves Execution out of Interaction so no longer a nested class.
    
    This is to make it easier to document
---
 .../pages/Execution/hooks/examples_and_usage.adoc  |  27 ++
 .../hooks/implementation.adoc                      |  26 ++
 .../Interaction/hooks/examples_and_usage.adoc      |  20 +
 .../hooks/implementation.adoc                      |   2 +
 .../applib-svc/pages/InteractionContext.adoc       | 168 +--------
 .../hooks/examples_and_usage.adoc                  |  17 +
 .../InteractionContext/hooks/implementation.adoc   |   3 +
 .../org/apache/isis/applib/annotation/Action.java  |   2 +-
 .../apache/isis/applib/annotation/Property.java    |   3 +-
 .../apache/isis/applib/annotation/Publishing.java  |  11 +-
 .../isis/applib/services/command/Command.java      |  11 +-
 .../applib/services/iactn/ActionInvocation.java    |  30 ++
 .../isis/applib/services/iactn/Execution.java      | 342 +++++++++++++++++
 .../applib/services/iactn/ExecutionContext.java    |  54 +--
 .../isis/applib/services/iactn/Interaction.java    | 417 ++-------------------
 .../applib/services/iactn/InteractionContext.java  |  18 +-
 .../isis/applib/services/iactn/PropertyEdit.java   |  29 ++
 .../isis/applib/services/iactn/Sequence.java       |  36 ++
 .../services/publishing/log/ExecutionLogger.java   |   8 +-
 .../publishing/spi/ExecutionSubscriber.java        |  10 +-
 .../applib/util/schema/InteractionDtoUtils.java    |  29 +-
 .../apache/isis/core/config/IsisConfiguration.java |  42 +--
 .../core/interaction/session/IsisInteraction.java  |   5 +-
 .../metamodel/execution/InternalInteraction.java   |  13 +-
 .../metamodel/execution/MemberExecutorService.java |  32 +-
 ...ctionInvocationFacetForDomainEventAbstract.java |  48 +--
 .../execution/ExecutionPublishingFacet.java        |  17 +-
 ...tySetterOrClearFacetForDomainEventAbstract.java |  16 +-
 .../services/publishing/ExecutionPublisher.java    |   6 +-
 .../command/CommandExecutorServiceDefault.java     |  12 +-
 .../executor/MemberExecutorServiceDefault.java     |  14 +-
 .../InteractionDtoServiceInternalDefault.java      |  11 +-
 .../publish/ExecutionPublisherDefault.java         |  24 +-
 .../changetracking/ChangingEntitiesFactory.java    |  37 +-
 34 files changed, 793 insertions(+), 747 deletions(-)

diff --git a/api/applib/src/main/adoc/modules/applib-svc/pages/Execution/hooks/examples_and_usage.adoc b/api/applib/src/main/adoc/modules/applib-svc/pages/Execution/hooks/examples_and_usage.adoc
new file mode 100644
index 0000000..9b69e56
--- /dev/null
+++ b/api/applib/src/main/adoc/modules/applib-svc/pages/Execution/hooks/examples_and_usage.adoc
@@ -0,0 +1,27 @@
+
+: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 [...]
+
+
+
+== Usage Notes
+
+``Execution``s can be subscribed to using the xref:system:generated:index/applib/services/publishing/spi/ExecutionSubscriber.adoc[ExecutionSubscriber] interface.
++
+One reason to subscribe is to persist these interaction/executions.
+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:system:generated:index/applib/services/publishing/spi/EntityPropertyChangeSubscriber.adoc[`EntityPropertyChangeSubscriber`]), they provide better audit information, since the parent xref:system:generated:index/applib/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.a [...]
+
+
+== See also
+
+* xref:system:generated:index/applib/services/iactn/Interaction.adoc[Interaction]
+
+* xref:system:generated:index/applib/services/publishing/spi/ExecutionSubscriber.adoc[ExecutionSubscriber]
+
+
+// TODO: mention oubox publisher once ported over from incode-platform
+//xref:mappings:outbox-publisher:about.adoc[Outbox Publisher] mapping module, for example.
+
diff --git a/api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext/hooks/implementation.adoc b/api/applib/src/main/adoc/modules/applib-svc/pages/Execution/hooks/implementation.adoc
similarity index 53%
copy from api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext/hooks/implementation.adoc
copy to api/applib/src/main/adoc/modules/applib-svc/pages/Execution/hooks/implementation.adoc
index 697f559..23a77b5 100644
--- a/api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext/hooks/implementation.adoc
+++ b/api/applib/src/main/adoc/modules/applib-svc/pages/Execution/hooks/implementation.adoc
@@ -4,3 +4,29 @@
 
 
 == Implementation
+
+This is an abstract class with two concrete subclasses
+
+* `ActionInvocation` represents the execution of an action being invoked:
++
+[source,java]
+----
+public class ActionInvocation extends Execution {
+    public List<Object> getArgs();                  // <.>
+}
+----
+
+<.> The objects passed in as the arguments to the action's parameters.
+Any of these could be `null`.
+
+* `PropertyEdit` represents the execution of a property being edited:
+=
+[source,java]
+----
+public class PropertyEdit extends Execution {
+    public Object getNewValue();                    // <.>
+}
+----
+<.> The object used as the new value of the property.
+Could be `null` if the property is being cleared.
+
diff --git a/api/applib/src/main/adoc/modules/applib-svc/pages/Interaction/hooks/examples_and_usage.adoc b/api/applib/src/main/adoc/modules/applib-svc/pages/Interaction/hooks/examples_and_usage.adoc
new file mode 100644
index 0000000..a1325c2
--- /dev/null
+++ b/api/applib/src/main/adoc/modules/applib-svc/pages/Interaction/hooks/examples_and_usage.adoc
@@ -0,0 +1,20 @@
+
+: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 [...]
+
+
+
+== Usage Notes
+
+You could also think of this interface as somewhat analogous to a (database) transaction.
+However, the framework's xref:system:generated:index/applib/services/xactn/TransactionService.adoc[TransactionService] allows programmatic control of underlying database transactions, including the ability to commit one transaction and start a new one (using xref:system:generated:index/applib/services/xactn/TransactionService.adoc#nextTransaction[nextTransaction]).
+The is therefore not an exact mapping between an `Interaction` and a (database) transaction, because the former could span multiple of the latter.
+
+
+
+
+== See Also
+
+* xref:system:generated:index/applib/services/iactn/Execution.adoc[Execution]
+
+* xref:system:generated:index/applib/services/publishing/spi/ExecutionSubscriber.adoc[ExecutionSubscriber]
+
diff --git a/api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext/hooks/implementation.adoc b/api/applib/src/main/adoc/modules/applib-svc/pages/Interaction/hooks/implementation.adoc
similarity index 96%
copy from api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext/hooks/implementation.adoc
copy to api/applib/src/main/adoc/modules/applib-svc/pages/Interaction/hooks/implementation.adoc
index 697f559..92fb556 100644
--- a/api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext/hooks/implementation.adoc
+++ b/api/applib/src/main/adoc/modules/applib-svc/pages/Interaction/hooks/implementation.adoc
@@ -4,3 +4,5 @@
 
 
 == Implementation
+
+This is a concrete class.
diff --git a/api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext.adoc b/api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext.adoc
index 8bb503d..d09af4e 100644
--- a/api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext.adoc
+++ b/api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext.adoc
@@ -4,172 +4,10 @@
 :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 [...]
 
 
+include::system:generated:page$index/applib/services/iactn/InteractionContext.adoc[]
 
-The `InteractionContext` is a request-scoped domain service that is used to obtain the current
-`Interaction`.
+include::InteractionContext/hooks/implementation.adoc[]
 
-An `Interaction` generally consists of a single top-level `Execution`, either to invoke an action or to edit a property.
-If that top-level action or property uses xref:refguide:applib-svc:WrapperFactory.adoc[`WrapperFactory`] to invoke child actions/properties, then those sub-executions are captured as a call-graph.
-The `Execution` is thus a graph structure.
+include::InteractionContext/hooks/examples_and_usage.adoc[]
 
-If a bulk action is performed (as per an action annotated using xref:refguide:applib-ant:Action.adoc#invokeOn[`@Action#invokeOn`]), then this will result in multiple ``Interaction``s, one per selected object (not one `Interaction` with multiple top-level ``Execution``s).
-
-It is possible for ``Interaction.Execution``s to be persisted; this is supported by the xref:mappings:outbox-publisher:about.adoc[Outbox Publisher] mapping module, for example.
-Persistent``Interaction``s support 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-svc:AuditerService.adoc[`AuditerService`]), they provide better audit information, since the
-`Interaction.Execution` 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[`transactionId`]
-
-== API
-
-The public API of the service consists of several related classes:
-
-* `InteractionContext` domain service itself:
-* `Interaction` class, obtainable from the `InteractionContext`
-+
-The `Interaction` can be used to obtain the `Command` object representing the top-level invocation action/property edit.
-* `Execution` class, obtainable from the `Interaction`.
-
-The `Execution` class itself is abstract; there are two subclasses, `ActionInvocation` and `PropertyEdit`.
-
-== API
-
-include::system:generated:page$index/applib/services/iactn/InteractionContext.adoc[leveloffset=+2]
-
-TODO example migration
-
-.Deprecated Docs
-[WARNING]
-================================
-
-=== `InteractionContext`
-
-The public API of the `InteractionContext` domain service itself consists of simply:
-
-[source,java]
-----
-include::refguide:applib-svc:example$services/iactn/InteractionContext.java[tags="refguide"]
-----
-<.> Returns the currently active {@link Interaction} for this thread.
-
-This class is concrete (that is, it is also the implementation).
-
-
-================================
-
-== API
-
-include::system:generated:page$index/applib/services/iactn/Interaction.adoc[leveloffset=+2]
-
-TODO example migration
-
-.Deprecated Docs
-[WARNING]
-================================
-
-=== `Interaction`
-
-The public API of the `Interaction` class consists of:
-
-[source,java]
-----
-include::refguide:applib-svc:example$services/iactn/Interaction.java[tags="refguide"]
-----
-<.> The unique identifier of this interaction.
-<.> Returns a (list of) execution}s in the order that they were pushed.
-Generally there will be just one entry in this list, but additional entries may arise from the use of mixins/contributions when re-rendering a modified object.
-<.> The current execution.
-<.> The member `Execution` (action invocation or property edit) that preceded the current one.
-<.> Generates numbers in a named sequence.
-Used by the framework both to number successive interaction ``Execution``s and for events published by the xref:refguide:applib-svc:ExecutionSubscriber.adoc[`PublisherService`].
-
-This class is concrete (is also the implementation).
-
-
-================================
-
-=== `Interaction.Execution`
-
-The `Interaction.Execution` (static nested) class represents an action invocation/property edit as a node in a call-stack execution graph.
-Sub-executions can be performed using the
-xref:refguide:applib-svc:WrapperFactory.adoc[`WrapperFactory`].
-
-It has the following public API:
-
-[source,java]
-----
-public abstract class Execution {
-    public Interaction getInteraction();            // <.>
-    public InteractionType getInteractionType();    // <.>
-    public String getMemberIdentifier();            // <.>
-    public Object getTarget();                      // <.>
-
-    public String getTargetClass();                 // <.>
-    public String getTargetMember();
-
-    public Execution getParent();                   // <.>
-    public List<Execution> getChildren();
-
-    public AbstractDomainEvent getEvent();          // <.>
-
-    public Timestamp getStartedAt();                // <.>
-    public Timestamp getCompletedAt();
-
-    public Object getReturned();                    // <.>
-    public Exception getThrew();
-
-    public T getDto();                              // <.>
-}
-----
-
-<.> The owning `Interaction`.
-<.> Whether this is an action invocation or a property edit.
-<.> A string uniquely identifying the action or property (similar to Javadoc syntax).
-<.> The object on which the action is being invoked or property edited.
-In the case of a mixin this will be the mixin object itself (rather than the mixed-in object).
-<.> A human-friendly description of the class of the target object, and of the name of the action invoked/property edited on the target object.
-<.> The parent action/property that invoked this action/property edit (if any), and any actions/property edits made in turn via the xref:refguide:applib-svc:WrapperFactory.adoc[`WrapperFactory`].
-<.> The domain event fired via the xref:refguide:applib-svc:EventBusService.adoc[`EventBusService`] representing the execution of this action invocation/property edit.
-<.> The date/time at which this execution started/completed.
-<.> The object returned by the action invocation/property edit, or the exception thrown.
-For `void` methods and for actions returning collections, the value will be `null`.
-<.> A DTO (instance of the xref:refguide:schema:ixn.adoc["ixn" schema]) being a serializable representation of this action invocation/property edit.
-
-
-There are two concrete subclasses of `Execution`.
-
-The first is `ActionInvocation`, representing the execution of an action being invoked:
-
-[source,java]
-----
-public class ActionInvocation extends Execution {
-    public List<Object> getArgs();                  // <1>
-}
-----
-<1> The objects passed in as the arguments to the action's parameters.
-Any of these could be `null`.
-
-The second is `PropertyEdit`, and naturally enough represents the execution of a property being edited:
-
-[source,java]
-----
-public class PropertyEdit extends Execution {
-    public Object getNewValue();                    // <1>
-}
-----
-<1> The object used as the new value of the property.
-Could be `null` if the property is being cleared.
-
-== Implementation
-
-This class (`o.a.i.applib.services.iactn.InteractionContext`) is also the default implementation.
-
-== Interacting with the services
-
-Typically domain objects will have little need to interact with the `InteractionContext` and `Interaction` directly.
-The services are used within the framework however, primarily to support the
-xref:refguide:applib-svc:ExecutionSubscriber.adoc[`PublisherService`] SPI, and to emit domain events over the
-xref:refguide:applib-svc:EventBusService.adoc[`EventBusService`].
 
diff --git a/api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext/hooks/examples_and_usage.adoc b/api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext/hooks/examples_and_usage.adoc
index 21f4ba4..25bb32f 100644
--- a/api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext/hooks/examples_and_usage.adoc
+++ b/api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext/hooks/examples_and_usage.adoc
@@ -2,3 +2,20 @@
 :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 [...]
 
 
+
+
+== Usage Notes
+
+Typically domain objects will have little need to interact with the `InteractionContext` and `Interaction` directly.
+The services are used within the framework however, primarily to support the xref:refguide:applib-svc:ExecutionSubscriber.adoc[ExecutionSubscriber] SPI, and to emit domain events over the xref:refguide:applib-svc:EventBusService.adoc[`EventBusService`].
+
+
+
+== See Also
+
+* xref:system:generated:index/applib/services/iactn/Interaction.adoc[Interaction], as provided by the `InteractionContext`
+
+* xref:system:generated:index/applib/services/iactn/Execution.adoc[Execution], as referenced by xref:system:generated:index/applib/services/iactn/Interaction.adoc[Interaction].
+
+* xref:system:generated:index/applib/services/publishing/spi/ExecutionSubscriber.adoc[ExecutionSubscriber]
+
diff --git a/api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext/hooks/implementation.adoc b/api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext/hooks/implementation.adoc
index 697f559..15474c5 100644
--- a/api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext/hooks/implementation.adoc
+++ b/api/applib/src/main/adoc/modules/applib-svc/pages/InteractionContext/hooks/implementation.adoc
@@ -4,3 +4,6 @@
 
 
 == Implementation
+
+This class (`o.a.i.applib.services.iactn.InteractionContext`) is also the default implementation.
+
diff --git a/api/applib/src/main/java/org/apache/isis/applib/annotation/Action.java b/api/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
index 2a6eaa7..39e5bc4 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
@@ -30,7 +30,7 @@ import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceForCommandDto;
 import org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceForCommandsDto;
 import org.apache.isis.applib.services.commanddto.processor.CommandDtoProcessor;
-import org.apache.isis.applib.services.iactn.Interaction.Execution;
+import org.apache.isis.applib.services.iactn.Execution;
 import org.apache.isis.applib.services.publishing.spi.CommandSubscriber;
 import org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber;
 import org.apache.isis.applib.value.Blob;
diff --git a/api/applib/src/main/java/org/apache/isis/applib/annotation/Property.java b/api/applib/src/main/java/org/apache/isis/applib/annotation/Property.java
index 1bd2227..fe73faf 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/annotation/Property.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/annotation/Property.java
@@ -30,6 +30,7 @@ import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceForCommandDto;
 import org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceForCommandsDto;
 import org.apache.isis.applib.services.commanddto.processor.CommandDtoProcessor;
+import org.apache.isis.applib.services.iactn.Execution;
 import org.apache.isis.applib.services.publishing.spi.CommandSubscriber;
 import org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber;
 import org.apache.isis.applib.spec.Specification;
@@ -112,7 +113,7 @@ public @interface Property {
 
     /**
      * Whether
-     * {@link org.apache.isis.applib.services.iactn.Interaction.Execution}s
+     * {@link Execution}s
      * (triggered property edits), should be dispatched to
      * {@link ExecutionSubscriber}s.
      */
diff --git a/api/applib/src/main/java/org/apache/isis/applib/annotation/Publishing.java b/api/applib/src/main/java/org/apache/isis/applib/annotation/Publishing.java
index e2e5fb6..0a63365 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/annotation/Publishing.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/annotation/Publishing.java
@@ -19,6 +19,7 @@
 package org.apache.isis.applib.annotation;
 
 import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.applib.services.iactn.Execution;
 import org.apache.isis.applib.services.publishing.spi.CommandSubscriber;
 import org.apache.isis.applib.services.publishing.spi.EntityChanges;
 import org.apache.isis.applib.services.publishing.spi.EntityChangesSubscriber;
@@ -27,22 +28,22 @@ import org.apache.isis.applib.services.publishing.spi.EntityPropertyChangeSubscr
 import org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber;
 
 /**
- * The available policies as to whether data should be published to  
- * corresponding subscribers. The framework supports several kinds of data 
+ * The available policies as to whether data should be published to
+ * corresponding subscribers. The framework supports several kinds of data
  * that are available for publishing:
  * <ul>
  * <li><b>{@link EntityChanges} ... subscribed to via {@link EntityChangesSubscriber}</li>
  * <li><b>{@link EntityPropertyChange} ... subscribed to via {@link EntityPropertyChangeSubscriber}</li>
  * <li><b>{@link Command} ... subscribed to via {@link CommandSubscriber}</li>
- * <li><b>{@link org.apache.isis.applib.services.iactn.Interaction.Execution} ... subscribed to via {@link ExecutionSubscriber}</li>
+ * <li><b>{@link Execution} ... subscribed to via {@link ExecutionSubscriber}</li>
  * </ul>
  * @since 1.x {@index}
  */
 public enum Publishing {
 
     /**
-     * Publishing of data triggered by interaction with this object 
-     * should be handled as per the default publishing policy 
+     * Publishing of data triggered by interaction with this object
+     * should be handled as per the default publishing policy
      * configured in <tt>application.properties</tt>.
      * <p>
      * If no publishing policy is configured, then publishing is disabled.
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 2faa4e9..5f4b385 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
@@ -25,6 +25,7 @@ import org.apache.isis.applib.events.domain.ActionDomainEvent;
 import org.apache.isis.applib.jaxb.JavaSqlXMLGregorianCalendarMarshalling;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.commanddto.HasCommandDto;
+import org.apache.isis.applib.services.iactn.Execution;
 import org.apache.isis.applib.services.iactn.Interaction;
 import org.apache.isis.applib.services.publishing.spi.CommandSubscriber;
 import org.apache.isis.applib.services.wrapper.WrapperFactory;
@@ -177,7 +178,7 @@ public class Command implements HasUniqueId, HasUsername, HasCommandDto {
      * which the {@link Interaction} that executed the command started.
      *
      * @see Interaction#getCurrentExecution()
-     * @see Interaction.Execution#getStartedAt()
+     * @see Execution#getStartedAt()
      */
     @Getter
     private Timestamp startedAt;
@@ -188,12 +189,12 @@ public class Command implements HasUniqueId, HasUsername, HasCommandDto {
      *
      * <p>
      *     Previously this field was deprecated (on the basis that the completedAt is also held in
-     *     {@link Interaction.Execution#getCompletedAt()}). However, this property is now used in master/slave
+     *     {@link Execution#getCompletedAt()}). However, this property is now used in master/slave
      *     replay scenarios which may query a persisted Command.
      * </p>
      *
      * See also {@link Interaction#getCurrentExecution()} and
-     * {@link Interaction.Execution#getCompletedAt()}.
+     * {@link Execution#getCompletedAt()}.
      */
     @Getter
     private Timestamp completedAt;
@@ -208,7 +209,7 @@ public class Command implements HasUniqueId, HasUsername, HasCommandDto {
      * </p>
      *
      * See also  {@link Interaction#getCurrentExecution()} and
-     * {@link org.apache.isis.applib.services.iactn.Interaction.Execution#getReturned()}.
+     * {@link Execution#getReturned()}.
      */
     @Getter
     private Bookmark result;
@@ -223,7 +224,7 @@ public class Command implements HasUniqueId, HasUsername, HasCommandDto {
      * </p>
      *
      * See also {@link Interaction#getCurrentExecution()} and
-     * {@link org.apache.isis.applib.services.iactn.Interaction.Execution#getThrew()}.
+     * {@link Execution#getThrew()}.
      */
     @Getter
     private Throwable exception;
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/iactn/ActionInvocation.java b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/ActionInvocation.java
new file mode 100644
index 0000000..c1ed6b5
--- /dev/null
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/ActionInvocation.java
@@ -0,0 +1,30 @@
+package org.apache.isis.applib.services.iactn;
+
+import java.util.List;
+
+import org.apache.isis.applib.events.domain.ActionDomainEvent;
+import org.apache.isis.schema.common.v2.InteractionType;
+import org.apache.isis.schema.ixn.v2.ActionInvocationDto;
+
+import lombok.Getter;
+
+/**
+ * @since 1.x {@index}
+ */
+public class ActionInvocation extends Execution<ActionInvocationDto, ActionDomainEvent<?>> {
+
+    @Getter
+    private final List<Object> args;
+
+    public ActionInvocation(
+            final Interaction interaction,
+            final String memberId,
+            final Object target,
+            final List<Object> args,
+            final String targetMember,
+            final String targetClass) {
+        super(interaction, InteractionType.ACTION_INVOCATION, memberId, target, targetMember, targetClass);
+        this.args = args;
+    }
+    // ...
+}
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/iactn/Execution.java b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/Execution.java
new file mode 100644
index 0000000..eb19372
--- /dev/null
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/Execution.java
@@ -0,0 +1,342 @@
+package org.apache.isis.applib.services.iactn;
+
+import java.sql.Timestamp;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.applib.events.domain.AbstractDomainEvent;
+import org.apache.isis.applib.jaxb.JavaSqlXMLGregorianCalendarMarshalling;
+import org.apache.isis.applib.services.clock.ClockService;
+import org.apache.isis.applib.services.eventbus.EventBusService;
+import org.apache.isis.applib.services.metrics.MetricsService;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.util.schema.MemberExecutionDtoUtils;
+import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.schema.common.v2.DifferenceDto;
+import org.apache.isis.schema.common.v2.InteractionType;
+import org.apache.isis.schema.common.v2.PeriodDto;
+import org.apache.isis.schema.ixn.v2.MemberExecutionDto;
+import org.apache.isis.schema.ixn.v2.MetricsDto;
+import org.apache.isis.schema.ixn.v2.ObjectCountsDto;
+
+import lombok.Getter;
+import lombok.val;
+
+/**
+ * Represents an action invocation/property edit as a node in a call-stack
+ * execution graph, with sub-interactions being made by way of the
+ * {@link WrapperFactory}).
+ *
+ * <p>
+ *     The {@link Interaction} has a reference to a {@link Interaction#getCurrentExecution() top-level} execution.
+ * </p>
+ *
+ * @since 1.x {@index}
+ */
+public abstract class Execution<T extends MemberExecutionDto, E extends AbstractDomainEvent<?>> {
+
+
+    /**
+     * The owning {@link Interaction}.
+     */
+    @Getter
+    private final Interaction interaction;
+
+    /**
+     * Whether this is an
+     * {@link InteractionType#ACTION_INVOCATION action invocation} or a
+     * {@link InteractionType#PROPERTY_EDIT property edit}.
+     */
+    @Getter
+    private final InteractionType interactionType;
+
+    /**
+     * Uniquely identifies the action or property (similar to Javadoc syntax).
+     */
+    @Getter
+    private final String memberIdentifier;
+
+    /**
+     * The target of the action invocation.
+     *
+     * <p>
+     * If this interaction is for a mixin action, then will be the mixed-in
+     * target (not the transient mixin itself).
+     * </p>
+     */
+    @Getter
+    private final Object target;
+
+    /**
+     * A human-friendly description of the class of the target object.
+     */
+    @Getter
+    private final String targetClass;
+
+    /**
+     * The human-friendly name of the action invoked/property edited on the target object.
+     */
+    @Getter
+    private final String targetMember;
+
+    /**
+     * Captures metrics before the Execution Dto is present.
+     */
+    private int numberObjectsLoadedBefore;
+    /**
+     * Captures metrics before the Execution Dto is present.
+     */
+    private int numberObjectsDirtiedBefore;
+
+    protected Execution(
+            final Interaction interaction,
+            final InteractionType interactionType,
+            final String memberIdentifier,
+            final Object target,
+            final String targetMember,
+            final String targetClass) {
+
+        this.interaction = interaction;
+        this.interactionType = interactionType;
+        this.memberIdentifier = memberIdentifier;
+        this.target = target;
+        this.targetMember = targetMember;
+        this.targetClass = targetClass;
+    }
+
+
+    // -- parent, children
+
+    private final List<Execution<?, ?>> children = _Lists.newArrayList();
+
+    /**
+     * The action/property that invoked this action/property edit (if any).
+     */
+    @Getter
+    private Execution<?, ?> parent;
+
+    /**
+     * <b>NOT API</b>: intended to be called only by the framework.
+     */
+    public void setParent(final Execution<?, ?> parent) {
+        this.parent = parent;
+        if (parent != null) {
+            parent.children.add(this);
+        }
+    }
+
+
+    /**
+     * The actions/property edits made in turn via the {@link WrapperFactory}.
+     */
+    public List<Execution<?, ?>> getChildren() {
+
+        return Collections.unmodifiableList(children);
+
+        // ...
+    }
+
+    /**
+     * The domain event fired on the {@link EventBusService event bus} representing the execution of
+     * this action invocation/property edit.
+     *
+     * <p>
+     * This event field is set by the framework before the action invocation/property edit itself;
+     * if read by the executing action/property edit method it will be in the
+     * {@link AbstractDomainEvent.Phase#EXECUTING executing} phase.
+     * </p>
+     */
+    @Getter
+    private E event;
+
+    /**
+     * <b>NOT API</b>: intended to be called only by the framework.
+     */
+    public void setEvent(final E event) {
+        this.event = event;
+    }
+
+    /**
+     * The date/time at which this execution started.
+     */
+    @Getter
+    private Timestamp startedAt;
+
+    /**
+     * The date/time at which this execution completed.
+     */
+    @Getter
+    private Timestamp completedAt;
+
+    public Timestamp start(
+            final ClockService clockService,
+            final MetricsService metricsService) {
+
+        val startedAt = clockService.getClock().javaSqlTimestamp();
+        syncMetrics(When.BEFORE, startedAt, metricsService);
+        return startedAt;
+
+        // ...
+    }
+
+    /**
+     * <b>NOT API</b>: intended to be called only by the framework.
+     */
+    public void setCompletedAt(
+            final Timestamp completedAt,
+            final MetricsService metricsService) {
+        syncMetrics(When.AFTER, completedAt, metricsService);
+    }
+
+    /**
+     * The object returned by the action invocation (for property edits, this
+     * is always <tt>null</tt>).
+     *
+     * <p>
+     * If the action returned either a domain entity or a simple value (and did not throw an
+     * exception) then this object is provided here.
+     *
+     * <p>
+     * For <tt>void</tt> methods and for actions returning collections, the value
+     * will be <tt>null</tt>.
+     * </p>
+     *
+     * <p>
+     *     If the action threw an exception, then the object returned will also
+     *     be <tt>null</tt>; the exception is instead captured in {@link #getThrew()}.
+     * </p>
+     */
+    @Getter
+    private Object returned;
+
+    /**
+     * <b>NOT API</b>: intended to be called only by the framework.
+     */
+    public void setReturned(Object returned) {
+        this.returned = returned;
+    }
+
+    /**
+     * If a property edit or action invocation did not complete successfully
+     * but instead threw an exception, then it is captured here.
+     */
+    @Getter
+    private Exception threw;
+
+    /**
+     * <b>NOT API</b>: intended to be called only by the framework.
+     */
+    public void setThrew(Exception threw) {
+        this.threw = threw;
+    }
+
+
+    // -- dto (property)
+
+    /**
+     * A serializable representation of this action invocation/property edit.
+     *
+     * <p>
+     * This <i>will</i> be populated (by the framework) during the method call itself (representing the
+     * action invocation/property edit), though some fields ({@link Execution#getCompletedAt()},
+     * {@link Execution#getReturned()}) will (obviously) still be null.
+     * </p>
+     */
+    @Getter
+    private T dto;
+
+    /**
+     * <b>NOT API</b>: Set by framework (implementation of
+     * {@link org.apache.isis.core.metamodel.execution.InternalInteraction.MemberExecutor})
+     */
+    public void setDto(final T executionDto) {
+        this.dto = executionDto;
+    }
+
+
+    // -- helpers (syncMetrics)
+
+    enum When {
+        BEFORE {
+            @Override
+            void syncMetrics(
+                    final Execution<?, ?> execution,
+                    final Timestamp timestamp,
+                    final int numberObjectsLoaded,
+                    final int numberObjectsDirtied) {
+
+                execution.startedAt = timestamp;
+                execution.numberObjectsLoadedBefore = numberObjectsLoaded;
+                execution.numberObjectsDirtiedBefore = numberObjectsLoaded;
+            }
+
+            // ....
+        },
+        AFTER {
+            @Override
+            void syncMetrics(
+                    final Execution<?, ?> execution,
+                    final Timestamp timestamp,
+                    final int numberObjectsLoaded,
+                    final int numberObjectsDirtied) {
+
+                execution.completedAt = timestamp;
+
+                final MetricsDto metricsDto = metricsFor(execution);
+
+                final PeriodDto periodDto = timingsFor(metricsDto);
+                periodDto.setStartedAt(JavaSqlXMLGregorianCalendarMarshalling.toXMLGregorianCalendar(execution.startedAt));
+                periodDto.setCompletedAt(JavaSqlXMLGregorianCalendarMarshalling.toXMLGregorianCalendar(execution.completedAt));
+
+                final ObjectCountsDto objectCountsDto = objectCountsFor(metricsDto);
+                numberObjectsLoadedFor(objectCountsDto).setBefore(execution.numberObjectsLoadedBefore);
+                numberObjectsDirtiedFor(objectCountsDto).setBefore(execution.numberObjectsDirtiedBefore);
+
+                numberObjectsLoadedFor(objectCountsDto).setAfter(numberObjectsLoaded);
+                numberObjectsDirtiedFor(objectCountsDto).setAfter(numberObjectsDirtied);
+            }
+
+            // ....
+        };
+
+        // -- helpers
+
+        private static DifferenceDto numberObjectsDirtiedFor(final ObjectCountsDto objectCountsDto) {
+            return MemberExecutionDtoUtils.numberObjectsDirtiedFor(objectCountsDto);
+        }
+
+        private static DifferenceDto numberObjectsLoadedFor(final ObjectCountsDto objectCountsDto) {
+            return MemberExecutionDtoUtils.numberObjectsLoadedFor(objectCountsDto);
+        }
+
+        private static ObjectCountsDto objectCountsFor(final MetricsDto metricsDto) {
+            return MemberExecutionDtoUtils.objectCountsFor(metricsDto);
+        }
+
+        private static MetricsDto metricsFor(final Execution<?, ?> execution) {
+            return MemberExecutionDtoUtils.metricsFor(execution.dto);
+        }
+
+        private static PeriodDto timingsFor(final MetricsDto metricsDto) {
+            return MemberExecutionDtoUtils.timingsFor(metricsDto);
+        }
+
+        abstract void syncMetrics(
+                final Execution<?, ?> teExecution,
+                final Timestamp timestamp,
+                final int numberObjectsLoaded,
+                final int numberObjectsDirtied);
+    }
+
+    private void syncMetrics(
+            final When when,
+            final Timestamp timestamp,
+            final MetricsService metricsService) {
+
+        final int numberObjectsLoaded = metricsService.numberEntitiesLoaded();
+        final int numberObjectsDirtied = metricsService.numberEntitiesDirtied();
+
+        when.syncMetrics(this, timestamp, numberObjectsLoaded, numberObjectsDirtied);
+    }
+
+}
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/iactn/ExecutionContext.java b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/ExecutionContext.java
index cbfa51a..4a88c76 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/iactn/ExecutionContext.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/ExecutionContext.java
@@ -33,51 +33,51 @@ import lombok.Value;
 import lombok.With;
 
 /**
- * Provides the user and scenario specific environment for an {@link Interaction.Execution}
- * 
+ * Provides the user and scenario specific environment for an {@link Execution}
+ *
  * @since 2.0 {@index}
  */
 @Value @Builder
 @RequiredArgsConstructor
-public final class ExecutionContext implements Serializable {
-    
+public class ExecutionContext implements Serializable {
+
     private static final long serialVersionUID = -220896735209733865L;
-    
+
     // -- IMMUTABLE FIELDS
 
     /**
      * The (programmatically) simulated (or actual) user.
-     * 
-     * @apiNote immutable, allows an {@link Interaction} to (logically) run with its 
-     * own simulated (or actual) user 
+     *
+     * @apiNote immutable, allows an {@link Interaction} to (logically) run with its
+     * own simulated (or actual) user
      */
-    @With @Getter @Builder.Default 
-    private final @NonNull UserMemento user = UserMemento.system();
-    
+    @With @Getter @Builder.Default
+    @NonNull UserMemento user = UserMemento.system();
+
     /**
      * The (programmatically) simulated (or actual) clock.
-     * 
-     * @apiNote immutable, allows an {@link Interaction} to (logically) run with its 
-     * own simulated (or actual) clock 
+     *
+     * @apiNote immutable, allows an {@link Interaction} to (logically) run with its
+     * own simulated (or actual) clock
      */
-    @With @Getter @Builder.Default 
-    private final @NonNull VirtualClock clock = VirtualClock.system();
-    
-    @With @Getter @Builder.Default 
-    private final @NonNull Locale locale = Locale.getDefault();
-    
-    @With @Getter @Builder.Default 
-    private final @NonNull TimeZone timeZone = TimeZone.getDefault();
-    
+    @With @Getter @Builder.Default
+    @NonNull VirtualClock clock = VirtualClock.system();
+
+    @With @Getter @Builder.Default
+    @NonNull Locale locale = Locale.getDefault();
+
+    @With @Getter @Builder.Default
+    @NonNull TimeZone timeZone = TimeZone.getDefault();
+
     // -- FACTORIES
-    
+
     /**
-     * Creates a new {@link ExecutionContext} with the specified user and 
+     * Creates a new {@link ExecutionContext} with the specified user and
      * system defaults for clock, locale and time-zone.
      */
     public static ExecutionContext ofUserWithSystemDefaults(
             final @NonNull UserMemento user) {
         return new ExecutionContext(user, VirtualClock.system(), Locale.getDefault(), TimeZone.getDefault());
-    }   
-    
+    }
+
 }
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 5d00103..ea68a44 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,65 +19,68 @@
 
 package org.apache.isis.applib.services.iactn;
 
-import java.sql.Timestamp;
-import java.util.Collections;
 import java.util.List;
+import java.util.UUID;
 
-import org.apache.isis.applib.events.domain.AbstractDomainEvent;
 import org.apache.isis.applib.events.domain.ActionDomainEvent;
 import org.apache.isis.applib.events.domain.PropertyDomainEvent;
-import org.apache.isis.applib.jaxb.JavaSqlXMLGregorianCalendarMarshalling;
-import org.apache.isis.applib.services.clock.ClockService;
 import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.applib.services.eventbus.EventBusService;
-import org.apache.isis.applib.services.metrics.MetricsService;
-import org.apache.isis.applib.services.wrapper.WrapperFactory;
-import org.apache.isis.applib.util.schema.MemberExecutionDtoUtils;
 import org.apache.isis.commons.having.HasUniqueId;
-import org.apache.isis.commons.internal.collections._Lists;
-import org.apache.isis.schema.common.v2.DifferenceDto;
 import org.apache.isis.schema.common.v2.InteractionType;
-import org.apache.isis.schema.common.v2.PeriodDto;
 import org.apache.isis.schema.ixn.v2.ActionInvocationDto;
-import org.apache.isis.schema.ixn.v2.MemberExecutionDto;
-import org.apache.isis.schema.ixn.v2.MetricsDto;
-import org.apache.isis.schema.ixn.v2.ObjectCountsDto;
 import org.apache.isis.schema.ixn.v2.PropertyEditDto;
 
 import lombok.Getter;
-import lombok.val;
 
 /**
- * Represents an action invocation or property modification, resulting in some state change of the system.  It captures
- * not only the target object and arguments passed, but also builds up the call-graph, and captures metrics, eg
- * for profiling.
+ * Represents an action invocation or property modification, resulting in some
+ * state change of the system.  It captures not only the target object and
+ * arguments passed, but also builds up the call-graph, and captures metrics,
+ * eg for profiling.
  *
  * <p>
- *     The distinction between {@link Command} and this object is perhaps subtle: the former represents the
- *     intention to invoke an action/edit a property, whereas this represents the actual invocation/edit itself.
+ *     The `Interaction` can be used to obtain the  {@link Command} object
+ *     representing the top-level invocation action/property edit.
  * </p>
  *
  * <p>
- *     To confuse matters slightly, historically the {@link Command} interface defines members (specifically:
- *     {@link Command#getStartedAt()}, {@link Command#getCompletedAt()}, {@link Command#getResult()},
- *     {@link Command#getException()}) which logically belong to this class instead; they remain in {@link Command}
- *     for backward compatibility only (and have been deprecated).
+ *     The distinction between {@link Command} and this object is perhaps
+ *     subtle: the former represents the intention to invoke an action/edit a
+ *     property, whereas this represents the actual invocation/edit itself.
  * </p>
  *
  * <p>
- *     NOTE: you could also think of this interface as being analogous to the (database) transaction.  The name
- *     &quot;Transaction&quot; has not been used for the interface not chosen however because there is also the
- *     system-level transaction that manages the persistence of
- *     the {@link Command} object itself.
+ *     To confuse matters slightly, historically the {@link Command} interface
+ *     defines members (specifically: {@link Command#getStartedAt()},
+ *     {@link Command#getCompletedAt()}, {@link Command#getResult()},
+ *     {@link Command#getException()}) which logically belong to this class
+ *     instead; they remain in {@link Command} for backward compatibility only
+ *     (and have been deprecated).
  * </p>
  *
- * 
  * @since 1.x revised for 2.0 {@index}
  */
 public interface Interaction extends HasUniqueId {
 
-    Command getCommand();
+    /**
+     * The unique identifier of this interaction (inherited from
+     * {@link HasUniqueId})
+     *
+     * <p>
+     *     This can be used to correlate audit records and transactions
+     *     happening as a consequence or within the interaction.
+     * </p>
+     *
+     * @return
+     */
+    @Override
+    UUID getUniqueId();
 
+    /**
+     * Represents the <i>intention</i> to perform this interaction.
+     * @return
+     */
+    Command getCommand();
 
     /**
      * The current (most recently pushed) {@link Execution}.
@@ -91,364 +94,12 @@ public interface Interaction extends HasUniqueId {
 
 
     /**
-     * Enumerates the different reasons why multiple occurrences of a certain type might occur within a single
-     * (top-level) interaction.
-     */
-    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 Interaction.Sequence.class.getName() + "#" + name();
-        }
-    }
-
-    /**
      * 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.
      */
     int next(final String sequenceId);
-    
-
-
-    /**
-     * Represents an action invocation/property edit as a node in a call-stack execution graph, with sub-interactions
-     * being made by way of the {@link WrapperFactory}).
-     */
-    public static abstract class Execution<T extends MemberExecutionDto, E extends AbstractDomainEvent<?>> {
-
-        @Getter
-        private final Interaction interaction;
-        @Getter
-        private final InteractionType interactionType;
-        @Getter
-        private final String memberIdentifier;
-
-        /**
-         * The target of the action invocation.  If this interaction is for a mixin action, then will be the
-         * mixed-in target (not the transient mixin itself).
-         */
-        @Getter
-        private final Object target;
-
-        /**
-         * A human-friendly description of the class of the target object.
-         */
-        @Getter
-        private final String targetClass;
-
-        /**
-         * The human-friendly name of the action invoked/property edited on the target object.
-         */
-        @Getter
-        private final String targetMember;
-
-
-        /**
-         * Captures metrics before the Execution Dto is present.
-         */
-        private int numberObjectsLoadedBefore;
-        /**
-         * Captures metrics before the Execution Dto is present.
-         */
-        private int numberObjectsDirtiedBefore;
-
-        protected Execution(
-                final Interaction interaction,
-                final InteractionType interactionType,
-                final String memberIdentifier,
-                final Object target,
-                final String targetMember,
-                final String targetClass) {
-
-            this.interaction = interaction;
-            this.interactionType = interactionType;
-            this.memberIdentifier = memberIdentifier;
-            this.target = target;
-            this.targetMember = targetMember;
-            this.targetClass = targetClass;
-        }
-
-
-        // -- parent, children
-
-        private final List<Execution<?,?>> children = _Lists.newArrayList();
-        /**
-         * The action/property that invoked this action/property edit (if any).
-         */
-        @Getter
-        private Execution<?,?> parent;
-
-        /**
-         * <b>NOT API</b>: intended to be called only by the framework.
-         */
-        public void setParent(final Execution<?,?> parent) {
-            this.parent = parent;
-            if(parent != null) {
-                parent.children.add(this);
-            }
-        }
-
-        /**
-         * The actions/property edits made in turn via the {@link WrapperFactory}.
-         */
-        public List<Execution<?,?>> getChildren() {
-
-            return Collections.unmodifiableList(children);
-
-            // ...
-        }
-
-        /**
-         * The domain event fired on the {@link EventBusService event bus} representing the execution of
-         * this action invocation/property edit.
-         *
-         * <p>
-         *     This event field is set by the framework before the action invocation/property edit itself;
-         *     if read by the executing action/property edit method it will be in the
-         *     {@link AbstractDomainEvent.Phase#EXECUTING executing} phase.
-         * </p>
-         */
-        @Getter
-        private E event;
-
-        /**
-         * <b>NOT API</b>: intended to be called only by the framework.
-         */
-        public void setEvent(final E event) {
-            this.event = event;
-        }
-
-        /**
-         * The date/time at which this execution started.
-         */
-        @Getter
-        private Timestamp startedAt;
-
-        /**
-         * The date/time at which this execution completed.
-         */
-        @Getter
-        private Timestamp completedAt;
-
-        public Timestamp start(
-                final ClockService clockService,
-                final MetricsService metricsService) {
-
-            val startedAt = clockService.getClock().javaSqlTimestamp();
-            syncMetrics(When.BEFORE, startedAt, metricsService);
-            return startedAt;
-
-            // ...
-        }
-
-        /**
-         * <b>NOT API</b>: intended to be called only by the framework.
-         */
-        public void setCompletedAt(
-                final Timestamp completedAt,
-                final MetricsService metricsService) {
-            syncMetrics(When.AFTER, completedAt, metricsService);
-        }
-
-        /**
-         * The object returned by the action invocation/property edit.
-         *
-         * <p>
-         * If the action returned either a domain entity or a simple value (and did not throw an
-         * exception) then this object is provided here.
-         *
-         * <p>
-         * For <tt>void</tt> methods and for actions returning collections, the value
-         * will be <tt>null</tt>.
-         */
-        @Getter
-        private Object returned;
-
-        /**
-         * <b>NOT API</b>: intended to be called only by the framework.
-         */
-        public void setReturned(Object returned) {
-            this.returned = returned;
-        }
-
-        @Getter
-        private Exception threw;
-
-        /**
-         * <b>NOT API</b>: intended to be called only by the framework.
-         */
-        public void setThrew(Exception threw) {
-            this.threw = threw;
-        }
-
-
-        // -- dto (property)
-
-        /**
-         * A serializable representation of this action invocation/property edit.
-         *
-         * <p>
-         *     This <i>will</i> be populated (by the framework) during the method call itself (representing the
-         *     action invocation/property edit), though some fields ({@link Execution#getCompletedAt()},
-         *     {@link Execution#getReturned()}) will (obviously) still be null.
-         * </p>
-         */
-        @Getter
-        private T dto;
-
-        /**
-         * <b>NOT API</b>: Set by framework (implementation of 
-         * {@link org.apache.isis.core.metamodel.execution.InternalInteraction.MemberExecutor})
-         */
-        public void setDto(final T executionDto) {
-            this.dto = executionDto;
-        }
-
-
-        // -- helpers (syncMetrics)
-
-        enum When {
-            BEFORE {
-
-                @Override
-                void syncMetrics(
-                        final Execution<?, ?> execution,
-                        final Timestamp timestamp,
-                        final int numberObjectsLoaded,
-                        final int numberObjectsDirtied) {
-
-                    execution.startedAt = timestamp;
-                    execution.numberObjectsLoadedBefore = numberObjectsLoaded;
-                    execution.numberObjectsDirtiedBefore = numberObjectsLoaded;
-                }
-
-                // ....
-            },
-            AFTER {
-
-                @Override void syncMetrics(
-                        final Execution<?, ?> execution,
-                        final Timestamp timestamp,
-                        final int numberObjectsLoaded,
-                        final int numberObjectsDirtied) {
-
-                    execution.completedAt = timestamp;
-
-                    final MetricsDto metricsDto = metricsFor(execution);
-
-                    final PeriodDto periodDto = timingsFor(metricsDto);
-                    periodDto.setStartedAt(JavaSqlXMLGregorianCalendarMarshalling.toXMLGregorianCalendar(execution.startedAt));
-                    periodDto.setCompletedAt(JavaSqlXMLGregorianCalendarMarshalling.toXMLGregorianCalendar(execution.completedAt));
-
-                    final ObjectCountsDto objectCountsDto = objectCountsFor(metricsDto);
-                    numberObjectsLoadedFor(objectCountsDto).setBefore(execution.numberObjectsLoadedBefore);
-                    numberObjectsDirtiedFor(objectCountsDto).setBefore(execution.numberObjectsDirtiedBefore);
-
-                    numberObjectsLoadedFor(objectCountsDto).setAfter(numberObjectsLoaded);
-                    numberObjectsDirtiedFor(objectCountsDto).setAfter(numberObjectsDirtied);
-                }
-
-                // ....
-            };
-
-            // -- helpers
-
-            private static DifferenceDto numberObjectsDirtiedFor(final ObjectCountsDto objectCountsDto) {
-                return MemberExecutionDtoUtils.numberObjectsDirtiedFor(objectCountsDto);
-            }
-
-            private static DifferenceDto numberObjectsLoadedFor(final ObjectCountsDto objectCountsDto) {
-                return MemberExecutionDtoUtils.numberObjectsLoadedFor(objectCountsDto);
-            }
-
-            private static ObjectCountsDto objectCountsFor(final MetricsDto metricsDto) {
-                return MemberExecutionDtoUtils.objectCountsFor(metricsDto);
-            }
-
-            private static MetricsDto metricsFor(final Execution<?, ?> execution) {
-                return MemberExecutionDtoUtils.metricsFor(execution.dto);
-            }
-
-            private static PeriodDto timingsFor(final MetricsDto metricsDto) {
-                return MemberExecutionDtoUtils.timingsFor(metricsDto);
-            }
-
-            abstract void syncMetrics(
-                    final Execution<?, ?> teExecution,
-                    final Timestamp timestamp,
-                    final int numberObjectsLoaded,
-                    final int numberObjectsDirtied);
-        }
-
-        private void syncMetrics(
-                final When when,
-                final Timestamp timestamp,
-                final MetricsService metricsService) {
-
-            final int numberObjectsLoaded = metricsService.numberEntitiesLoaded();
-            final int numberObjectsDirtied = metricsService.numberEntitiesDirtied();
-
-            when.syncMetrics(this, timestamp, numberObjectsLoaded, numberObjectsDirtied);
-        }
-
-    }
-
-    public static class ActionInvocation extends Execution<ActionInvocationDto, ActionDomainEvent<?>> {
-
-        @Getter
-        private final List<Object> args;
-
-        public ActionInvocation(
-                final Interaction interaction,
-                final String memberId,
-                final Object target,
-                final List<Object> args,
-                final String targetMember,
-                final String targetClass) {
-            super(interaction, InteractionType.ACTION_INVOCATION, memberId, target, targetMember, targetClass);
-            this.args = args;
-        }
-        // ...
-    }
-
-    public static class PropertyEdit extends Execution<PropertyEditDto, PropertyDomainEvent<?,?>> {
-
-        @Getter
-        private final Object newValue;
-
-        public PropertyEdit(
-                final Interaction interaction,
-                final String memberId,
-                final Object target,
-                final Object newValue,
-                final String targetMember,
-                final String targetClass) {
-            super(interaction, InteractionType.PROPERTY_EDIT, memberId, target, targetMember, targetClass);
-            this.newValue = newValue;
-        }
 
-        // ...
-    }
 
 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/iactn/InteractionContext.java b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/InteractionContext.java
index 524883f..0d58a2e 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/iactn/InteractionContext.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/InteractionContext.java
@@ -24,8 +24,18 @@ import org.apache.isis.commons.internal.exceptions._Exceptions;
 
 /**
  * Provides the current thread's {@link Interaction}.
- * 
- * @since 2.0 {@index}
+ *
+ * <p>
+ * An {@link Interaction}  contains a top-level {@link Execution}
+ * representing the invocation of an action or the editing of a property.
+ * If that top-level action or property uses the
+ * {@link org.apache.isis.applib.services.wrapper.WrapperFactory} domain
+ * service to invoke child actions/properties, then those sub-executions are
+ * captured as a call-graph. The {@link Execution} is thus a
+ * graph structure.
+ * </p>
+ *
+ * @since 1.x {@index}
  */
 public interface InteractionContext {
 
@@ -36,11 +46,11 @@ public interface InteractionContext {
     Optional<Interaction> currentInteraction();
 
     // -- SHORTCUTS
-    
+
     default Interaction currentInteractionElseFail() {
     	return currentInteraction().orElseThrow(()->_Exceptions
     			.illegalState("No InteractionSession on current thread"));
     }
-    
+
 
 }
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/iactn/PropertyEdit.java b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/PropertyEdit.java
new file mode 100644
index 0000000..c6e71c8
--- /dev/null
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/PropertyEdit.java
@@ -0,0 +1,29 @@
+package org.apache.isis.applib.services.iactn;
+
+import org.apache.isis.applib.events.domain.PropertyDomainEvent;
+import org.apache.isis.schema.common.v2.InteractionType;
+import org.apache.isis.schema.ixn.v2.PropertyEditDto;
+
+import lombok.Getter;
+
+/**
+ * @since 1.x {@index}
+ */
+public class PropertyEdit extends Execution<PropertyEditDto, PropertyDomainEvent<?, ?>> {
+
+    @Getter
+    private final Object newValue;
+
+    public PropertyEdit(
+            final Interaction interaction,
+            final String memberId,
+            final Object target,
+            final Object newValue,
+            final String targetMember,
+            final String targetClass) {
+        super(interaction, InteractionType.PROPERTY_EDIT, memberId, target, targetMember, targetClass);
+        this.newValue = newValue;
+    }
+
+    // ...
+}
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
new file mode 100644
index 0000000..5f1de87
--- /dev/null
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/Sequence.java
@@ -0,0 +1,36 @@
+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/publishing/log/ExecutionLogger.java b/api/applib/src/main/java/org/apache/isis/applib/services/publishing/log/ExecutionLogger.java
index 940cff4..03498d9 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/publishing/log/ExecutionLogger.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/publishing/log/ExecutionLogger.java
@@ -26,7 +26,7 @@ import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
-import org.apache.isis.applib.services.iactn.Interaction;
+import org.apache.isis.applib.services.iactn.Execution;
 import org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber;
 import org.apache.isis.applib.util.schema.InteractionDtoUtils;
 import org.apache.isis.schema.ixn.v2.InteractionDto;
@@ -34,7 +34,7 @@ import org.apache.isis.schema.ixn.v2.InteractionDto;
 import lombok.extern.log4j.Log4j2;
 
 /**
- * 
+ *
  * @since 2.0 {@index}
  */
 @Service
@@ -49,9 +49,9 @@ public class ExecutionLogger implements ExecutionSubscriber {
     public boolean isEnabled() {
         return log.isDebugEnabled();
     }
-    
+
     @Override
-    public void onExecution(final Interaction.Execution<?, ?> execution) {
+    public void onExecution(final Execution<?, ?> execution) {
 
         final InteractionDto interactionDto =
                 InteractionDtoUtils.newInteractionDto(execution, InteractionDtoUtils.Strategy.DEEP);
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/publishing/spi/ExecutionSubscriber.java b/api/applib/src/main/java/org/apache/isis/applib/services/publishing/spi/ExecutionSubscriber.java
index b141b31..908951c 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/publishing/spi/ExecutionSubscriber.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/publishing/spi/ExecutionSubscriber.java
@@ -20,7 +20,7 @@ package org.apache.isis.applib.services.publishing.spi;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.Property;
-import org.apache.isis.applib.services.iactn.Interaction;
+import org.apache.isis.applib.services.iactn.Execution;
 import org.apache.isis.applib.util.schema.InteractionDtoUtils;
 import org.apache.isis.commons.having.HasEnabling;
 
@@ -49,7 +49,7 @@ public interface ExecutionSubscriber extends HasEnabling {
     /**
      * Callback to notify that an interaction (an action invocation or property
      * edit, as represented by
-     * {@link org.apache.isis.applib.services.iactn.Interaction.Execution}) has
+     * {@link Execution}) has
      * completed.
      *
      * <p>
@@ -60,12 +60,12 @@ public interface ExecutionSubscriber extends HasEnabling {
      *
      * <p>
      * Most implementations are expected to use
-     * {@link org.apache.isis.applib.services.iactn.Interaction.Execution#getDto()}
+     * {@link Execution#getDto()}
      * to create a serializable XML representation of the execution.
      * The easiest way to do this is using
-     * {@link InteractionDtoUtils#newInteractionDto(Interaction.Execution)}.
+     * {@link InteractionDtoUtils#newInteractionDto(Execution)}.
      * </p>
      */
-    void onExecution(Interaction.Execution<?, ?> execution);
+    void onExecution(Execution<?, ?> execution);
 
 }
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 b715931..ace463d 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
@@ -36,6 +36,7 @@ import javax.xml.bind.Unmarshaller;
 
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
+import org.apache.isis.applib.services.iactn.Execution;
 import org.apache.isis.applib.services.iactn.Interaction;
 import org.apache.isis.applib.util.JaxbUtil;
 import org.apache.isis.commons.internal.base._NullSafe;
@@ -115,30 +116,30 @@ public final class InteractionDtoUtils {
     // -- newInteractionDto
 
     /**
-     * Encapsulates the mechanism for obtaining a {@link MemberExecutionDto} DTO (XML memento) 
-     * of the provided in-memory 
-     * {@link org.apache.isis.applib.services.iactn.Interaction.Execution}.
+     * Encapsulates the mechanism for obtaining a {@link MemberExecutionDto} DTO (XML memento)
+     * of the provided in-memory
+     * {@link Execution}.
      */
     public enum Strategy {
         FLAT {
 
             @Override
-            public MemberExecutionDto dtoFor(final Interaction.Execution<?, ?> execution) {
+            public MemberExecutionDto dtoFor(final Execution<?, ?> execution) {
                 return execution.getDto();
             }
         },
         DEEP {
             @Override
-            public MemberExecutionDto dtoFor(final Interaction.Execution<?, ?> execution) {
+            public MemberExecutionDto dtoFor(final Execution<?, ?> execution) {
                 return traverse(execution);
             }
 
-            private MemberExecutionDto traverse(final Interaction.Execution<?, ?> parentExecution) {
+            private MemberExecutionDto traverse(final Execution<?, ?> parentExecution) {
 
                 final MemberExecutionDto parentDto = clone(parentExecution.getDto());
 
-                final List<Interaction.Execution<?, ?>> children = parentExecution.getChildren();
-                for (Interaction.Execution<?, ?> childExecution : children) {
+                final List<Execution<?, ?>> children = parentExecution.getChildren();
+                for (Execution<?, ?> childExecution : children) {
                     final MemberExecutionDto childDto = clone(childExecution.getDto());
                     final MemberExecutionDto.ChildExecutions childExecutions =
                             InteractionDtoUtils.childExecutionsOf(parentDto);
@@ -158,7 +159,7 @@ public final class InteractionDtoUtils {
         };
 
 
-        public abstract MemberExecutionDto dtoFor(final Interaction.Execution<?, ?> execution);
+        public abstract MemberExecutionDto dtoFor(final Execution<?, ?> execution);
 
     }
 
@@ -173,20 +174,20 @@ public final class InteractionDtoUtils {
 
     /**
      * Creates a {@link InteractionDto} (serializable  to XML) for the provided
-     * {@link org.apache.isis.applib.services.iactn.Interaction.Execution} 
+     * {@link Execution}
      * (the applib object).
      */
-    public static InteractionDto newInteractionDto(final Interaction.Execution<?, ?> execution) {
+    public static InteractionDto newInteractionDto(final Execution<?, ?> execution) {
         return newInteractionDto(execution, Strategy.FLAT);
     }
 
     /**
      * Creates a {@link InteractionDto} (serializable  to XML) for the provided
-     * {@link org.apache.isis.applib.services.iactn.Interaction.Execution} 
+     * {@link Execution}
      * (the applib object).
      */
     public static InteractionDto newInteractionDto(
-            final Interaction.Execution<?, ?> execution,
+            final Execution<?, ?> execution,
             final Strategy strategy) {
 
         final MemberExecutionDto memberExecutionDto = strategy.dtoFor(execution);
@@ -194,7 +195,7 @@ public final class InteractionDtoUtils {
     }
 
     private static InteractionDto newInteractionDto(
-            final Interaction.Execution<?, ?> execution,
+            final Execution<?, ?> execution,
             final MemberExecutionDto executionDto) {
         final Interaction interaction = execution.getInteraction();
         final String transactionId = interaction.getUniqueId().toString();
diff --git a/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java b/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
index a3a7fcb..203f295 100644
--- a/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
+++ b/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
@@ -59,7 +59,7 @@ import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.LabelPosition;
 import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.applib.services.i18n.TranslationService;
-import org.apache.isis.applib.services.iactn.Interaction;
+import org.apache.isis.applib.services.iactn.Execution;
 import org.apache.isis.applib.services.publishing.spi.EntityChangesSubscriber;
 import org.apache.isis.applib.services.publishing.spi.EntityPropertyChangeSubscriber;
 import org.apache.isis.applib.services.userreg.EmailNotificationService;
@@ -655,9 +655,9 @@ public class IsisConfiguration {
                  * {@link org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber} for publishing.
                  *
                  * <p>
-                 *     The service's {@link org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber#publish(Interaction.Execution) publish}
+                 *     The service's {@link org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber#publish(Execution) publish}
                  *     method is called only once per transaction, with
-                 *     {@link Interaction.Execution} collecting details of
+                 *     {@link Execution} collecting details of
                  *     the identity of the target object, the action invoked, the action arguments and the returned
                  *     object (if any).
                  * </p>
@@ -841,9 +841,9 @@ public class IsisConfiguration {
                  * {@link org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber} for publishing.
                  *
                  * <p>
-                 * The service's {@link org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber#publish(Interaction.Execution) publish}
+                 * The service's {@link org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber#publish(Execution) publish}
                  * method is called only once per transaction, with
-                 * {@link Interaction.Execution} collecting details of
+                 * {@link Execution} collecting details of
                  * the identity of the target object, the property edited, and the new value of the property.
                  * </p>
                  *
@@ -1594,7 +1594,7 @@ public class IsisConfiguration {
             public static class Translation {
 
                 private final Po po = new Po();
-                
+
                 /**
                  * Specifies the relative resource path to look for translation files.
                  * <p>
@@ -1646,44 +1646,44 @@ public class IsisConfiguration {
     private final Persistence persistence = new Persistence();
     @Data
     public static class Persistence {
-        
+
         private final Schema schema = new Schema();
         @Data
         public static class Schema {
-            
+
             /**
              * List of additional schemas to be auto-created.
              * <p>
-             * Explicitly creates given list of schemas by using the specified 
-             * {@link #getCreateSchemaSqlTemplate()} to generate the actual SQL 
+             * Explicitly creates given list of schemas by using the specified
+             * {@link #getCreateSchemaSqlTemplate()} to generate the actual SQL
              * statement against the configured data-source.
-             * <p> 
-             * This configuration mechanism does not consider any schema-auto-creation 
+             * <p>
+             * This configuration mechanism does not consider any schema-auto-creation
              * configuration (if any), that independently is provided the standard JPA way.
              */
             private final List<String> autoCreateSchemas = new ArrayList<>();
-            
+
             /**
              * Does lookup additional "mapping-files" in META-INF/orm-<i>name</i>.xml
-             * (equivalent to "mapping-file" entries in persistence.xml) and adds these 
+             * (equivalent to "mapping-file" entries in persistence.xml) and adds these
              * to those that are already configured the <i>Spring Data</i> way (if any).
-             * @implNote not implemented for JDO 
+             * @implNote not implemented for JDO
              */
             private final List<String> additionalOrmFiles = new ArrayList<>();
-            
+
             /**
              * Vendor specific SQL syntax to create a DB schema.
              * <p>
-             * This template is passed through {@link String#format(String, schemaName)} to 
+             * This template is passed through {@link String#format(String, schemaName)} to
              * make the actual SQL statement thats to be used against the configured data-source.
              * <p>
-             * Default template is {@literal CREATE SCHEMA IF NOT EXISTS %S} with the schema name 
+             * Default template is {@literal CREATE SCHEMA IF NOT EXISTS %S} with the schema name
              * converted to upper-case.
-             * <p>  
+             * <p>
              * For MYSQL/MARIADB use escape like {@code `%S`}
              */
             private String createSchemaSqlTemplate = "CREATE SCHEMA IF NOT EXISTS %S";
-        
+
         }
     }
 
@@ -2768,7 +2768,7 @@ public class IsisConfiguration {
         }
     }
 
-    
+
     private final Extensions extensions = new Extensions();
     @Data
     public static class Extensions {
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 9a49559..e5024c1 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
@@ -26,6 +26,9 @@ import java.util.concurrent.atomic.LongAdder;
 
 import org.apache.isis.applib.services.clock.ClockService;
 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.metrics.MetricsService;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.collections._Maps;
@@ -154,7 +157,7 @@ public class IsisInteraction implements InternalInteraction {
     }
 
     private void start(
-            final IsisInteraction.Execution<?,?> execution,
+            final Execution<?,?> execution,
             final ClockService clockService,
             final MetricsService metricsService,
             final Command command) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/execution/InternalInteraction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/execution/InternalInteraction.java
index edd02b5..af0458e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/execution/InternalInteraction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/execution/InternalInteraction.java
@@ -22,7 +22,10 @@ import java.util.concurrent.Callable;
 
 import org.apache.isis.applib.services.clock.ClockService;
 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.Interaction;
+import org.apache.isis.applib.services.iactn.PropertyEdit;
 import org.apache.isis.applib.services.metrics.MetricsService;
 
 /**
@@ -40,10 +43,10 @@ public interface InternalInteraction extends Interaction {
 
     /**
      * Use the provided {@link MemberExecutor} to invoke an action, with the provided
-     * {@link org.apache.isis.applib.services.iactn.Interaction.ActionInvocation} capturing 
+     * {@link ActionInvocation} capturing
      * the details of said action.
      * <p>
-     * Because this both pushes an {@link org.apache.isis.applib.services.iactn.Interaction.Execution} to
+     * Because this both pushes an {@link Execution} to
      * represent the action invocation and then pops it, that completed
      * execution is accessible at {@link Interaction#getPriorExecution()}.
      */
@@ -56,10 +59,10 @@ public interface InternalInteraction extends Interaction {
 
     /**
      * Use the provided {@link MemberExecutor} to edit a property, with the provided
-     * {@link org.apache.isis.applib.services.iactn.Interaction.PropertyEdit} 
+     * {@link PropertyEdit}
      * capturing the details of said property edit.
      * <p>
-     * Because this both pushes an {@link org.apache.isis.applib.services.iactn.Interaction.Execution} to
+     * Because this both pushes an {@link Execution} to
      * represent the property edit and then pops it, that completed
      * execution is accessible at {@link Interaction#getPriorExecution()}.
      */
@@ -69,5 +72,5 @@ public interface InternalInteraction extends Interaction {
             final ClockService clockService,
             final MetricsService metricsService,
             final Command command);
-    
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/execution/MemberExecutorService.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/execution/MemberExecutorService.java
index 4e615ab..97a6cfa 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/execution/MemberExecutorService.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/execution/MemberExecutorService.java
@@ -21,8 +21,8 @@ package org.apache.isis.core.metamodel.execution;
 import java.lang.reflect.Method;
 import java.util.Optional;
 
-import org.apache.isis.applib.services.iactn.Interaction.ActionInvocation;
-import org.apache.isis.applib.services.iactn.Interaction.PropertyEdit;
+import org.apache.isis.applib.services.iactn.ActionInvocation;
+import org.apache.isis.applib.services.iactn.PropertyEdit;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
@@ -40,11 +40,11 @@ import lombok.NonNull;
  * Used by ActionInvocationFacets and PropertySetterOrClearFacets to submit their executions.
  * <p>
  * That is, invoke a domain action or edit a domain property.
- * 
+ *
  * @since 2.0
  */
 public interface MemberExecutorService {
-    
+
     @Deprecated // just a refactoring step
     @FunctionalInterface
     interface ActionExecutorFactory {
@@ -55,7 +55,7 @@ public interface MemberExecutorService {
                 ManagedObject mixinElseRegularAdapter,
                 ManagedObject mixedInAdapter);
     }
-    
+
     @Deprecated // just a refactoring step
     @FunctionalInterface
     interface PropertyExecutorFactory {
@@ -67,45 +67,45 @@ public interface MemberExecutorService {
                 InteractionHead head,
                 EditingVariant editingVariant);
     }
-    
+
     /**
      * Optionally, the currently active {@link InternalInteraction} for the calling thread.
      */
     Optional<InternalInteraction> getInteraction();
 
     // -- SHORTCUTS
-    
+
     default InternalInteraction getInteractionIfAny() {
         return getInteraction().orElse(null);
     }
-    
+
     default InternalInteraction getInteractionElseFail() {
         return getInteraction().orElseThrow(()->_Exceptions
                 .unrecoverable("needs an InteractionSession on current thread"));
     }
-    
+
     // -- REFACTORING
 
     //TODO implementations of this service should also handle domain object events, don't delegate this responsibility to facets
     ManagedObject invokeAction(
-            @NonNull ObjectAction owningAction, 
+            @NonNull ObjectAction owningAction,
             @NonNull InteractionHead head,
-            @NonNull Can<ManagedObject> argumentAdapters, 
+            @NonNull Can<ManagedObject> argumentAdapters,
             @NonNull InteractionInitiatedBy interactionInitiatedBy,
             @NonNull Method method,
-            @NonNull ActionExecutorFactory actionExecutorFactory, 
-            @NonNull FacetHolder facetHolder, 
+            @NonNull ActionExecutorFactory actionExecutorFactory,
+            @NonNull FacetHolder facetHolder,
             @NonNull IdentifiedHolder identifiedHolder);
 
     //TODO implementations of this service should also handle domain object events, don't delegate this responsibility to facets
     ManagedObject setOrClearProperty(
-            @NonNull OneToOneAssociation owningProperty, 
-            @NonNull InteractionHead head, 
+            @NonNull OneToOneAssociation owningProperty,
+            @NonNull InteractionHead head,
             @NonNull ManagedObject newValueAdapter,
             @NonNull InteractionInitiatedBy interactionInitiatedBy,
             @NonNull PropertyExecutorFactory propertyExecutorFactory,
             @NonNull FacetHolder facetHolder,
             @NonNull IdentifiedHolder identifiedHolder,
             @NonNull EditingVariant editingVariant);
-         
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
index 1386db5..936d08e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
@@ -28,7 +28,7 @@ import java.util.Objects;
 
 import org.apache.isis.applib.events.domain.AbstractDomainEvent;
 import org.apache.isis.applib.events.domain.ActionDomainEvent;
-import org.apache.isis.applib.services.iactn.Interaction.ActionInvocation;
+import org.apache.isis.applib.services.iactn.ActionInvocation;
 import org.apache.isis.applib.services.queryresultscache.QueryResultsCache;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
 import org.apache.isis.commons.collections.Can;
@@ -73,7 +73,7 @@ implements ImperativeFacet {
             final ObjectSpecification onType,
             final ObjectSpecification returnType,
             final FacetHolder holder) {
-        
+
         super(holder);
         this.eventType = eventType;
         this.method = method;
@@ -104,7 +104,7 @@ implements ImperativeFacet {
             final Can<ManagedObject> argumentAdapters,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
-        val executionResult = 
+        val executionResult =
                 getTransactionService().callWithinCurrentTransactionElseCreateNew(()->
                     doInvoke(owningAction, head, argumentAdapters, interactionInitiatedBy));
 
@@ -115,7 +115,7 @@ implements ImperativeFacet {
                 .orElse(null);
     }
 
-    @Override 
+    @Override
     public void appendAttributesTo(final Map<String, Object> attributeMap) {
         super.appendAttributesTo(attributeMap);
         ImperativeFacet.Util.appendAttributesTo(this, attributeMap);
@@ -123,31 +123,31 @@ implements ImperativeFacet {
         attributeMap.put("returnType", returnType);
         attributeMap.put("eventType", eventType);
     }
-    
+
     @Override
     protected String toStringValues() {
         return "method=" + method;
     }
-    
+
     // -- HELPER
-    
+
     private ManagedObject doInvoke(
             final ObjectAction owningAction,
             final InteractionHead head,
             final Can<ManagedObject> argumentAdapters,
             final InteractionInitiatedBy interactionInitiatedBy) {
-        
+
         _Assert.assertEquals(owningAction.getParameterCount(), argumentAdapters.size(),
                 "action's parameter count and provided argument count must match");
-        
+
         return getMemberExecutor().invokeAction(
-                owningAction, 
-                head, 
-                argumentAdapters, 
-                interactionInitiatedBy, 
+                owningAction,
+                head,
+                argumentAdapters,
+                interactionInitiatedBy,
                 method,
-                DomainEventMemberExecutor::new, 
-                getFacetHolder(), 
+                DomainEventMemberExecutor::new,
+                getFacetHolder(),
                 getIdentified());
     }
 
@@ -162,7 +162,7 @@ implements ImperativeFacet {
     }
 
     private Object invokeMethodElseFromCache(
-            final ManagedObject targetAdapter, 
+            final ManagedObject targetAdapter,
             final Can<ManagedObject> arguments)
                     throws IllegalAccessException, InvocationTargetException {
 
@@ -210,7 +210,7 @@ implements ImperativeFacet {
         final ManagedObject clonedAdapter = getObjectManager().adapt(clone);
         return clonedAdapter;
     }
-    
+
     private QueryResultsCache getQueryResultsCache() {
         return serviceRegistry.lookupServiceElseFail(QueryResultsCache.class);
     }
@@ -218,11 +218,11 @@ implements ImperativeFacet {
     private InteractionDtoServiceInternal getInteractionDtoServiceInternal() {
         return serviceRegistry.lookupServiceElseFail(InteractionDtoServiceInternal.class);
     }
-    
+
     @RequiredArgsConstructor
-    private final class DomainEventMemberExecutor 
+    private final class DomainEventMemberExecutor
             implements InternalInteraction.MemberExecutor<ActionInvocation> {
-        
+
         private final Can<ManagedObject> argumentAdapters;
         private final ManagedObject targetAdapter;
         private final ObjectAction owningAction;
@@ -241,9 +241,9 @@ implements ImperativeFacet {
                 // update the current execution with the DTO (memento)
                 val invocationDto = getInteractionDtoServiceInternal()
                 .asActionInvocationDto(owningAction, mixinElseRegularAdapter, argumentAdapters);
-                
+
                 currentExecution.setDto(invocationDto);
-                
+
                 val head = InteractionHead.mixedIn(targetAdapter, mixedInAdapter);
 
 
@@ -264,7 +264,7 @@ implements ImperativeFacet {
 
                 // invoke method
                 val resultPojo = invokeMethodElseFromCache(targetAdapter, argumentAdapters);
-                ManagedObject resultAdapterPossiblyCloned = 
+                ManagedObject resultAdapterPossiblyCloned =
                         cloneIfViewModelCloneable(resultPojo, mixinElseRegularAdapter);
 
                 // ... post the executed event
@@ -277,7 +277,7 @@ implements ImperativeFacet {
 
                 final Object returnValue = actionDomainEvent.getReturnValue();
                 if(returnValue != resultPojo) {
-                    resultAdapterPossiblyCloned = 
+                    resultAdapterPossiblyCloned =
                             cloneIfViewModelCloneable(returnValue, mixinElseRegularAdapter);
                 }
                 return UnwrapUtil.single(resultAdapterPossiblyCloned);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/publish/execution/ExecutionPublishingFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/publish/execution/ExecutionPublishingFacet.java
index 38b8ac1..f6d9208 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/publish/execution/ExecutionPublishingFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/publish/execution/ExecutionPublishingFacet.java
@@ -19,6 +19,7 @@
 
 package org.apache.isis.core.metamodel.facets.members.publish.execution;
 
+import org.apache.isis.applib.services.iactn.Execution;
 import org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -28,22 +29,22 @@ import lombok.NonNull;
 import lombok.val;
 
 /**
- * Indicates that details of the action invocation or property edit, 
- * captured by an {@link org.apache.isis.applib.services.iactn.Interaction.Execution},
- * should be dispatched via {@link ExecutionPublisher} to all subscribed 
+ * Indicates that details of the action invocation or property edit,
+ * captured by an {@link Execution},
+ * should be dispatched via {@link ExecutionPublisher} to all subscribed
  * {@link ExecutionSubscriber}s.
  * <p>
- * Corresponds to annotating the action method or property using 
+ * Corresponds to annotating the action method or property using
  * {@code @Action/@Property(executionPublishing=ENABLED)}
- * 
+ *
  * @since 2.0
- * 
+ *
  */
 public interface ExecutionPublishingFacet extends Facet {
-    
+
     public static boolean isPublishingEnabled(final @NonNull FacetHolder facetHolder) {
         val executionPublishingFacet = facetHolder.getFacet(ExecutionPublishingFacet.class);
         return executionPublishingFacet!=null;
     }
-    
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
index f8238c9..5cd6a74 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
@@ -24,7 +24,7 @@ import java.util.Objects;
 
 import org.apache.isis.applib.events.domain.AbstractDomainEvent;
 import org.apache.isis.applib.events.domain.PropertyDomainEvent;
-import org.apache.isis.applib.services.iactn.Interaction;
+import org.apache.isis.applib.services.iactn.PropertyEdit;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.execution.InternalInteraction;
 import org.apache.isis.core.metamodel.facetapi.Facet;
@@ -151,10 +151,10 @@ extends SingleValueFacetAbstract<Class<? extends PropertyDomainEvent<?,?>>> {
         return getTransactionService()
                 .callWithinCurrentTransactionElseCreateNew(() ->
                     doSetOrClearProperty(
-                            style, 
-                            owningProperty, 
-                            InteractionHead.simple(targetAdapter), 
-                            newValueAdapter, 
+                            style,
+                            owningProperty,
+                            InteractionHead.simple(targetAdapter),
+                            newValueAdapter,
                             interactionInitiatedBy))
                 .optionalElseFail()
                 .orElse(null);
@@ -162,7 +162,7 @@ extends SingleValueFacetAbstract<Class<? extends PropertyDomainEvent<?,?>>> {
 
     @RequiredArgsConstructor
     private final class DomainEventMemberExecutor
-            implements InternalInteraction.MemberExecutor<Interaction.PropertyEdit> {
+            implements InternalInteraction.MemberExecutor<PropertyEdit> {
 
         private final ManagedObject newValueAdapter;
         private final OneToOneAssociation owningProperty;
@@ -173,7 +173,7 @@ extends SingleValueFacetAbstract<Class<? extends PropertyDomainEvent<?,?>>> {
         private final InteractionHead head;
         private final EditingVariant style;
 
-        public Object execute(Interaction.PropertyEdit currentExecution) {
+        public Object execute(PropertyEdit currentExecution) {
 
             // TODO: REVIEW - is this safe to do?
             ManagedObject newValueAdapterMutatable = newValueAdapter;
@@ -253,7 +253,7 @@ extends SingleValueFacetAbstract<Class<? extends PropertyDomainEvent<?,?>>> {
         if(!editingVariant.hasCorrespondingFacet(this)) {
             return head.getTarget();
         }
-        
+
         return getMemberExecutor().setOrClearProperty(
                 owningProperty,
                 head,
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/publishing/ExecutionPublisher.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/publishing/ExecutionPublisher.java
index a5a6ebc..a41a9c2 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/publishing/ExecutionPublisher.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/publishing/ExecutionPublisher.java
@@ -20,7 +20,7 @@ package org.apache.isis.core.metamodel.services.publishing;
 
 import java.util.function.Supplier;
 
-import org.apache.isis.applib.services.iactn.Interaction;
+import org.apache.isis.applib.services.iactn.Execution;
 import org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber;
 
 /**
@@ -29,9 +29,9 @@ import org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber;
  */
 public interface ExecutionPublisher {
 
-    void publishActionInvocation(Interaction.Execution<?,?> execution);
+    void publishActionInvocation(Execution<?,?> execution);
 
-    void publishPropertyEdit(Interaction.Execution<?,?> execution);
+    void publishPropertyEdit(Execution<?,?> execution);
 
     /**
      * Slightly hokey wormhole (anti)pattern to disable publishing for mixin associations.
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
index 758148a..f40dc60 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
@@ -40,7 +40,7 @@ import org.apache.isis.applib.services.clock.ClockService;
 import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.applib.services.command.CommandExecutorService;
 import org.apache.isis.applib.services.command.CommandOutcomeHandler;
-import org.apache.isis.applib.services.iactn.Interaction;
+import org.apache.isis.applib.services.iactn.Execution;
 import org.apache.isis.applib.services.iactn.InteractionContext;
 import org.apache.isis.applib.services.sudo.SudoService;
 import org.apache.isis.applib.services.user.UserMemento;
@@ -159,7 +159,7 @@ public class CommandExecutorServiceDefault implements CommandExecutorService {
             log.warn("Exception when executing : {}",
                     dto.getMember().getLogicalMemberIdentifier(), ex);
         });
-        
+
         return handleOutcomeAndSetCompletedAt(commandUpdater, result);
     }
 
@@ -238,7 +238,7 @@ public class CommandExecutorServiceDefault implements CommandExecutorService {
                 final Object targetObject = bookmarkService.lookup(bookmark);
 
                 val targetAdapter = adapterFor(targetObject);
-                
+
                 if(ManagedObjects.isNullOrUnspecifiedOrEmpty(targetAdapter)) {
                     throw _Exceptions.unrecoverableFormatted("cannot recreate ManagedObject from bookmark %s", bookmark);
                 }
@@ -259,7 +259,7 @@ public class CommandExecutorServiceDefault implements CommandExecutorService {
             final CommandOutcomeHandler outcomeHandler,
             final Result<Bookmark> result) {
 
-        
+
         //
         // copy over the outcome
         //
@@ -274,7 +274,7 @@ public class CommandExecutorServiceDefault implements CommandExecutorService {
         //
         val interaction = interactionContextProvider.get().currentInteractionElseFail();
 
-        final Interaction.Execution<?, ?> priorExecution = interaction.getPriorExecution();
+        final Execution<?, ?> priorExecution = interaction.getPriorExecution();
         if(priorExecution != null) {
 
             if (outcomeHandler.getStartedAt() == null) {
@@ -344,7 +344,7 @@ public class CommandExecutorServiceDefault implements CommandExecutorService {
     private static ObjectAction findActionElseNull(
             final ObjectSpecification specification,
             final String localActionId) {
-        
+
         return specification.getAction(localActionId).orElse(null);
     }
 
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java
index d667dcc..f9afd3d 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java
@@ -34,7 +34,9 @@ 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.command.Command;
-import org.apache.isis.applib.services.iactn.Interaction;
+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.metrics.MetricsService;
 import org.apache.isis.applib.services.xactn.TransactionService;
 import org.apache.isis.commons.collections.Can;
@@ -133,10 +135,10 @@ implements MemberExecutorService {
         val targetClass = CommandUtil.targetClassNameFor(targetAdapter);
 
         val actionInvocation =
-                new Interaction.ActionInvocation(
+                new ActionInvocation(
                         interaction, actionId, targetPojo, argumentPojos, targetMemberName,
                         targetClass);
-        final InternalInteraction.MemberExecutor<Interaction.ActionInvocation> memberExecution =
+        final InternalInteraction.MemberExecutor<ActionInvocation> memberExecution =
                 actionExecutorFactory.createExecutor(
                         argumentAdapters, targetAdapter, owningAction,
                         targetAdapter, mixedInAdapter);
@@ -145,7 +147,7 @@ implements MemberExecutorService {
         interaction.execute(memberExecution, actionInvocation, clockService, metricsService.get(), command);
 
         // handle any exceptions
-        final Interaction.Execution<ActionInvocationDto, ?> priorExecution =
+        final Execution<ActionInvocationDto, ?> priorExecution =
                 _Casts.uncheckedCast(interaction.getPriorExecution());
 
         val executionExceptionIfAny = priorExecution.getThrew();
@@ -205,7 +207,7 @@ implements MemberExecutorService {
         val targetMemberName = CommandUtil.targetMemberNameFor(owningProperty);
         val targetClass = CommandUtil.targetClassNameFor(targetManagedObject);
 
-        val propertyEdit = new Interaction.PropertyEdit(interaction, propertyId, target, argValue, targetMemberName, targetClass);
+        val propertyEdit = new PropertyEdit(interaction, propertyId, target, argValue, targetMemberName, targetClass);
         val executor = propertyExecutorFactory
                 .createExecutor(newValueAdapter, owningProperty, targetManagedObject,
                         interactionInitiatedBy, head, editingVariant);
@@ -214,7 +216,7 @@ implements MemberExecutorService {
         val targetPojo = interaction.execute(executor, propertyEdit, clockService, metricsService.get(), command);
 
         // handle any exceptions
-        final Interaction.Execution<?, ?> priorExecution = interaction.getPriorExecution();
+        final Execution<?, ?> priorExecution = interaction.getPriorExecution();
 
         // TODO: should also sync DTO's 'threw' attribute here...?
 
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/interaction/InteractionDtoServiceInternalDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/interaction/InteractionDtoServiceInternalDefault.java
index f6ac707..3f3457a 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/interaction/InteractionDtoServiceInternalDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/interaction/InteractionDtoServiceInternalDefault.java
@@ -34,6 +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.user.UserService;
 import org.apache.isis.applib.util.schema.CommandDtoUtils;
 import org.apache.isis.applib.util.schema.InteractionDtoUtils;
@@ -65,18 +66,18 @@ public class InteractionDtoServiceInternalDefault implements InteractionDtoServi
     @Inject private BookmarkService bookmarkService;
     @Inject private javax.inject.Provider<InteractionContext> interactionContextProvider;
     @Inject private UserService userService;
-    
+
     @Override
     public ActionInvocationDto asActionInvocationDto(
             final ObjectAction objectAction,
             final ManagedObject targetAdapter,
             final Can<ManagedObject> argumentAdapters) {
-        
+
         _Assert.assertEquals(objectAction.getParameterCount(), argumentAdapters.size(),
                 "action's parameter count and provided argument count must match");
-        
+
         final Interaction interaction = interactionContextProvider.get().currentInteractionElseFail();
-        final int nextEventSequence = interaction.next(Interaction.Sequence.INTERACTION.id());
+        final int nextEventSequence = interaction.next(Sequence.INTERACTION.id());
 
         final Bookmark targetBookmark = targetAdapter.getRootOid()
                 .map(RootOid::asBookmark)
@@ -122,7 +123,7 @@ public class InteractionDtoServiceInternalDefault implements InteractionDtoServi
 
         final Interaction interaction = interactionContextProvider.get().currentInteractionElseFail();
 
-        final int nextEventSequence = interaction.next(Interaction.Sequence.INTERACTION.id());
+        final int nextEventSequence = interaction.next(Sequence.INTERACTION.id());
 
         final Bookmark targetBookmark = targetAdapter.getRootOid()
                 .map(RootOid::asBookmark)
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/ExecutionPublisherDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/ExecutionPublisherDefault.java
index 66c9082..ac48b9a 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/ExecutionPublisherDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/ExecutionPublisherDefault.java
@@ -34,7 +34,7 @@ import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.InteractionScope;
 import org.apache.isis.applib.annotation.OrderPrecedence;
-import org.apache.isis.applib.services.iactn.Interaction;
+import org.apache.isis.applib.services.iactn.Execution;
 import org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.having.HasEnabling;
@@ -51,13 +51,13 @@ import lombok.val;
 @InteractionScope
 @RequiredArgsConstructor(onConstructor_ = {@Inject})
 //@Log4j2
-public class ExecutionPublisherDefault 
+public class ExecutionPublisherDefault
 implements ExecutionPublisher {
 
     private final List<ExecutionSubscriber> subscribers;
-    
+
     private Can<ExecutionSubscriber> enabledSubscribers;
-    
+
     @PostConstruct
     public void init() {
         enabledSubscribers = Can.ofCollection(subscribers)
@@ -65,15 +65,15 @@ implements ExecutionPublisher {
     }
 
     @Override
-    public void publishActionInvocation(final Interaction.Execution<?,?> execution) {
+    public void publishActionInvocation(final Execution<?,?> execution) {
         notifySubscribers(execution);
     }
 
     @Override
-    public void publishPropertyEdit(final Interaction.Execution<?,?> execution) {
+    public void publishPropertyEdit(final Execution<?,?> execution) {
         notifySubscribers(execution);
     }
-    
+
     @Override
     public <T> T withPublishingSuppressed(final Supplier<T> block) {
         try {
@@ -86,7 +86,7 @@ implements ExecutionPublisher {
 
     // -- HELPERS
 
-    private void notifySubscribers(final Interaction.Execution<?,?> execution) {
+    private void notifySubscribers(final Execution<?,?> execution) {
         if(isSuppressed()) {
             return;
         }
@@ -96,12 +96,12 @@ implements ExecutionPublisher {
     }
 
     private final LongAdder suppressionRequestCounter = new LongAdder();
-    
+
     private boolean isSuppressed() {
-        return enabledSubscribers == null 
-                || enabledSubscribers.isEmpty() 
+        return enabledSubscribers == null
+                || enabledSubscribers.isEmpty()
                 || suppressionRequestCounter.intValue() > 0;
     }
-    
+
 
 }
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 c632a8f..a223383 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,6 +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.publishing.spi.EntityChanges;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.collections._Maps;
@@ -44,15 +45,15 @@ import lombok.experimental.UtilityClass;
 
 @UtilityClass
 class ChangingEntitiesFactory {
-    
+
     @Nullable
     public static EntityChanges createChangingEntities(
             final java.sql.Timestamp completedAt,
             final String userName,
             final EntityChangeTrackerDefault entityChangeTracker) {
-        
+
         // take a copy of enlisted adapters ... the JDO implementation of the PublishingService
-        // creates further entities which would be enlisted; 
+        // creates further entities which would be enlisted;
         // taking copy of the map avoids ConcurrentModificationException
 
         val changeKindByEnlistedAdapter = new HashMap<>(
@@ -66,15 +67,15 @@ class ChangingEntitiesFactory {
                 completedAt,
                 userName,
                 entityChangeTracker.currentInteraction(),
-                entityChangeTracker.numberEntitiesLoaded(), 
+                entityChangeTracker.numberEntitiesLoaded(),
                 entityChangeTracker.numberAuditedEntityPropertiesModified(),
                 changeKindByEnlistedAdapter);
-        
+
         return changingEntities;
     }
-    
+
     // -- HELPER
-    
+
     private static EntityChanges newChangingEntities(
             final java.sql.Timestamp completedAt,
             final String userName,
@@ -84,17 +85,17 @@ class ChangingEntitiesFactory {
             final Map<ManagedObject, EntityChangeKind> changeKindByEnlistedAdapter) {
 
         val uniqueId = interaction.getUniqueId();
-        final int nextEventSequence = interaction.next(Interaction.Sequence.INTERACTION.id());
+        final int nextEventSequence = interaction.next(Sequence.INTERACTION.id());
 
         return new SimpleChangingEntities(
                     uniqueId, nextEventSequence,
                     userName, completedAt,
-                    numberEntitiesLoaded, 
-                    numberEntityPropertiesModified, 
+                    numberEntitiesLoaded,
+                    numberEntityPropertiesModified,
                     ()->newDto(
                             uniqueId, nextEventSequence,
                             userName, completedAt,
-                            numberEntitiesLoaded,         
+                            numberEntitiesLoaded,
                             numberEntityPropertiesModified,
                             changeKindByEnlistedAdapter));
     }
@@ -105,11 +106,11 @@ class ChangingEntitiesFactory {
             final int numberEntitiesLoaded,
             final int numberEntityPropertiesModified,
             final Map<ManagedObject, EntityChangeKind> changeKindByEnlistedAdapter) {
-        
+
         // calculate the inverse of 'changesByAdapter'
-        final ListMultimap<EntityChangeKind, ManagedObject> adaptersByChange = 
+        final ListMultimap<EntityChangeKind, ManagedObject> adaptersByChange =
             _Maps.invertToListMultimap(changeKindByEnlistedAdapter);
-        
+
         val objectsDto = new ObjectsDto();
 
         objectsDto.setCreated(oidsDtoFor(adaptersByChange, EntityChangeKind.CREATE));
@@ -135,22 +136,22 @@ class ChangingEntitiesFactory {
     }
 
     private static OidsDto oidsDtoFor(
-            final ListMultimap<EntityChangeKind, ManagedObject> adaptersByChange, 
+            final ListMultimap<EntityChangeKind, ManagedObject> adaptersByChange,
             final EntityChangeKind kind) {
         val oidsDto = new OidsDto();
 
         _NullSafe.stream(adaptersByChange.get(kind))
-        .map((final ManagedObject adapter) -> 
+        .map((final ManagedObject adapter) ->
             ManagedObjects.identify(adapter)
             .map(RootOid::asOidDto)
             .orElse(null)
         )
         .filter(Objects::nonNull)
         .forEach(oidsDto.getOid()::add);
-        
+
         return oidsDto;
     }
 
 
-    
+
 }