diff --git a/TestFx.slnx b/TestFx.slnx
index c668218c84..5d7f088626 100644
--- a/TestFx.slnx
+++ b/TestFx.slnx
@@ -55,6 +55,7 @@
+
diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/Microsoft.Testing.Extensions.HangDump.csproj b/src/Platform/Microsoft.Testing.Extensions.HangDump/Microsoft.Testing.Extensions.HangDump.csproj
index ec29cb0c2e..ffdd4bf22a 100644
--- a/src/Platform/Microsoft.Testing.Extensions.HangDump/Microsoft.Testing.Extensions.HangDump.csproj
+++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/Microsoft.Testing.Extensions.HangDump.csproj
@@ -33,6 +33,7 @@ This package extends Microsoft Testing Platform to provide an implementation of
+
diff --git a/src/Platform/Microsoft.Testing.Extensions.MSBuild/Microsoft.Testing.Extensions.MSBuild.csproj b/src/Platform/Microsoft.Testing.Extensions.MSBuild/Microsoft.Testing.Extensions.MSBuild.csproj
index 0df011bd84..784251490b 100644
--- a/src/Platform/Microsoft.Testing.Extensions.MSBuild/Microsoft.Testing.Extensions.MSBuild.csproj
+++ b/src/Platform/Microsoft.Testing.Extensions.MSBuild/Microsoft.Testing.Extensions.MSBuild.csproj
@@ -14,6 +14,7 @@
+
diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Microsoft.Testing.Extensions.Retry.csproj b/src/Platform/Microsoft.Testing.Extensions.Retry/Microsoft.Testing.Extensions.Retry.csproj
index 8c909f7691..0961b63dc9 100644
--- a/src/Platform/Microsoft.Testing.Extensions.Retry/Microsoft.Testing.Extensions.Retry.csproj
+++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Microsoft.Testing.Extensions.Retry.csproj
@@ -16,6 +16,7 @@
+
diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/Microsoft.Testing.Extensions.TrxReport.csproj b/src/Platform/Microsoft.Testing.Extensions.TrxReport/Microsoft.Testing.Extensions.TrxReport.csproj
index 0a25d33170..e9e5cf3c87 100644
--- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/Microsoft.Testing.Extensions.TrxReport.csproj
+++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/Microsoft.Testing.Extensions.TrxReport.csproj
@@ -16,6 +16,7 @@
+
diff --git a/src/Platform/Microsoft.Testing.Platform.DotnetTestProtocol/Microsoft.Testing.Platform.DotnetTestProtocol.csproj b/src/Platform/Microsoft.Testing.Platform.DotnetTestProtocol/Microsoft.Testing.Platform.DotnetTestProtocol.csproj
new file mode 100644
index 0000000000..977aac4bef
--- /dev/null
+++ b/src/Platform/Microsoft.Testing.Platform.DotnetTestProtocol/Microsoft.Testing.Platform.DotnetTestProtocol.csproj
@@ -0,0 +1,63 @@
+
+
+
+
+ netstandard2.0
+
+
+ true
+ false
+ true
+ false
+ false
+
+
+ true
+
+
+ false
+
+
+ $(NoWarn);NU5128
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Platform/Microsoft.Testing.Platform.DotnetTestProtocol/PACKAGE.md b/src/Platform/Microsoft.Testing.Platform.DotnetTestProtocol/PACKAGE.md
new file mode 100644
index 0000000000..2b609543b0
--- /dev/null
+++ b/src/Platform/Microsoft.Testing.Platform.DotnetTestProtocol/PACKAGE.md
@@ -0,0 +1,31 @@
+# Microsoft.Testing.Platform.DotnetTestProtocol
+
+This package shares — **as compiled source** — the `dotnet test` named-pipe **wire contract** used between a
+[Microsoft.Testing.Platform](https://www.nuget.org/packages/Microsoft.Testing.Platform) test host and the
+`dotnet test` command line.
+
+It exists so the protocol's serializer/field ids and handshake/session/state constants have a **single source of
+truth** across the [microsoft/testfx](https://github.com/microsoft/testfx) and
+[dotnet/sdk](https://github.com/dotnet/sdk) repositories, instead of being hand-copied (where any drift is a silent
+wire-protocol break).
+
+> This package is an implementation detail of `dotnet test` integration. It is **not** intended for direct
+> end-user consumption.
+
+## What's inside
+
+The package ships two zero-dependency source files as `contentFiles` (compiled into the consuming assembly):
+
+- `ObjectFieldIds.cs` — serializer ids and per-message field ids.
+- `Constants.cs` — handshake property names, execution modes, session-event types, test states and the protocol
+ version.
+
+Because they are delivered as `contentFiles/cs/any` with `BuildAction=Compile`, the consumer compiles them into its
+**own** assembly, so the `internal` types are visible without any `InternalsVisibleTo` plumbing.
+
+## Scope
+
+Only the wire **contract** (ids + constants) is shared here. The message **models** and **serializers** are not
+included yet because they still depend on `TestMetadataProperty`
+(`Microsoft.Testing.Platform.Extensions.Messages`) and use a different class shape than the SDK's copy; sharing them
+requires decoupling/unifying first.
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestProtocolContract.props b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestProtocolContract.props
index c6e23c9e1e..80aea90a47 100644
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestProtocolContract.props
+++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestProtocolContract.props
@@ -23,10 +23,20 @@
USAGE
Import this file from any project that needs the contract. Microsoft.Testing.Platform itself does NOT import
it (it compiles these files via its default source globbing); importing it there would double-include them.
+
+ The single canonical list of contract files lives in the @(DotnetTestProtocolContractSource) item below.
+ - Source consumers (e.g. the standalone contract test project) get them as items (the default).
+ - The Microsoft.Testing.Platform.DotnetTestProtocol package project sets
+ DotnetTestProtocolContractCompile=false and instead packs @(DotnetTestProtocolContractSource) as
+ contentFiles, so the NuGet and the source-share never drift.
-->
-
-
+
+
+
+
+
+
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Constants.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Constants.cs
index ab38cf7280..c5c547ab0d 100644
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Constants.cs
+++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Constants.cs
@@ -1,8 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using Microsoft.CodeAnalysis;
+
namespace Microsoft.Testing.Platform.IPC;
+[Embedded]
internal static class TestStates
{
internal const byte Discovered = 0;
@@ -15,12 +18,14 @@ internal static class TestStates
internal const byte InProgress = 7;
}
+[Embedded]
internal static class SessionEventTypes
{
internal const byte TestSessionStart = 0;
internal const byte TestSessionEnd = 1;
}
+[Embedded]
internal static class HandshakeMessagePropertyNames
{
internal const byte PID = 0;
@@ -47,6 +52,7 @@ internal static class HandshakeMessagePropertyNames
internal const byte OrchestratorFeature = 11;
}
+[Embedded]
internal static class HandshakeMessageHostTypes
{
// A regular (console or server) test host that actually runs tests.
@@ -63,6 +69,7 @@ internal static class HandshakeMessageHostTypes
internal const string TestHostOrchestrator = "TestHostOrchestrator";
}
+[Embedded]
internal static class HandshakeMessageExecutionModes
{
// Standard test run.
@@ -75,6 +82,7 @@ internal static class HandshakeMessageExecutionModes
internal const string Discover = "discover";
}
+[Embedded]
internal static class ProtocolConstants
{
internal const string Version = "1.0.0";
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/ObjectFieldIds.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/ObjectFieldIds.cs
index f328182ffa..462f233d8f 100644
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/ObjectFieldIds.cs
+++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/ObjectFieldIds.cs
@@ -1,27 +1,33 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using Microsoft.CodeAnalysis;
+
namespace Microsoft.Testing.Platform.IPC;
// WARNING: Please note this file needs to be kept aligned with the one in the dotnet sdk.
// The protocol follows the concept of optional properties.
// The id is used to identify the property in the stream and it will be skipped if it's not recognized.
// We can add new properties with new ids, but we CANNOT change the existing ids (to support backwards compatibility).
+[Embedded]
internal static class VoidResponseFieldsId
{
public const int MessagesSerializerId = 0;
}
+[Embedded]
internal static class TestHostCompletedRequestFieldsId
{
public const int MessagesSerializerId = 1;
}
+[Embedded]
internal static class TestHostProcessPIDRequestFieldsId
{
public const int MessagesSerializerId = 2;
}
+[Embedded]
internal static class CommandLineOptionMessagesFieldsId
{
public const int MessagesSerializerId = 3;
@@ -30,6 +36,7 @@ internal static class CommandLineOptionMessagesFieldsId
public const ushort CommandLineOptionMessageList = 2;
}
+[Embedded]
internal static class CommandLineOptionMessageFieldsId
{
public const ushort Name = 1;
@@ -39,6 +46,7 @@ internal static class CommandLineOptionMessageFieldsId
// Reserved: field ID 5 was ObsolescenceMessage, removed as unused.
}
+[Embedded]
internal static class DiscoveredTestMessagesFieldsId
{
public const int MessagesSerializerId = 5;
@@ -48,6 +56,7 @@ internal static class DiscoveredTestMessagesFieldsId
public const ushort DiscoveredTestMessageList = 3;
}
+[Embedded]
internal static class DiscoveredTestMessageFieldsId
{
public const ushort Uid = 1;
@@ -61,12 +70,14 @@ internal static class DiscoveredTestMessageFieldsId
public const ushort ParameterTypeFullNames = 9;
}
+[Embedded]
internal static class TraitMessageFieldsId
{
public const ushort Key = 1;
public const ushort Value = 2;
}
+[Embedded]
internal static class TestResultMessagesFieldsId
{
public const int MessagesSerializerId = 6;
@@ -77,6 +88,7 @@ internal static class TestResultMessagesFieldsId
public const ushort FailedTestMessageList = 4;
}
+[Embedded]
internal static class SuccessfulTestResultMessageFieldsId
{
public const ushort Uid = 1;
@@ -89,6 +101,7 @@ internal static class SuccessfulTestResultMessageFieldsId
public const ushort SessionUid = 8;
}
+[Embedded]
internal static class FailedTestResultMessageFieldsId
{
public const ushort Uid = 1;
@@ -102,6 +115,7 @@ internal static class FailedTestResultMessageFieldsId
public const ushort SessionUid = 9;
}
+[Embedded]
internal static class ExceptionMessageFieldsId
{
public const ushort ErrorMessage = 1;
@@ -109,6 +123,7 @@ internal static class ExceptionMessageFieldsId
public const ushort StackTrace = 3;
}
+[Embedded]
internal static class FileArtifactMessagesFieldsId
{
public const int MessagesSerializerId = 7;
@@ -118,6 +133,7 @@ internal static class FileArtifactMessagesFieldsId
public const ushort FileArtifactMessageList = 3;
}
+[Embedded]
internal static class FileArtifactMessageFieldsId
{
public const ushort FullPath = 1;
@@ -128,6 +144,7 @@ internal static class FileArtifactMessageFieldsId
public const ushort SessionUid = 6;
}
+[Embedded]
internal static class TestSessionEventFieldsId
{
public const int MessagesSerializerId = 8;
@@ -137,11 +154,13 @@ internal static class TestSessionEventFieldsId
public const ushort ExecutionId = 3;
}
+[Embedded]
internal static class HandshakeMessageFieldsId
{
public const int MessagesSerializerId = 9;
}
+[Embedded]
internal static class TestInProgressMessagesFieldsId
{
public const int MessagesSerializerId = 10;
@@ -151,6 +170,7 @@ internal static class TestInProgressMessagesFieldsId
public const ushort TestInProgressMessageList = 3;
}
+[Embedded]
internal static class TestInProgressMessageFieldsId
{
public const ushort Uid = 1;
diff --git a/test/UnitTests/Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests/Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests.csproj b/test/UnitTests/Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests/Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests.csproj
index faafca44c4..92fb668730 100644
--- a/test/UnitTests/Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests/Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests.csproj
+++ b/test/UnitTests/Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests/Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests.csproj
@@ -11,6 +11,16 @@
+
+
+
+
+