Merge origin/main with local pending work and update AGENTS.md references

- Resolve 14 conflicts from popping local stash on top of origin's
  eed1e88 + 8d3352f doc-comment additions (11 mechanical, plus
  version.rs, DashboardAuthenticatorTests.cs, DashboardGalaxyProjector.cs)
- Fix 4 test files that used AGENTS.md as the repo-root sentinel
  (now use CLAUDE.md, since AGENTS.md was removed in 4731ab5)
- Redirect 10 doc citations from AGENTS.md to the matching gateway.md
  sections (Value Model, Status Model, Security, STA Worker Thread
  Model, gRPC Layer rule, cancellation rule)

Verified: solution build clean, x86 worker build clean, 266/266
gateway tests passing, 121/121 worker tests passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-04-30 14:13:33 -04:00
parent 8d3352f2c6
commit ddad573b75
101 changed files with 6053 additions and 621 deletions
@@ -19,6 +19,7 @@ public sealed class GatewayOptionsValidator : IValidateOptions<GatewayOptions>
List<string> failures = [];
ValidateAuthentication(options.Authentication, failures);
ValidateLdap(options.Ldap, failures);
ValidateWorker(options.Worker, failures);
ValidateSessions(options.Sessions, failures);
ValidateEvents(options.Events, failures);
@@ -55,6 +56,47 @@ public sealed class GatewayOptionsValidator : IValidateOptions<GatewayOptions>
}
}
private static void ValidateLdap(LdapOptions options, List<string> failures)
{
if (!options.Enabled)
{
return;
}
AddIfBlank(options.Server, "MxGateway:Ldap:Server is required when LDAP login is enabled.", failures);
AddIfBlank(options.SearchBase, "MxGateway:Ldap:SearchBase is required when LDAP login is enabled.", failures);
AddIfBlank(
options.ServiceAccountDn,
"MxGateway:Ldap:ServiceAccountDn is required when LDAP login is enabled.",
failures);
AddIfBlank(
options.ServiceAccountPassword,
"MxGateway:Ldap:ServiceAccountPassword is required when LDAP login is enabled.",
failures);
AddIfBlank(
options.UserNameAttribute,
"MxGateway:Ldap:UserNameAttribute is required when LDAP login is enabled.",
failures);
AddIfBlank(
options.DisplayNameAttribute,
"MxGateway:Ldap:DisplayNameAttribute is required when LDAP login is enabled.",
failures);
AddIfBlank(
options.GroupAttribute,
"MxGateway:Ldap:GroupAttribute is required when LDAP login is enabled.",
failures);
AddIfBlank(
options.RequiredGroup,
"MxGateway:Ldap:RequiredGroup is required when LDAP login is enabled.",
failures);
AddIfNotPositive(options.Port, "MxGateway:Ldap:Port must be greater than zero.", failures);
if (!options.UseTls && !options.AllowInsecureLdap)
{
failures.Add("MxGateway:Ldap:AllowInsecureLdap must be true when UseTls is false.");
}
}
private static void ValidateWorker(WorkerOptions options, List<string> failures)
{
AddIfBlank(options.ExecutablePath, "MxGateway:Worker:ExecutablePath is required.", failures);
@@ -135,6 +177,14 @@ public sealed class GatewayOptionsValidator : IValidateOptions<GatewayOptions>
options.MaxPendingCommandsPerSession,
"MxGateway:Sessions:MaxPendingCommandsPerSession must be greater than zero.",
failures);
AddIfNotPositive(
options.DefaultLeaseSeconds,
"MxGateway:Sessions:DefaultLeaseSeconds must be greater than zero.",
failures);
AddIfNotPositive(
options.LeaseSweepIntervalSeconds,
"MxGateway:Sessions:LeaseSweepIntervalSeconds must be greater than zero.",
failures);
if (options.AllowMultipleEventSubscribers)
{
@@ -185,6 +235,12 @@ public sealed class GatewayOptionsValidator : IValidateOptions<GatewayOptions>
failures.Add(
$"MxGateway:Protocol:WorkerProtocolVersion must be {GatewayContractInfo.WorkerProtocolVersion}.");
}
if (options.MaxGrpcMessageBytes is < MinimumMaxMessageBytes or > MaximumMaxMessageBytes)
{
failures.Add(
$"MxGateway:Protocol:MaxGrpcMessageBytes must be between {MinimumMaxMessageBytes} and {MaximumMaxMessageBytes}.");
}
}
private static void AddIfBlank(string? value, string message, List<string> failures)