Skip to content

Commit 7ecf2f4

Browse files
committed
Add interoperability evidence registry
1 parent 83f465e commit 7ecf2f4

6 files changed

Lines changed: 137 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ The first production milestone is M3UA over a transport abstraction. SCCP, TCAP,
3737
| Interoperability tooling | Phase 6 foundation-ready: trace frames, Wireshark-friendly hex dumps, conformance vectors, built-in M3UA/MAP vectors, simulator scripts, MAP SMS flow builders, local TCP samples, sample catalog, CI profile, and readiness report; production gate is external interoperability lab evidence |
3838
| Commercial readiness | Phase 7 started: internal release readiness is available; commercial production readiness requires native SCTP verification, external interoperability evidence, and release governance |
3939
| Native SCTP support | Phase 7 matrix added: Linux requires lab verification; Windows and macOS are contract-only until a production provider is verified |
40+
| External interoperability evidence | Phase 7 registry added for peer-stack lab results and packet trace references; current evidence inventory is empty until real lab artifacts are captured |
4041

4142
## Requirements
4243

docs/INTEROPERABILITY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,5 @@ bool productionReady = report.IsProductionReady;
105105
The foundation gate is complete when trace formatting, conformance vectors, built-in vectors, simulator scripts, MAP SMS flows, transport samples, sample catalog, and CI profile are all present.
106106

107107
Production readiness remains false until external interoperability lab evidence is captured against real peer stacks and packet traces.
108+
109+
Phase 7 adds `SigtranInteropEvidenceRegistry` so those lab artifacts can be tracked as stable release evidence instead of free-form notes.

docs/PHASE7_COMMERCIALIZATION.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,19 @@ Commercial readiness remains blocked until native SCTP verification, external in
2727
| macOS | Contract only |
2828

2929
Linux is the target for native SCTP lab verification. Windows and macOS remain supported through transport contracts and development adapters until a production provider is selected and verified.
30+
31+
## External Interoperability Evidence
32+
33+
`SigtranInteropEvidenceRegistry` records evidence from real peer stacks and captured traces.
34+
35+
```csharp
36+
SigtranInteropEvidenceRegistry registry = new();
37+
registry.Add(new SigtranInteropEvidenceItem(
38+
"lab/linux/m3ua-asp",
39+
"openss7",
40+
"M3UA ASP to SG",
41+
"traces/m3ua-asp.pcapng",
42+
SigtranInteropEvidenceResult.Passed));
43+
```
44+
45+
The current registry is intentionally empty until real lab artifacts are added. Commercial readiness requires at least one passing external evidence item, and later release policies should require multiple peer stacks and scenarios.

src/sigtran.net.Tests/Program.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
Run("SIGTRAN phase 6 status summarizes completed tooling", SigtranPhase6StatusSummarizesCompletedTooling);
2323
Run("SIGTRAN commercial readiness reports release gates", SigtranCommercialReadinessReportsReleaseGates);
2424
Run("SIGTRAN native SCTP support matrix reports verification status", SigtranNativeSctpSupportMatrixReportsVerificationStatus);
25+
Run("SIGTRAN interop evidence registry tracks lab results", SigtranInteropEvidenceRegistryTracksLabResults);
2526
Run("TCAP BER element encodes short and long lengths", TcapBerElementEncodesShortAndLongLengths);
2627
Run("TCAP transaction identifiers use BER context tags", TcapTransactionIdentifiersUseBerContextTags);
2728
Run("TCAP BER Invoke component round-trips", TcapBerInvokeComponentRoundTrips);
@@ -293,6 +294,17 @@ static void SigtranNativeSctpSupportMatrixReportsVerificationStatus()
293294
Assert(!SigtranNativeSctpSupport.IsProductionVerified(), "native SCTP should not be production verified yet");
294295
}
295296

