Skip to content

[codex] Delta closure: truthful routing + portability cleanup#90

Merged
Prekzursil merged 1 commit intomainfrom
codex/delta-truthful-routing
Mar 1, 2026
Merged

[codex] Delta closure: truthful routing + portability cleanup#90
Prekzursil merged 1 commit intomainfrom
codex/delta-truthful-routing

Conversation

@Prekzursil
Copy link
Owner

@Prekzursil Prekzursil commented Mar 1, 2026

User description

Summary

This PR implements the delta closure wave on current origin/main for truthful routing + metadata portability.

Delivered:

  • Added SWFOC_FORCE_PROMOTED_EXTENDER routing override in BackendRouter.
  • Default behavior is now non-forced for promoted FoC actions; explicit env override preserves forced behavior for regression runs.
  • Added route diagnostics keys:
    • promotedExtenderOverrideEnabled
    • promotedExtenderOverrideSource
    • promotedExtenderApplied
  • Updated universal_auto profile to backendPreference: auto and cleared local promoted capability list.
  • Removed hardcoded per-user saveRootDefault metadata from base_swfoc and base_sweaw.
  • Added portability guard test: ProfileMetadataPortabilityTests.
  • Updated runbook/test plan/TODO evidence notes for override semantics and run IDs.

Why

Current main still forced promoted FoC actions into Extender through router promotion gates, and base profile metadata still contained user-specific save-root paths. This PR closes those deltas without reopening already-landed M2 scope.

Risk

risk:high (runtime routing behavior + live evidence workflow docs).

Deterministic Verification

  • dotnet restore SwfocTrainer.sln
  • dotnet build SwfocTrainer.sln -c Release --no-restore
  • dotnet test tests/SwfocTrainer.Tests/SwfocTrainer.Tests.csproj -c Release --no-build --filter "FullyQualifiedName!~SwfocTrainer.Tests.Profiles.Live&FullyQualifiedName!~RuntimeAttachSmokeTests" ✅ (Passed: 233, Failed: 0)

Live Evidence (TACTICAL)

Default routing run:

  • TestResults/runs/20260301-004145/repro-bundle.json
  • classification=blocked_environment (no swfoc process detected)

Forced override regression run (SWFOC_FORCE_PROMOTED_EXTENDER=1):

  • TestResults/runs/20260301-004232/repro-bundle.json
  • classification=blocked_environment (no swfoc process detected)

Bundle schema validation:

  • tools/validate-repro-bundle.ps1 strict validation passed for both run IDs.

Reliability Evidence Contract

repro bundle json: TestResults/runs/20260301-004145/repro-bundle.json
classification: blocked_environment


PR Type

Enhancement, Tests


Description

  • Implement SWFOC_FORCE_PROMOTED_EXTENDER environment override for promoted FoC action routing

    • Default behavior is non-forced (routes to legacy backend)
    • Override enables forced routing to Extender with fail-closed semantics
    • Add route diagnostics keys for override state tracking
  • Remove hardcoded user-specific save-root paths from base profiles for portability

  • Update universal_auto profile to backendPreference: auto and clear promoted capability list

  • Add comprehensive test coverage for override semantics and profile metadata portability


Diagram Walkthrough

flowchart LR
  A["BackendRouter"] -->|"reads env var"| B["SWFOC_FORCE_PROMOTED_EXTENDER"]
  B -->|"disabled default"| C["Legacy Backend Routing"]
  B -->|"enabled override"| D["Extender Promotion"]
  C -->|"diagnostics"| E["Override State Keys"]
  D -->|"diagnostics"| E
  F["Base Profiles"] -->|"remove hardcoded"| G["User Save Paths"]
  H["universal_auto"] -->|"change to"| I["backendPreference: auto"]
  H -->|"clear"| J["Required Capabilities"]
Loading

File Walkthrough

Relevant files
Enhancement
1 files
BackendRouter.cs
Add promoted extender override environment variable semantics
+43/-4   
Tests
3 files
BackendRouterTests.cs
Add override scope tests and update routing behavior assertions
+169/-13
ProfileInheritanceTests.cs
Add test for universal_auto backend preference default     
+18/-0   
ProfileMetadataPortabilityTests.cs
Add portability guard test for user-specific save paths   
+30/-0   
Configuration changes
3 files
base_sweaw.json
Remove hardcoded user save-root default path                         
+0/-1     
base_swfoc.json
Remove hardcoded user save-root default path                         
+0/-1     
universal_auto.json
Change backend preference to auto and clear capabilities 
+2/-8     
Documentation
3 files
TODO.md
Document delta closure wave completion with evidence         
+7/-0     
LIVE_VALIDATION_RUNBOOK.md
Update promoted action matrix evidence procedures               
+17/-3   
TEST_PLAN.md
Update test expectations for promoted routing override     
+15/-2   

