diff --git a/src/ScadaLink.InboundAPI/InboundScriptExecutor.cs b/src/ScadaLink.InboundAPI/InboundScriptExecutor.cs
index 2a68abe..80aff65 100644
--- a/src/ScadaLink.InboundAPI/InboundScriptExecutor.cs
+++ b/src/ScadaLink.InboundAPI/InboundScriptExecutor.cs
@@ -172,6 +172,9 @@ public class InboundScriptExecutor
RouteHelper route,
TimeSpan timeout,
CancellationToken cancellationToken = default,
+ // Deliberate ordering: this optional parameter trails the CancellationToken
+ // because it was appended additively for non-breaking contract evolution.
+ // Every call site passes it by named argument (parentExecutionId:).
Guid? parentExecutionId = null)
{
// InboundAPI-004: keep the timeout source and the request-abort source
diff --git a/src/ScadaLink.InboundAPI/Middleware/AuditWriteMiddleware.cs b/src/ScadaLink.InboundAPI/Middleware/AuditWriteMiddleware.cs
index 71ce437..db83c85 100644
--- a/src/ScadaLink.InboundAPI/Middleware/AuditWriteMiddleware.cs
+++ b/src/ScadaLink.InboundAPI/Middleware/AuditWriteMiddleware.cs
@@ -249,8 +249,11 @@ public sealed class AuditWriteMiddleware
/// Audit Log #23 (ParentExecutionId): reads the inbound request's per-request
/// ExecutionId that minted and stashed on
/// under .
- /// Falls back to a fresh id only if the slot is somehow absent — the inbound
- /// audit row must always carry an execution id.
+ /// Throws if the slot is absent — for a
+ /// correlation feature a silently-divergent id is the worst failure mode, so we
+ /// fail fast rather than mint a fresh one. 's
+ /// try/catch degrades the throw to a dropped best-effort audit row, never a
+ /// failed request.
///
private static Guid ResolveInboundExecutionId(HttpContext ctx)
{
@@ -260,7 +263,9 @@ public sealed class AuditWriteMiddleware
return id;
}
- return Guid.NewGuid();
+ throw new InvalidOperationException(
+ "Inbound ExecutionId invariant violated: the inbound ExecutionId must be "
+ + "stashed by AuditWriteMiddleware.InvokeAsync before the audit row is emitted.");
}
///