diff --git a/src/TenantPartitionedEventsTests/AppendWrite/append_return_shapes_under_partitioning.cs b/src/TenantPartitionedEventsTests/AppendWrite/append_return_shapes_under_partitioning.cs
new file mode 100644
index 0000000000..9223d0f5c0
--- /dev/null
+++ b/src/TenantPartitionedEventsTests/AppendWrite/append_return_shapes_under_partitioning.cs
@@ -0,0 +1,114 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using JasperFx.Events;
+using Marten;
+using Shouldly;
+using TenantPartitionedEventsTests.Fixtures;
+using Xunit;
+
+namespace TenantPartitionedEventsTests.AppendWrite;
+
+///
+/// #4617 section 3a — the multiple Append / StartStream overload shapes
+/// (single event, `IEnumerable<object>`, `params object[]`,
+/// IEvent-wrapped) each route through the bulk
+/// mt_quick_append_events function and land in the owning tenant's
+/// partition. Pin the shape-matrix so a future overload-resolution change
+/// (or a refactor of how the appender enqueues events) doesn't silently
+/// reshape what hits the partitioned tables.
+///
+[Collection("guid-partitioned")]
+public class append_return_shapes_under_partitioning
+{
+ private readonly GuidPartitionedFixture _fixture;
+
+ public append_return_shapes_under_partitioning(GuidPartitionedFixture fixture)
+ {
+ _fixture = fixture;
+ }
+
+ [Fact]
+ public async Task append_via_params_object_array_lands_in_tenants_partition()
+ {
+ var tenant = PartitionedFixtureBase.NewTenant();
+ await _fixture.Store.Advanced.AddMartenManagedTenantsAsync(CancellationToken.None, tenant);
+
+ var streamId = Guid.NewGuid();
+ await using (var s = _fixture.Store.LightweightSession(tenant))
+ {
+ // Both StartStream + Append using `params object[]` — the canonical
+ // shape.
+ s.Events.StartStream(streamId, new TripStarted(streamId), new TripLeg(1));
+ await s.SaveChangesAsync();
+ }
+ await using (var s = _fixture.Store.LightweightSession(tenant))
+ {
+ s.Events.Append(streamId, new TripLeg(2), new TripLeg(3));
+ await s.SaveChangesAsync();
+ }
+
+ await using var q = _fixture.Store.QuerySession(tenant);
+ var events = await q.Events.FetchStreamAsync(streamId);
+ events.Count.ShouldBe(4);
+ }
+
+ [Fact]
+ public async Task append_via_IEnumerable_lands_in_tenants_partition()
+ {
+ var tenant = PartitionedFixtureBase.NewTenant();
+ await _fixture.Store.Advanced.AddMartenManagedTenantsAsync(CancellationToken.None, tenant);
+
+ var streamId = Guid.NewGuid();
+ IEnumerable