diff --git a/src/AgentOs.Modules.Pipeline/Agents/AgentsOptions.cs b/src/AgentOs.Modules.Pipeline/Agents/AgentsOptions.cs
index bbd977f..fb810b1 100644
--- a/src/AgentOs.Modules.Pipeline/Agents/AgentsOptions.cs
+++ b/src/AgentOs.Modules.Pipeline/Agents/AgentsOptions.cs
@@ -84,13 +84,7 @@ public bool IsValid() => AgentRoles.All.All(r => For(r.Key) is { } a
&& a.MaxTokens > 0);
/// Every configured agent, for cross-cutting checks (startup validation).
- public IEnumerable All()
- {
- foreach (var role in AgentRoles.All)
- {
- if (For(role.Key) is { } options) { yield return options; }
- }
- }
+ public IEnumerable All() => AgentRoles.All.Select(role => For(role.Key)).OfType();
}
/// Configuration for a single agent.
diff --git a/src/AgentOs.Modules.Pipeline/Agents/TicketFlowDefinition.cs b/src/AgentOs.Modules.Pipeline/Agents/TicketFlowDefinition.cs
index 5e9c4e4..a45bdfd 100644
--- a/src/AgentOs.Modules.Pipeline/Agents/TicketFlowDefinition.cs
+++ b/src/AgentOs.Modules.Pipeline/Agents/TicketFlowDefinition.cs
@@ -363,13 +363,9 @@ public static IReadOnlyList Validate(TicketFlowDefinition? de
}
// Edges: known steps; pass = one next step each (none after Merge, none into Code); fail = back to Code only.
- foreach (var e in definition.Edges)
- {
- if (!byId.ContainsKey(e.From) || !byId.ContainsKey(e.To))
- {
- problems.Add(new(null, $"An edge points at a step that doesn't exist ({e.From} → {e.To})."));
- }
- }
+ problems.AddRange(definition.Edges
+ .Where(e => !byId.ContainsKey(e.From) || !byId.ContainsKey(e.To))
+ .Select(e => new TicketFlowProblem(null, $"An edge points at a step that doesn't exist ({e.From} → {e.To}).")));
var edges = definition.Edges.Where(e => byId.ContainsKey(e.From) && byId.ContainsKey(e.To)).ToList();
var pass = edges.Where(e => e.When == TicketFlowEdgeWhen.Pass).ToList();
var fail = edges.Where(e => e.When == TicketFlowEdgeWhen.Fail).ToList();
diff --git a/src/AgentOs.Web/Components/Pages/AgentProfilesApp.razor b/src/AgentOs.Web/Components/Pages/AgentProfilesApp.razor
index afa7d62..905f227 100644
--- a/src/AgentOs.Web/Components/Pages/AgentProfilesApp.razor
+++ b/src/AgentOs.Web/Components/Pages/AgentProfilesApp.razor
@@ -231,11 +231,10 @@ else
{
foreach (var field in RoleFields.Where(f => byKey.GetValueOrDefault(AgentSettings.Key(role, f))?.Source is null or SettingSource.Default))
{
- if (await Legacy.ReadAsync(role, field, _tenantId) is { } old)
- {
- row.Loaded[field] = old;
- row.Legacy = true;
- }
+ var old = await Legacy.ReadAsync(role, field, _tenantId);
+ if (old is null) { continue; }
+ row.Loaded[field] = old;
+ row.Legacy = true;
}
}
row.Provider = row.Loaded.GetValueOrDefault(ProviderField, string.Empty);
diff --git a/src/AgentOs.Web/Services/BoardTasks/BoardTaskService.cs b/src/AgentOs.Web/Services/BoardTasks/BoardTaskService.cs
index 322a62b..bd35822 100644
--- a/src/AgentOs.Web/Services/BoardTasks/BoardTaskService.cs
+++ b/src/AgentOs.Web/Services/BoardTasks/BoardTaskService.cs
@@ -552,7 +552,7 @@ await sessRepo.UpdateRepoRunResultAsync(tenantId, outcome.SessionRepoId, "Failed
// It used to mark the repo Failed and drop the pull request link: Autopilot lost track of the open PR
// and started the ticket over on a new branch (VNChess #95 / PR #97, 2026-10-24).
var stood = children.FirstOrDefault(c => c.Id == outcome.SessionRepoId);
- if (FailedFollowUpKeepsItsChange(change is not null, stood?.Status, stood?.PrUrl) && stood is not null)
+ if (stood is not null && FailedFollowUpKeepsItsChange(change is not null, stood.Status, stood.PrUrl))
{
await sessRepo.UpdateRepoRunResultAsync(tenantId, stood.Id, stood.Status, stood.BranchName, stood.PrUrl,
"The last fix attempt failed: " + (outcome.Error ?? "Agent failed.")).ConfigureAwait(false);
diff --git a/tests/AgentOs.E2E.Tests/AgentOsUi/TicketFlowTests.cs b/tests/AgentOs.E2E.Tests/AgentOsUi/TicketFlowTests.cs
index eb7a593..b362cd0 100644
--- a/tests/AgentOs.E2E.Tests/AgentOsUi/TicketFlowTests.cs
+++ b/tests/AgentOs.E2E.Tests/AgentOsUi/TicketFlowTests.cs
@@ -63,11 +63,10 @@ private static async Task EnsureDefaultAsync(ILocator win)
var changed = false;
foreach (var step in new[] { "review", "test" })
{
- if (await Card(win, step).GetAttributeAsync("class") is { } css && css.Contains("run-skipped", StringComparison.Ordinal))
- {
- await SetRunsAsync(win, step, on: true);
- changed = true;
- }
+ var css = await Card(win, step).GetAttributeAsync("class");
+ if (css is null || !css.Contains("run-skipped", StringComparison.Ordinal)) { continue; }
+ await SetRunsAsync(win, step, on: true);
+ changed = true;
}
if (changed)
{
diff --git a/tests/AgentOs.Tests/Agents/AgentRegistryGuardTests.cs b/tests/AgentOs.Tests/Agents/AgentRegistryGuardTests.cs
index 69cc0e9..16a4d8f 100644
--- a/tests/AgentOs.Tests/Agents/AgentRegistryGuardTests.cs
+++ b/tests/AgentOs.Tests/Agents/AgentRegistryGuardTests.cs
@@ -75,15 +75,14 @@ BinaryExpressionSyntax b when b.IsKind(SyntaxKind.AddExpression) => HardCoded(b.
_ => false,
};
- foreach (var call in root.DescendantNodes().OfType())
+ foreach (var (call, provider) in root.DescendantNodes().OfType()
+ .Where(c => c.Expression is MemberAccessExpressionSyntax { Name.Identifier.ValueText: "Create" })
+ .Select(c => (Call: c, Provider: c.ArgumentList.Arguments.FirstOrDefault()))
+ .Where(x => x.Provider is { } p
+ && p.NameColon is null or { Name.Identifier.ValueText: "providerName" }
+ && HardCoded(p.Expression)))
{
- if (call.Expression is MemberAccessExpressionSyntax { Name.Identifier.ValueText: "Create" }
- && call.ArgumentList.Arguments is [var provider, ..]
- && provider.NameColon is null or { Name.Identifier.ValueText: "providerName" }
- && HardCoded(provider.Expression))
- {
- yield return $"line {Line(call)}: ILlmClientFactory.Create({provider.Expression})";
- }
+ yield return $"line {Line(call)}: ILlmClientFactory.Create({provider!.Expression})";
}
foreach (var creation in root.DescendantNodes().OfType())
diff --git a/tests/AgentOs.Tests/Web/TicketFlowDefinitionTests.cs b/tests/AgentOs.Tests/Web/TicketFlowDefinitionTests.cs
index 57ddcec..9409ad9 100644
--- a/tests/AgentOs.Tests/Web/TicketFlowDefinitionTests.cs
+++ b/tests/AgentOs.Tests/Web/TicketFlowDefinitionTests.cs
@@ -229,9 +229,8 @@ public void Plan_WithoutAGate_IsUnsafe()
[Fact]
public void EveryStepKind_IsRegistered_WithRolesFromTheAgentRegistry()
{
- foreach (var kind in System.Enum.GetValues())
+ foreach (var info in System.Enum.GetValues().Select(TicketStepKinds.Of))
{
- var info = TicketStepKinds.Of(kind);
info.Roles.ShouldAllBe(r => AgentRoles.Find(r) != null);
}
TicketStepKinds.Of(TicketStepKind.Code).DefaultRole.ShouldBe(AgentRoles.IssueWork);