Summary by CodeRabbit

Release Notes

  • New Features

    • Added optional override mechanism for promoted action routing via environment variable
    • Universal Auto profile now defaults to auto backend preference
  • Improvements

    • Removed user-specific paths from profile metadata to improve portability across accounts
  • Documentation

    • Updated validation and test guidance for new routing configuration options

Add SWFOC_FORCE_PROMOTED_EXTENDER override semantics in BackendRouter with default non-forced promoted routing, de-trap universal_auto backend preference, remove hardcoded user save-root metadata, and align tests/docs/TODO evidence for deterministic and tactical live validation runs.

Co-authored-by: Codex <noreply@openai.com>
@devloai
Copy link

devloai bot commented Mar 1, 2026

Unable to trigger custom agent "Code Reviewer". You have run out of credits 😔
Please upgrade your plan or buy additional credits from the subscription page.

@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@Prekzursil Prekzursil added the risk:high High-risk change; strict human gate required. label Mar 1, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 1, 2026

📝 Walkthrough

Walkthrough

This pull request implements environment-variable-driven override logic for promoted extender routing, removes user-specific save root defaults from profiles for portability, adjusts the universal_auto backend preference to "auto", and updates tests and documentation to reflect the new override mechanism.

Changes

Cohort / File(s) Summary
Environment Override Implementation
src/SwfocTrainer.Runtime/Services/BackendRouter.cs
Introduces PromotedExtenderOverrideState record and ResolvePromotedExtenderOverrideState method to parse SWFOC_FORCE_PROMOTED_EXTENDER environment variable. Renames IsPromotedExtenderAction to IsPromotedExtenderActionCandidate and integrates override state into route resolution and diagnostic payload, including new fields for override enabled/source tracking.
Profile Configuration
profiles/default/profiles/base_sweaw.json, profiles/default/profiles/base_swfoc.json, profiles/default/profiles/universal_auto.json
Removes saveRootDefault from metadata in base profiles for portability. Changes universal_auto backendPreference from "extender" to "auto" and clears requiredCapabilities array.
Documentation Updates
TODO.md, docs/LIVE_VALIDATION_RUNBOOK.md, docs/TEST_PLAN.md
Documents new SWFOC_FORCE_PROMOTED_EXTENDER override capability with setup/reset instructions, verification steps, and updated Phase 2 promoted action guidance reflecting opt-in extender routing behavior.
Test Coverage
tests/SwfocTrainer.Tests/Runtime/BackendRouterTests.cs, tests/SwfocTrainer.Tests/Profiles/ProfileInheritanceTests.cs, tests/SwfocTrainer.Tests/Profiles/ProfileMetadataPortabilityTests.cs
Refactors backend router tests to rename promoted-action scenarios and add override-enabled/disabled test variants with new PromotedExtenderOverrideScope helper. Adds tests for universal_auto profile backend preference and metadata portability verification via regex pattern matching.

Sequence Diagram

sequenceDiagram
    actor Env as Environment
    participant Router as BackendRouter
    participant Override as Override Parser
    participant Candidate as Candidate Check
    participant Diag as Diagnostics

    Env->>Router: SWFOC_FORCE_PROMOTED_EXTENDER set/unset
    Router->>Override: ResolvePromotedExtenderOverrideState()
    Override->>Override: Parse env var (boolean/int/string forms)
    Override-->>Router: PromotedExtenderOverrideState {Enabled, Source}
    
    Router->>Candidate: IsPromotedExtenderActionCandidate(profile, action)
    Candidate-->>Router: bool (candidate or not)
    
    Router->>Router: Compute isPromotedExtenderAction<br/>= Candidate AND Override.Enabled
    
    Router->>Diag: BuildDiagnostics() with override context
    Diag->>Diag: Add promotedExtenderOverrideEnabled<br/>promotedExtenderOverrideSource<br/>promotedExtenderApplied
    Diag-->>Router: Complete diagnostic payload
    Router-->>Env: Route decision + diagnostics
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