297+
static void SigtranInteropEvidenceRegistryTracksLabResults()
298+
{
299+
SigtranInteropEvidenceRegistry registry = new();
300+
registry.Add(new SigtranInteropEvidenceItem("lab/linux/m3ua-asp", "openss7", "M3UA ASP to SG", "traces/m3ua-asp.pcapng", SigtranInteropEvidenceResult.Passed));
301+
302+
AssertEqual(1, registry.Snapshot().Count, "interop evidence count");
303+
Assert(registry.HasPassingEvidence(), "interop evidence should pass with one passing item");
304+
AssertThrows<InvalidOperationException>(() => registry.Add(registry.Snapshot()[0]));
305+
Assert(!SigtranInteropEvidence.CreateCurrentRegistry().HasPassingEvidence(), "current interop evidence should be empty until real lab artifacts are added");
306+
}
307+
296308
static void TcapBerElementEncodesShortAndLongLengths()
297309
{
298310
Span<byte> shortBuffer = stackalloc byte[8];

src/sigtran.net/Core/Utilities/SigtranCommercialReadiness.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public static SigtranCommercialReadinessReport GetReport()
7474
hasInteroperabilityTooling: SigtranInteroperabilityReadiness.GetReport().FoundationReady,
7575
hasCiVerification: SigtranCiVerification.CreateDefaultProfile().Steps.Count > 0,
7676
hasNativeSctpVerification: SigtranNativeSctpSupport.IsProductionVerified(),
77-
hasExternalInteroperabilityEvidence: false,
77+
hasExternalInteroperabilityEvidence: SigtranInteropEvidence.CreateCurrentRegistry().HasPassingEvidence(),
7878
hasReleaseGovernance: false);
7979
}
8080
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
namespace sigtran.net.Core.Utilities;
2+
3+
/// <summary>
4+
/// Identifies the result of an external interoperability evidence item.
5+
/// </summary>
6+
public enum SigtranInteropEvidenceResult
7+
{
8+
/// <summary>The evidence item passed.</summary>
9+
Passed,
10+
11+
/// <summary>The evidence item failed.</summary>
12+
Failed,
13+
14+
/// <summary>The evidence item is informational only.</summary>
15+
Informational
16+
}
17+
18+
/// <summary>
19+
/// Describes one external interoperability evidence item.
20+
/// </summary>
21+
public sealed class SigtranInteropEvidenceItem
22+
{
23+
/// <summary>Creates an interoperability evidence item.</summary>
24+
/// <param name="id">The stable evidence id.</param>
25+
/// <param name="peerStack">The peer stack or product name.</param>
26+
/// <param name="scenario">The tested scenario.</param>
27+
/// <param name="traceReference">The trace or artifact reference.</param>
28+
/// <param name="result">The evidence result.</param>
29+
public SigtranInteropEvidenceItem(
30+
string id,
31+
string peerStack,
32+
string scenario,
33+
string traceReference,
34+
SigtranInteropEvidenceResult result)
35+
{
36+
Id = string.IsNullOrWhiteSpace(id) ? throw new ArgumentException("Evidence id is required.", nameof(id)) : id;
37+
PeerStack = string.IsNullOrWhiteSpace(peerStack) ? throw new ArgumentException("Peer stack is required.", nameof(peerStack)) : peerStack;
38+
Scenario = string.IsNullOrWhiteSpace(scenario) ? throw new ArgumentException("Scenario is required.", nameof(scenario)) : scenario;
39+
TraceReference = string.IsNullOrWhiteSpace(traceReference) ? throw new ArgumentException("Trace reference is required.", nameof(traceReference)) : traceReference;
40+
Result = result;
41+
}
42+
43+
/// <summary>The stable evidence id.</summary>
44+
public string Id { get; }
45+
46+
/// <summary>The peer stack or product name.</summary>
47+
public string PeerStack { get; }
48+
49+
/// <summary>The tested scenario.</summary>
50+
public string Scenario { get; }
51+
52+
/// <summary>The trace or artifact reference.</summary>
53+
public string TraceReference { get; }
54+
55+
/// <summary>The evidence result.</summary>
56+
public SigtranInteropEvidenceResult Result { get; }
57+
}
58+
59+
/// <summary>
60+
/// Stores external interoperability evidence in deterministic order.
61+
/// </summary>
62+
public sealed class SigtranInteropEvidenceRegistry
63+
{
64+
private readonly List<SigtranInteropEvidenceItem> _items = [];
65+
66+
/// <summary>Adds an evidence item.</summary>
67+
/// <param name="item">The evidence item.</param>
68+
public void Add(SigtranInteropEvidenceItem item)
69+
{
70+
ArgumentNullException.ThrowIfNull(item);
71+
if (_items.Any(existing => string.Equals(existing.Id, item.Id, StringComparison.OrdinalIgnoreCase)))
72+
{
73+
throw new InvalidOperationException($"Interop evidence '{item.Id}' already exists.");
74+
}
75+
76+
_items.Add(item);
77+
}
78+
79+
/// <summary>Returns a deterministic evidence snapshot.</summary>
80+
/// <returns>The evidence snapshot.</returns>
81+
public IReadOnlyList<SigtranInteropEvidenceItem> Snapshot()
82+
{
83+
return _items.ToArray();
84+
}
85+
86+
/// <summary>Returns whether all evidence items passed and at least one item exists.</summary>
87+
/// <returns>True when the registry has passing evidence; otherwise false.</returns>
88+
public bool HasPassingEvidence()
89+
{
90+
return _items.Count > 0 && _items.All(static item => item.Result == SigtranInteropEvidenceResult.Passed);
91+
}
92+
}
93+
94+
/// <summary>
95+
/// Provides external interoperability evidence inventory helpers.
96+
/// </summary>
97+
public static class SigtranInteropEvidence
98+
{
99+
/// <summary>Creates the current external evidence registry.</summary>
100+
/// <returns>The current external evidence registry.</returns>
101+
public static SigtranInteropEvidenceRegistry CreateCurrentRegistry()
102+
{
103+
return new SigtranInteropEvidenceRegistry();
104+
}
105+
}

0 commit comments

Comments
 (0)