You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by da...@apache.org on 2026/06/07 14:49:19 UTC
(causeway) 28/50: CAUSEWAY-4014: removes replayable command target cosmetics
This is an automated email from the ASF dual-hosted git repository.
danhaywood pushed a commit to branch CAUSEWAY-4014
in repository https://gitbox.apache.org/repos/asf/causeway.git
commit e5bf9694d91309bf67bcdb0dba93a1f82d6a8f95
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Sun Jun 7 11:50:08 2026 +0100
CAUSEWAY-4014: removes replayable command target cosmetics
---
.../applib/CausewayModuleExtCommandLogApplib.java | 4 --
...ExportManager#exported.columnOrder.fallback.txt | 4 +-
...Manager#notYetExported.columnOrder.fallback.txt | 4 +-
...anager#pendingOrFailed.columnOrder.fallback.txt | 4 +-
...er#succeededOrExcluded.columnOrder.fallback.txt | 4 +-
.../ReplayableCommand.columnOrder.fallback.txt | 4 +-
.../applib/dom/replay/ReplayableCommand.java | 64 ++++-----------------
.../replay/ReplayableCommand.layout.fallback.xml | 7 +--
.../dom/replay/ReplayableCommand_openTarget.java | 65 ----------------------
.../dom/replay/ReplayableCommand_openTargetTR.java | 62 ---------------------
.../.openspec.yaml | 0
.../design.md | 0
.../proposal.md | 0
.../specs/replayable-command-remappings/spec.md | 3 +-
.../tasks.md | 16 ++++++
.../changes/replayable-command-cosmetics/tasks.md | 16 ------
.../specs/replayable-command-remappings/spec.md | 12 +++-
17 files changed, 46 insertions(+), 223 deletions(-)
diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/CausewayModuleExtCommandLogApplib.java b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/CausewayModuleExtCommandLogApplib.java
index 945ddddabb7..b17292d4e83 100644
--- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/CausewayModuleExtCommandLogApplib.java
+++ b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/CausewayModuleExtCommandLogApplib.java
@@ -57,8 +57,6 @@
import org.apache.causeway.extensions.commandlog.applib.dom.replay.ReplayableCommand_excludeFromReplay;
import org.apache.causeway.extensions.commandlog.applib.dom.replay.ReplayableCommand_makeExportable;
import org.apache.causeway.extensions.commandlog.applib.dom.replay.ReplayableCommand_openCommandLogEntry;
-import org.apache.causeway.extensions.commandlog.applib.dom.replay.ReplayableCommand_openTarget;
-import org.apache.causeway.extensions.commandlog.applib.dom.replay.ReplayableCommand_openTargetTR;
import org.apache.causeway.extensions.commandlog.applib.dom.replay.ReplayableCommand_replayOrRetry;
import org.apache.causeway.extensions.commandlog.applib.fakescheduler.FakeScheduler;
import org.apache.causeway.extensions.commandlog.applib.job.BackgroundCommandsJobControl;
@@ -90,8 +88,6 @@
CommandReplayResultMapping_delete.class,
ReplayableCommand_makeExportable.class,
ReplayableCommand_openCommandLogEntry.class,
- ReplayableCommand_openTarget.class,
- ReplayableCommand_openTargetTR.class,
ReplayableCommand_replayOrRetry.class,
ReplayableCommand_excludeFromReplay.class,
ReplayableCommand_delete.class,
diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandExportManager#exported.columnOrder.fallback.txt b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandExportManager#exported.columnOrder.fallback.txt
index bde91a6f91d..337130c7561 100644
--- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandExportManager#exported.columnOrder.fallback.txt
+++ b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandExportManager#exported.columnOrder.fallback.txt
@@ -1,6 +1,4 @@
#interactionId
timestamp
-targetType
-targetId
member
-replayState
\ No newline at end of file
+replayState
diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandExportManager#notYetExported.columnOrder.fallback.txt b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandExportManager#notYetExported.columnOrder.fallback.txt
index bde91a6f91d..337130c7561 100644
--- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandExportManager#notYetExported.columnOrder.fallback.txt
+++ b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandExportManager#notYetExported.columnOrder.fallback.txt
@@ -1,6 +1,4 @@
#interactionId
timestamp
-targetType
-targetId
member
-replayState
\ No newline at end of file
+replayState
diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandReplayManager#pendingOrFailed.columnOrder.fallback.txt b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandReplayManager#pendingOrFailed.columnOrder.fallback.txt
index bde91a6f91d..337130c7561 100644
--- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandReplayManager#pendingOrFailed.columnOrder.fallback.txt
+++ b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandReplayManager#pendingOrFailed.columnOrder.fallback.txt
@@ -1,6 +1,4 @@
#interactionId
timestamp
-targetType
-targetId
member
-replayState
\ No newline at end of file
+replayState
diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandReplayManager#succeededOrExcluded.columnOrder.fallback.txt b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandReplayManager#succeededOrExcluded.columnOrder.fallback.txt
index bde91a6f91d..337130c7561 100644
--- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandReplayManager#succeededOrExcluded.columnOrder.fallback.txt
+++ b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandReplayManager#succeededOrExcluded.columnOrder.fallback.txt
@@ -1,6 +1,4 @@
#interactionId
timestamp
-targetType
-targetId
member
-replayState
\ No newline at end of file
+replayState
diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.columnOrder.fallback.txt b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.columnOrder.fallback.txt
index bde91a6f91d..337130c7561 100644
--- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.columnOrder.fallback.txt
+++ b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.columnOrder.fallback.txt
@@ -1,6 +1,4 @@
#interactionId
timestamp
-targetType
-targetId
member
-replayState
\ No newline at end of file
+replayState
diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.java b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.java
index ae2213a0e8a..24f9bac1f49 100644
--- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.java
+++ b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.java
@@ -31,20 +31,16 @@
import javax.inject.Named;
import org.apache.causeway.applib.ViewModel;
-import org.apache.causeway.applib.annotation.Action;
-import org.apache.causeway.applib.annotation.ActionLayout;
import org.apache.causeway.applib.annotation.Collection;
import org.apache.causeway.applib.annotation.CollectionLayout;
import org.apache.causeway.applib.annotation.DomainObject;
import org.apache.causeway.applib.annotation.DomainObjectLayout;
import org.apache.causeway.applib.annotation.Introspection;
import org.apache.causeway.applib.annotation.LabelPosition;
-import org.apache.causeway.applib.annotation.MemberSupport;
import org.apache.causeway.applib.annotation.ObjectSupport;
import org.apache.causeway.applib.annotation.Programmatic;
import org.apache.causeway.applib.annotation.Property;
import org.apache.causeway.applib.annotation.PropertyLayout;
-import org.apache.causeway.applib.annotation.SemanticsOf;
import org.apache.causeway.applib.annotation.Where;
import org.apache.causeway.applib.jaxb.JavaTimeXMLGregorianCalendarMarshalling;
import org.apache.causeway.applib.services.bookmark.Bookmark;
@@ -54,7 +50,6 @@
import org.apache.causeway.commons.functional.Try;
import org.apache.causeway.commons.internal.base._NullSafe;
import org.apache.causeway.commons.internal.base._Refs.ObjectReference;
-import org.apache.causeway.commons.internal.base._Strings;
import org.apache.causeway.commons.io.JsonUtils;
import org.apache.causeway.commons.io.TextUtils;
import org.apache.causeway.commons.io.YamlUtils;
@@ -164,7 +159,17 @@ public ReplayableCommand(
@ObjectSupport public String title() {
final var timestamp = getTimestampIfAny().map(ChronoZonedDateTime::toInstant).map(Instant::toString).map(x -> " @ " + x).orElse("");
- return getTargetType() + ":" + getTargetId() + " #" + getMember() + timestamp;
+ return targetTitlePrefix() + " #" + getMember() + timestamp;
+ }
+
+ private String targetTitlePrefix() {
+ return commandRecord()
+ .map(CommandRecord::commandDto)
+ .map(CommandDto::getTargets)
+ .filter(targets -> !targets.getOid().isEmpty())
+ .map(targets -> targets.getOid().get(0))
+ .map(target -> target.getType() + ":" + target.getId())
+ .orElse("");
}
//requires v4
@@ -208,53 +213,6 @@ public Optional<ZonedDateTime> getTimestampIfAny() {
.map(JavaTimeXMLGregorianCalendarMarshalling::toZonedDateTime);
}
- @Property
- @PropertyLayout(
- sequence = "2.1",
- fieldSetId = "details",
- describedAs = "Target Type of the original (replayable) Command")
- public String getTargetType() {
- return commandRecord()
- .map(CommandRecord::commandDto)
- .map(commandDto->commandDto.getTargets().getOid().get(0))
- .map(OidDto::getType)
- .orElse(null);
- }
-
- @Property
- @PropertyLayout(
- sequence = "2.2",
- fieldSetId = "details",
- describedAs = "Target ID of the original (replayable) Command")
- public String getTargetId() {
- return commandRecord()
- .map(CommandRecord::commandDto)
- .map(commandDto->commandDto.getTargets().getOid().get(0))
- .map(OidDto::getId)
- .map(id->_Strings.ellipsifyAtEnd(id, 10, "..."))
- .orElse(null);
- }
-
- @Action(semantics = SemanticsOf.SAFE)
- @ActionLayout(
- cssClassFa = "fa-bullseye"
- )
- public class openTarget {
-
- @MemberSupport public Object act() {
- return commandLogEntry()
- .map(CommandLogEntry::getTarget)
- .flatMap(bookmark -> bookmarkService.lookup(bookmark))
- .orElse(null);
- }
- @MemberSupport public String disableAct() {
- return commandLogEntry().isPresent() ? null : "Unknown target";
- }
-
- @Inject BookmarkService bookmarkService;
- }
-
-
@Property
@PropertyLayout(
sequence = "3.1",
diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.layout.fallback.xml b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.layout.fallback.xml
index 9abeeb06dc2..cebdcf14f12 100644
--- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.layout.fallback.xml
+++ b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.layout.fallback.xml
@@ -37,7 +37,7 @@
</bs:row>
</bs:tab>
</bs:tabGroup>
- <cpt:collection id="participants"/>
+ <cpt:collection defaultView="table" paged="15" id="participants"/>
<cpt:fieldSet name="Control" id="control">
<cpt:action id="replayOrRetry" position="PANEL"/>
<cpt:property id="replayState"/>
@@ -50,11 +50,6 @@
</cpt:fieldSet>
</bs:col>
</bs:row>
- <bs:row>
- <bs:col span="12">
- <cpt:collection defaultView="table" paged="15" id="participants"/>
- </bs:col>
- </bs:row>
<bs:row>
<bs:col span="12">
<bs:tabGroup unreferencedCollections="true"/>
diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand_openTarget.java b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand_openTarget.java
deleted file mode 100644
index c26fa2068c0..00000000000
--- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand_openTarget.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.causeway.extensions.commandlog.applib.dom.replay;
-
-import javax.inject.Inject;
-
-import org.apache.causeway.applib.annotation.Action;
-import org.apache.causeway.applib.annotation.ActionLayout;
-import org.apache.causeway.applib.annotation.MemberSupport;
-import org.apache.causeway.applib.annotation.Publishing;
-import org.apache.causeway.applib.annotation.SemanticsOf;
-import org.apache.causeway.applib.services.bookmark.BookmarkService;
-import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntry;
-
-import lombok.RequiredArgsConstructor;
-
-@Action(
- semantics = SemanticsOf.SAFE,
- commandPublishing = Publishing.DISABLED,
- domainEvent = ReplayableCommand_openTarget.DomainEvent.class,
- executionPublishing = Publishing.DISABLED
-)
-@ActionLayout(
- sequence = "0.3", associateWith = "target",
- describedAs = "Opens the underlying Target"
-)
-@RequiredArgsConstructor
-public class ReplayableCommand_openTarget {
-
- public static class DomainEvent extends ReplayableCommand.ActionDomainEvent<ReplayableCommand_openTarget> {
- }
-
- private final ReplayableCommand replayableCommand;
-
- @MemberSupport
- public Object act() {
- return replayableCommand.commandLogEntry()
- .map(CommandLogEntry::getTarget)
- .flatMap(bookmark -> bookmarkService.lookup(bookmark))
- .orElse(null);
- }
-
- @MemberSupport
- public String disableAct() {
- return replayableCommand.commandLogEntry().isEmpty() ? "No corresponding CommandLogEntry" : null;
- }
-
- @Inject private BookmarkService bookmarkService;
-}
diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand_openTargetTR.java b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand_openTargetTR.java
deleted file mode 100644
index ae9fad85db4..00000000000
--- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand_openTargetTR.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.causeway.extensions.commandlog.applib.dom.replay;
-
-import lombok.RequiredArgsConstructor;
-
-import javax.inject.Inject;
-
-import org.apache.causeway.applib.annotation.*;
-import org.apache.causeway.applib.services.bookmark.BookmarkService;
-import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntry;
-
-@Action(
- semantics = SemanticsOf.SAFE,
- commandPublishing = Publishing.DISABLED,
- domainEvent = ReplayableCommand_openTargetTR.DomainEvent.class,
- executionPublishing = Publishing.DISABLED
-)
-@ActionLayout(
- named = "Open Target",
- describedAs = "Opens the underlying Target",
- hidden = Where.OBJECT_FORMS // table row action.
-)
-@RequiredArgsConstructor
-public class ReplayableCommand_openTargetTR {
-
- public static class DomainEvent extends ReplayableCommand.ActionDomainEvent<ReplayableCommand_openTargetTR> {
- }
-
- private final ReplayableCommand replayableCommand;
-
- @MemberSupport
- public Object act() {
- return replayableCommand.commandLogEntry()
- .map(CommandLogEntry::getTarget)
- .flatMap(bookmark -> bookmarkService.lookup(bookmark))
- .orElse(null);
- }
-
- @MemberSupport
- public String disableAct() {
- return replayableCommand.commandLogEntry().isEmpty() ? "No corresponding CommandLogEntry" : null;
- }
-
- @Inject private BookmarkService bookmarkService;
-}
diff --git a/openspec/changes/replayable-command-cosmetics/.openspec.yaml b/openspec/changes/archive/2026-06-07-replayable-command-cosmetics/.openspec.yaml
similarity index 100%
rename from openspec/changes/replayable-command-cosmetics/.openspec.yaml
rename to openspec/changes/archive/2026-06-07-replayable-command-cosmetics/.openspec.yaml
diff --git a/openspec/changes/replayable-command-cosmetics/design.md b/openspec/changes/archive/2026-06-07-replayable-command-cosmetics/design.md
similarity index 100%
rename from openspec/changes/replayable-command-cosmetics/design.md
rename to openspec/changes/archive/2026-06-07-replayable-command-cosmetics/design.md
diff --git a/openspec/changes/replayable-command-cosmetics/proposal.md b/openspec/changes/archive/2026-06-07-replayable-command-cosmetics/proposal.md
similarity index 100%
rename from openspec/changes/replayable-command-cosmetics/proposal.md
rename to openspec/changes/archive/2026-06-07-replayable-command-cosmetics/proposal.md
diff --git a/openspec/changes/replayable-command-cosmetics/specs/replayable-command-remappings/spec.md b/openspec/changes/archive/2026-06-07-replayable-command-cosmetics/specs/replayable-command-remappings/spec.md
similarity index 91%
rename from openspec/changes/replayable-command-cosmetics/specs/replayable-command-remappings/spec.md
rename to openspec/changes/archive/2026-06-07-replayable-command-cosmetics/specs/replayable-command-remappings/spec.md
index d75a9e7f117..0906e5e7ad1 100644
--- a/openspec/changes/replayable-command-cosmetics/specs/replayable-command-remappings/spec.md
+++ b/openspec/changes/archive/2026-06-07-replayable-command-cosmetics/specs/replayable-command-remappings/spec.md
@@ -3,7 +3,7 @@
### Requirement: Replayable participant layouts expose participant data
The system SHALL provide fallback layout metadata for `ReplayableCommandParticipant`.
The participant layout SHALL expose role, parameter name, recorded bookmark, target, parameter, result, and actual bookmark in that order.
-The `ReplayableCommand` fallback layout SHALL include the participants collection as a table named `Participants`.
+The `ReplayableCommand` fallback layout SHALL include the participants collection as a table named `Participants` before the control field set.
The `ReplayableCommand` object view MUST NOT expose separate target summary properties for target type or target identifier.
The `ReplayableCommand` object view MUST NOT expose a separate open target action.
Target inspection and navigation SHALL be available through target rows in the participants collection.
@@ -11,6 +11,7 @@ Target inspection and navigation SHALL be available through target rows in the p
#### Scenario: User views participants table on a replayable command
- **WHEN** a user views a replayable command using fallback layout metadata
- **THEN** the layout includes the participants collection as a table named `Participants`
+- **AND** the participants table appears before the control field set
#### Scenario: User views participant fields
- **WHEN** a user views a replayable command participant using fallback layout metadata
diff --git a/openspec/changes/archive/2026-06-07-replayable-command-cosmetics/tasks.md b/openspec/changes/archive/2026-06-07-replayable-command-cosmetics/tasks.md
new file mode 100644
index 00000000000..c1d840ba0a1
--- /dev/null
+++ b/openspec/changes/archive/2026-06-07-replayable-command-cosmetics/tasks.md
@@ -0,0 +1,16 @@
+## 1. ReplayableCommand Cleanup
+
+- [x] 1.1 Remove the `openTarget` action and its `BookmarkService` dependency from `ReplayableCommand`.
+- [x] 1.2 Remove exposed `targetType` and `targetId` properties from `ReplayableCommand`.
+- [x] 1.3 Preserve any needed title logic using non-exposed helpers if required.
+
+## 2. Layout Metadata
+
+- [x] 2.1 Remove `openTarget`, `targetType`, and `targetId` references from `ReplayableCommand.layout.fallback.xml`.
+- [x] 2.2 Keep the `member`, replay state, DTO, and participants table layout unchanged except for removed target members.
+
+## 3. Tests and Validation
+
+- [x] 3.1 Update focused command log applib tests for the removed target members if needed.
+- [x] 3.2 Run focused command log applib tests for replayable command mapping and participant behaviour.
+- [x] 3.3 Run `openspec validate replayable-command-cosmetics --strict`.
diff --git a/openspec/changes/replayable-command-cosmetics/tasks.md b/openspec/changes/replayable-command-cosmetics/tasks.md
deleted file mode 100644
index ac9f017427f..00000000000
--- a/openspec/changes/replayable-command-cosmetics/tasks.md
+++ /dev/null
@@ -1,16 +0,0 @@
-## 1. ReplayableCommand Cleanup
-
-- [ ] 1.1 Remove the `openTarget` action and its `BookmarkService` dependency from `ReplayableCommand`.
-- [ ] 1.2 Remove exposed `targetType` and `targetId` properties from `ReplayableCommand`.
-- [ ] 1.3 Preserve any needed title logic using non-exposed helpers if required.
-
-## 2. Layout Metadata
-
-- [ ] 2.1 Remove `openTarget`, `targetType`, and `targetId` references from `ReplayableCommand.layout.fallback.xml`.
-- [ ] 2.2 Keep the `member`, replay state, DTO, and participants table layout unchanged except for removed target members.
-
-## 3. Tests and Validation
-
-- [ ] 3.1 Update focused command log applib tests for the removed target members if needed.
-- [ ] 3.2 Run focused command log applib tests for replayable command mapping and participant behaviour.
-- [ ] 3.3 Run `openspec validate replayable-command-cosmetics --strict`.
diff --git a/openspec/specs/replayable-command-remappings/spec.md b/openspec/specs/replayable-command-remappings/spec.md
index 4b947796e80..d5d42543fcf 100644
--- a/openspec/specs/replayable-command-remappings/spec.md
+++ b/openspec/specs/replayable-command-remappings/spec.md
@@ -96,12 +96,22 @@ The system MUST NOT resolve or display a result object for commands that have no
### Requirement: Replayable participant layouts expose participant data
The system SHALL provide fallback layout metadata for `ReplayableCommandParticipant`.
The participant layout SHALL expose role, parameter name, recorded bookmark, target, parameter, result, and actual bookmark in that order.
-The `ReplayableCommand` fallback layout SHALL include the participants collection as a table named `Participants`.
+The `ReplayableCommand` fallback layout SHALL include the participants collection as a table named `Participants` before the control field set.
+The `ReplayableCommand` object view MUST NOT expose separate target summary properties for target type or target identifier.
+The `ReplayableCommand` object view MUST NOT expose a separate open target action.
+Target inspection and navigation SHALL be available through target rows in the participants collection.
#### Scenario: User views participants table on a replayable command
- **WHEN** a user views a replayable command using fallback layout metadata
- **THEN** the layout includes the participants collection as a table named `Participants`
+- **AND** the participants table appears before the control field set
#### Scenario: User views participant fields
- **WHEN** a user views a replayable command participant using fallback layout metadata
- **THEN** the layout displays the participant role, parameter name, recorded bookmark, target, parameter, result, and actual bookmark in order
+
+#### Scenario: User inspects target through participants
+- **WHEN** a user views a replayable command using fallback layout metadata
+- **THEN** the layout does not display separate `targetType` or `targetId` properties
+- **AND** the layout does not display a separate `openTarget` action
+- **AND** target information is available through the participants table