area:runtime, area:profiles, area:docs, Review effort 3/5, needs-reviewer, risk:medium

Poem

🐰 A rabbit hops through routing flows,
With switches set by env that glows—
Promoted paths now bend their way,
Default-free, portable today! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title '[codex] Delta closure: truthful routing + portability cleanup' accurately summarizes the main changes—implementing environment-driven routing override and removing hardcoded user paths from profiles.
Description check ✅ Passed The PR description is comprehensive and covers most required template sections with clear summaries, risk assessment, reliability evidence, and detailed implementation notes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/delta-truthful-routing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review
Copy link

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
No persistent audit log: The PR adds routing diagnostics (promotedExtenderOverrideEnabled/Source/Applied) but does
not show that these critical routing decisions are written to an auditable, timestamped
log with actor context.

Referred Code
var promotedExtenderOverride = ResolvePromotedExtenderOverrideState();
var isPromotedActionCandidate = IsPromotedExtenderActionCandidate(request.Action.Id, profile, process);
var isPromotedExtenderAction = promotedExtenderOverride.Enabled && isPromotedActionCandidate;
var defaultBackend = MapDefaultBackend(request.Action.ExecutionKind, isPromotedExtenderAction);
var preferredBackend = ResolvePreferredBackend(profile.BackendPreference, defaultBackend, isPromotedExtenderAction);
var isMutating = IsMutating(request.Action.Id);
var profileRequiredCapabilities = profile.RequiredCapabilities ?? Array.Empty<string>();
var requiredCapabilities = ResolveRequiredCapabilitiesForAction(
    profileRequiredCapabilities,
    request.Action.Id,
    isPromotedExtenderAction);
var missingRequired = requiredCapabilities
    .Where(featureId => !capabilityReport.IsFeatureAvailable(featureId))
    .ToArray();
var diagnostics = BuildDiagnostics(new BackendDiagnosticsContext(
    request,
    profile,
    process,
    capabilityReport,
    defaultBackend,
    preferredBackend,


 ... (clipped 37 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Diagnostics logging unknown: The PR adds additional diagnostic fields that may be logged elsewhere, but the diff does
not show whether/where these diagnostics are emitted and whether log scrubbing/structure
guarantees are enforced end-to-end.

Referred Code
    ["profileBackendPreference"] = context.Profile.BackendPreference,
    ["hostRole"] = context.Process.HostRole.ToString(),
    ["probeReasonCode"] = context.CapabilityReport.ProbeReasonCode.ToString(),
    ["profileRequiredCapabilities"] = context.ProfileRequiredCapabilities,
    ["requiredCapabilities"] = context.RequiredCapabilities,
    ["missingRequiredCapabilities"] = context.MissingRequired,
    ["hybridExecution"] = false,
    ["promotedExtenderAction"] = context.PromotedExtenderAction,
    ["promotedExtenderOverrideEnabled"] = context.PromotedExtenderOverrideEnabled,
    ["promotedExtenderOverrideSource"] = context.PromotedExtenderOverrideSource,
    ["promotedExtenderApplied"] = context.PromotedExtenderAction,
    ["capabilityMapReasonCode"] = capabilityMapReasonCode ?? string.Empty,
    ["capabilityMapState"] = capabilityMapState ?? string.Empty,
    ["capabilityDeclaredAvailable"] = capabilityDeclaredAvailable
};

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Remove duplicate diagnostic entry

Remove the redundant promotedExtenderApplied entry from the diagnostics
dictionary as it duplicates the value of promotedExtenderAction.

src/SwfocTrainer.Runtime/Services/BackendRouter.cs [119]

-["promotedExtenderApplied"] = context.PromotedExtenderAction,
+# (remove the entire `["promotedExtenderApplied"]` line)
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies that the promotedExtenderApplied diagnostic key is redundant because its value is always the same as promotedExtenderAction. Removing it simplifies the diagnostic output and reduces potential confusion for consumers of this data.

Low
Cache override state once

Cache the result of ResolvePromotedExtenderOverrideState in a static readonly
Lazy field to avoid reading and parsing the environment variable on every call.

src/SwfocTrainer.Runtime/Services/BackendRouter.cs [415-437]

-private static PromotedExtenderOverrideState ResolvePromotedExtenderOverrideState()
-{
-    var raw = Environment.GetEnvironmentVariable(PromotedExtenderOverrideEnvironmentVariable);
-    if (string.IsNullOrWhiteSpace(raw))
+private static readonly Lazy<PromotedExtenderOverrideState> _promotedExtenderOverrideStateLazy =
+    new(() =>
     {
-        return new PromotedExtenderOverrideState(Enabled: false, Source: "default");
-    }
+        var raw = Environment.GetEnvironmentVariable(PromotedExtenderOverrideEnvironmentVariable);
+        if (string.IsNullOrWhiteSpace(raw))
+        {
+            return new PromotedExtenderOverrideState(Enabled: false, Source: "default");
+        }
+        if (bool.TryParse(raw, out var parsedBool))
+        {
+            return new PromotedExtenderOverrideState(Enabled: parsedBool, Source: "env");
+        }
+        if (int.TryParse(raw, out var parsedInt))
+        {
+            return new PromotedExtenderOverrideState(Enabled: parsedInt != 0, Source: "env");
+        }
+        var normalized = raw.Trim();
+        var enabled = normalized.Equals("on", StringComparison.OrdinalIgnoreCase) ||
+                      normalized.Equals("yes", StringComparison.OrdinalIgnoreCase);
+        return new PromotedExtenderOverrideState(Enabled: enabled, Source: "env");
+    });
 
-    if (bool.TryParse(raw, out var parsedBool))
-    {
-        return new PromotedExtenderOverrideState(Enabled: parsedBool, Source: "env");
-    }
+private static PromotedExtenderOverrideState ResolvePromotedExtenderOverrideState() =>
+    _promotedExtenderOverrideStateLazy.Value;
 
-    if (int.TryParse(raw, out var parsedInt))
-    {
-        return new PromotedExtenderOverrideState(Enabled: parsedInt != 0, Source: "env");
-    }
-
-    var normalized = raw.Trim();
-    var enabled = normalized.Equals("on", StringComparison.OrdinalIgnoreCase) ||
-                  normalized.Equals("yes", StringComparison.OrdinalIgnoreCase);
-    return new PromotedExtenderOverrideState(Enabled: enabled, Source: "env");
-}
-
  • Apply / Chat
Suggestion importance[1-10]: 5

__

Why: This is a good suggestion for a performance micro-optimization by caching the environment variable lookup using Lazy<T>. This avoids repeated I/O and parsing, which is beneficial as the value is not expected to change during the process lifetime.

Low
Improve environment variable parsing logic

Improve the environment variable parsing by explicitly checking for falsy string
values like "off" and "no" to make the logic more robust and clear.

src/SwfocTrainer.Runtime/Services/BackendRouter.cs [433-436]

 var normalized = raw.Trim();
-var enabled = normalized.Equals("on", StringComparison.OrdinalIgnoreCase) ||
-              normalized.Equals("yes", StringComparison.OrdinalIgnoreCase);
-return new PromotedExtenderOverrideState(Enabled: enabled, Source: "env");
+if (normalized.Equals("on", StringComparison.OrdinalIgnoreCase) ||
+    normalized.Equals("yes", StringComparison.OrdinalIgnoreCase))
+{
+    return new PromotedExtenderOverrideState(Enabled: true, Source: "env");
+}
 
+if (normalized.Equals("off", StringComparison.OrdinalIgnoreCase) ||
+    normalized.Equals("no", StringComparison.OrdinalIgnoreCase))
+{
+    return new PromotedExtenderOverrideState(Enabled: false, Source: "env");
+}
+
+return new PromotedExtenderOverrideState(Enabled: false, Source: "env");
+
  • Apply / Chat
Suggestion importance[1-10]: 2

__

Why: The suggestion correctly identifies that the code doesn't explicitly handle falsy strings like "off" or "no", but the current implementation already correctly evaluates them to false. The proposed change only makes the logic more verbose for explicitness, offering a minor readability improvement without changing behavior.

Low
  • More

@codacy-production
Copy link

Codacy's Analysis Summary

0 new issue (≤ 0 issue)
0 new security issue
5 complexity
0 duplications
More details

AI Reviewer: run the reviewer on demand. As new changes are pushed, run a review below.
To trigger the first review automatically, go to your organization or repository integration settings.
AI can make mistakes. Always validate suggestions.

 
  Run Reviewer ▶︎  
 

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
tests/SwfocTrainer.Tests/Profiles/ProfileMetadataPortabilityTests.cs (1)

19-19: Optional: scan subdirectories to future-proof this portability guard.

Line 19 uses SearchOption.TopDirectoryOnly; switching to recursive discovery avoids silently missing profile files if directory layout expands later.

♻️ Optional refactor
-        var profileFiles = Directory.GetFiles(profileDirectory, "*.json", SearchOption.TopDirectoryOnly);
+        var profileFiles = Directory.GetFiles(profileDirectory, "*.json", SearchOption.AllDirectories);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/SwfocTrainer.Tests/Profiles/ProfileMetadataPortabilityTests.cs` at line
19, Change the file discovery to search recursively so profile files in
subfolders aren’t missed: update the Directory.GetFiles call that assigns
profileFiles (currently using profileDirectory and
SearchOption.TopDirectoryOnly) to use SearchOption.AllDirectories (or an
equivalent recursive enumeration) so all "*.json" profile files under
profileDirectory are discovered; ensure any code that expects flat results still
works or is adjusted to handle nested paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/TEST_PLAN.md`:
- Around line 197-202: The TEST_PLAN expects summary.total=15 but the promoted
contract now records two-step set_unit_cap entries (e.g., "[1/2]" + "[2/2]")
producing an 18-row closure matrix; update the assertions/expected values that
reference summary.total=15 to summary.total=18 and adjust any companion checks
that validate matrix row counts or pass-count criteria (including the sections
that reference set_unit_cap multi-step entries) so the runbook gate counts both
steps as separate rows and will not accept incomplete promoted evidence.

In `@tests/SwfocTrainer.Tests/Runtime/BackendRouterTests.cs`:
- Around line 500-524: Tests using the PromotedExtenderOverrideScope manipulate
the process-wide env var "SWFOC_FORCE_PROMOTED_EXTENDER" and must not run in
parallel; create an xUnit collection to serialize them and apply it to the test
class: add a CollectionDefinition (e.g., name "EnvVarSerial") with
DisableParallelization = true, and annotate the test class containing
PromotedExtenderOverrideScope (or any other classes/tests that use it) with
[Collection("EnvVarSerial")], ensuring all tests that call
PromotedExtenderOverrideScope.Disable/Enable are placed in that collection to
prevent cross-test interference.

In `@TODO.md`:
- Around line 126-127: The two evidence entries that reference only
repro-bundle.json need matching markdown artifacts added: for each run ID listed
(e.g., runs/20260301-004145 and runs/20260301-004232) add a paired evidence line
pointing to the corresponding repro-bundle.md (e.g.,
TestResults/runs/<runId>/repro-bundle.md) so each JSON bundle has its paired
markdown; update the entries that currently show only `repro-bundle.json` to
include the paired `repro-bundle.md` artifact for both run IDs.

---

Nitpick comments:
In `@tests/SwfocTrainer.Tests/Profiles/ProfileMetadataPortabilityTests.cs`:
- Line 19: Change the file discovery to search recursively so profile files in
subfolders aren’t missed: update the Directory.GetFiles call that assigns
profileFiles (currently using profileDirectory and
SearchOption.TopDirectoryOnly) to use SearchOption.AllDirectories (or an
equivalent recursive enumeration) so all "*.json" profile files under
profileDirectory are discovered; ensure any code that expects flat results still
works or is adjusted to handle nested paths.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7e6f2a9 and 2c9965a.

📒 Files selected for processing (10)
  • TODO.md
  • docs/LIVE_VALIDATION_RUNBOOK.md
  • docs/TEST_PLAN.md
  • profiles/default/profiles/base_sweaw.json
  • profiles/default/profiles/base_swfoc.json
  • profiles/default/profiles/universal_auto.json
  • src/SwfocTrainer.Runtime/Services/BackendRouter.cs
  • tests/SwfocTrainer.Tests/Profiles/ProfileInheritanceTests.cs
  • tests/SwfocTrainer.Tests/Profiles/ProfileMetadataPortabilityTests.cs
  • tests/SwfocTrainer.Tests/Runtime/BackendRouterTests.cs
💤 Files with no reviewable changes (2)
  • profiles/default/profiles/base_sweaw.json
  • profiles/default/profiles/base_swfoc.json

Comment on lines +197 to +202
Promoted FoC actions are not forced to extender by default.
For extender-authoritative promoted matrix evidence, explicitly enable:

```powershell
$env:SWFOC_FORCE_PROMOTED_EXTENDER = "1"
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Align matrix pass-count criteria with the current promoted contract.

Line 223 still expects summary.total=15, while the companion runbook gate tracks two-step set_unit_cap entries ([1/2] + [2/2]) for an 18-row closure matrix. Please sync this section to avoid accepting incomplete promoted evidence.

Also applies to: 223-225, 236-240

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/TEST_PLAN.md` around lines 197 - 202, The TEST_PLAN expects
summary.total=15 but the promoted contract now records two-step set_unit_cap
entries (e.g., "[1/2]" + "[2/2]") producing an 18-row closure matrix; update the
assertions/expected values that reference summary.total=15 to summary.total=18
and adjust any companion checks that validate matrix row counts or pass-count
criteria (including the sections that reference set_unit_cap multi-step entries)
so the runbook gate counts both steps as separate rows and will not accept
incomplete promoted evidence.

Comment on lines +500 to +524
private sealed class PromotedExtenderOverrideScope : IDisposable
{
private const string VariableName = "SWFOC_FORCE_PROMOTED_EXTENDER";
private readonly string? _previousValue;

private PromotedExtenderOverrideScope(string? value)
{
_previousValue = Environment.GetEnvironmentVariable(VariableName);
Environment.SetEnvironmentVariable(VariableName, value);
}

public static PromotedExtenderOverrideScope Disable()
{
return new PromotedExtenderOverrideScope(value: null);
}

public static PromotedExtenderOverrideScope Enable()
{
return new PromotedExtenderOverrideScope(value: "1");
}

public void Dispose()
{
Environment.SetEnvironmentVariable(VariableName, _previousValue);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== xUnit parallelization configuration ==="
rg -n --type=cs 'CollectionBehavior|DisableTestParallelization|CollectionDefinition|DisableParallelization' tests

echo
echo "=== BackendRouterTests env-var mutation sites and collection attributes ==="
rg -n --type=cs -C2 'class BackendRouterTests|Collection\(|Environment\.SetEnvironmentVariable|PromotedExtenderOverrideScope' tests/SwfocTrainer.Tests/Runtime/BackendRouterTests.cs

Repository: Prekzursil/SWFOC-Mod-Menu

Length of output: 112


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Repository structure ==="
ls -la

echo
echo "=== Looking for BackendRouterTests.cs ==="
fd -t f "BackendRouterTests.cs" 2>/dev/null || echo "File not found with fd"

echo
echo "=== Checking tests directory ==="
ls -la tests 2>/dev/null || echo "tests directory not found"

echo
echo "=== Git files in repository ==="
git ls-files | grep -i backendrouter || echo "No BackendRouter files found"

Repository: Prekzursil/SWFOC-Mod-Menu

Length of output: 3145


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== BackendRouterTests.cs - checking for Collection attributes and env-var mutations ==="
cat -n tests/SwfocTrainer.Tests/Runtime/BackendRouterTests.cs | head -100

echo
echo "=== Lines around 500-524 (PromotedExtenderOverrideScope implementation) ==="
cat -n tests/SwfocTrainer.Tests/Runtime/BackendRouterTests.cs | sed -n '495,530p'

echo
echo "=== Checking for Collection attributes anywhere in file ==="
rg -n --type=cs '\[Collection|CollectionDefinition|CollectionBehavior' tests/SwfocTrainer.Tests/Runtime/BackendRouterTests.cs || echo "No Collection attributes found"

echo
echo "=== All uses of Environment.SetEnvironmentVariable in file ==="
rg -n --type=cs 'Environment\.SetEnvironmentVariable' tests/SwfocTrainer.Tests/Runtime/BackendRouterTests.cs

Repository: Prekzursil/SWFOC-Mod-Menu

Length of output: 7578


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Checking for xUnit collection/parallelization settings in test project ==="
rg -n --type=cs 'CollectionBehavior|DisableParallelization|CollectionDefinition' tests/SwfocTrainer.Tests/ 2>/dev/null || echo "No parallelization settings found"

echo
echo "=== Running canonical test verification command ==="
dotnet test tests/SwfocTrainer.Tests/SwfocTrainer.Tests.csproj -c Release --no-build --filter "FullyQualifiedName!~SwfocTrainer.Tests.Profiles.Live&FullyQualifiedName!~RuntimeAttachSmokeTests" 2>&1 | tail -50

Repository: Prekzursil/SWFOC-Mod-Menu

Length of output: 281


Add xUnit Collection attributes to isolate env-var tests from parallel execution.

Lines 508 and 523 mutate a process-global environment variable. Without parallelization guards, xUnit may run tests across collections concurrently, causing cross-test interference and nondeterministic outcomes.

🛠️ Required fix
+using Xunit;
+
 namespace SwfocTrainer.Tests.Runtime;
 
+[Collection(nameof(BackendRouterEnvVarCollection))]
 public sealed class BackendRouterTests
 {
@@
 }
+
+[CollectionDefinition(nameof(BackendRouterEnvVarCollection), DisableParallelization = true)]
+public sealed class BackendRouterEnvVarCollection
+{
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/SwfocTrainer.Tests/Runtime/BackendRouterTests.cs` around lines 500 -
524, Tests using the PromotedExtenderOverrideScope manipulate the process-wide
env var "SWFOC_FORCE_PROMOTED_EXTENDER" and must not run in parallel; create an
xUnit collection to serialize them and apply it to the test class: add a
CollectionDefinition (e.g., name "EnvVarSerial") with DisableParallelization =
true, and annotate the test class containing PromotedExtenderOverrideScope (or
any other classes/tests that use it) with [Collection("EnvVarSerial")], ensuring
all tests that call PromotedExtenderOverrideScope.Disable/Enable are placed in
that collection to prevent cross-test interference.

Comment on lines +126 to +127
evidence: bundle `TestResults/runs/20260301-004145/repro-bundle.json` (`classification=blocked_environment`, tactical default routing run; no swfoc process detected)
evidence: bundle `TestResults/runs/20260301-004232/repro-bundle.json` (`classification=blocked_environment`, tactical forced-override run; no swfoc process detected)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add matching repro-bundle.md evidence entries.

Line 126 and Line 127 list only repro-bundle.json. For runtime/mod closure evidence in this repo, include the paired markdown artifact too for each run ID.

📎 Suggested update
   evidence: bundle `TestResults/runs/20260301-004145/repro-bundle.json` (`classification=blocked_environment`, tactical default routing run; no swfoc process detected)
+  evidence: bundle `TestResults/runs/20260301-004145/repro-bundle.md` (`classification=blocked_environment`, tactical default routing run; no swfoc process detected)
   evidence: bundle `TestResults/runs/20260301-004232/repro-bundle.json` (`classification=blocked_environment`, tactical forced-override run; no swfoc process detected)
+  evidence: bundle `TestResults/runs/20260301-004232/repro-bundle.md` (`classification=blocked_environment`, tactical forced-override run; no swfoc process detected)

Based on learnings: Mod/runtime bugfixes must include a reproducible bundle with TestResults/runs/<runId>/repro-bundle.json and TestResults/runs/<runId>/repro-bundle.md.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
evidence: bundle `TestResults/runs/20260301-004145/repro-bundle.json` (`classification=blocked_environment`, tactical default routing run; no swfoc process detected)
evidence: bundle `TestResults/runs/20260301-004232/repro-bundle.json` (`classification=blocked_environment`, tactical forced-override run; no swfoc process detected)
evidence: bundle `TestResults/runs/20260301-004145/repro-bundle.json` (`classification=blocked_environment`, tactical default routing run; no swfoc process detected)
evidence: bundle `TestResults/runs/20260301-004145/repro-bundle.md` (`classification=blocked_environment`, tactical default routing run; no swfoc process detected)
evidence: bundle `TestResults/runs/20260301-004232/repro-bundle.json` (`classification=blocked_environment`, tactical forced-override run; no swfoc process detected)
evidence: bundle `TestResults/runs/20260301-004232/repro-bundle.md` (`classification=blocked_environment`, tactical forced-override run; no swfoc process detected)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@TODO.md` around lines 126 - 127, The two evidence entries that reference only
repro-bundle.json need matching markdown artifacts added: for each run ID listed
(e.g., runs/20260301-004145 and runs/20260301-004232) add a paired evidence line
pointing to the corresponding repro-bundle.md (e.g.,
TestResults/runs/<runId>/repro-bundle.md) so each JSON bundle has its paired
markdown; update the entries that currently show only `repro-bundle.json` to
include the paired `repro-bundle.md` artifact for both run IDs.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 1, 2026

@Prekzursil Prekzursil merged commit e114f29 into main Mar 1, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Review effort 3/5 risk:high High-risk change; strict human gate required.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant