Skip to content

ADR-187: Add backend local-dev guardrails (Scalar, LocalStack startup checks, and docs) and unblock Linux full-solution builds#145

Merged
jodavis merged 10 commits intofeature/ADR-161-cusrtomization-servicefrom
copilot/adr-187-implement-layout-customization
Apr 23, 2026
Merged

ADR-187: Add backend local-dev guardrails (Scalar, LocalStack startup checks, and docs) and unblock Linux full-solution builds#145
jodavis merged 10 commits intofeature/ADR-161-cusrtomization-servicefrom
copilot/adr-187-implement-layout-customization

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 18, 2026

  • Review new PR comment and identify actionable review feedback
  • Check workflow runs for base and current branches per stacked-PR guidance
  • Update backend startup check reliability (retry/backoff) and improve exception logging diagnostics
  • Update outdated test XML documentation wording
  • Build with warnings-as-errors and run tests
  • Verify dotnet run + /scalar endpoint success
  • Run parallel validation and address findings if needed
  • Reply to PR comment with commit hash

@jodavis
Copy link
Copy Markdown
Owner

jodavis commented Apr 18, 2026

@copilot confirm that you can dotnet run the two backend services and get a successful response from their scalar endpoints. If they don't work after following the setup instructions provided, then debug the issues, fix the code, and update setup instructions as needed.

@jodavis jodavis requested a review from Copilot April 18, 2026 19:57
@jodavis jodavis marked this pull request as ready for review April 18, 2026 19:57
@jodavis jodavis self-requested a review as a code owner April 18, 2026 19:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a standardized local-development workflow for backend services (OpenAPI + Scalar UI, LocalStack dependency guardrails, and supporting docs), updates test infrastructure to satisfy the new startup check, and tweaks project settings so the full solution can build on Linux agents while preserving Windows-only runtime constraints.

Changes:

  • Added OpenAPI generation plus Development-only Scalar UI (/scalar) and a Development-time LocalStack health check that exits non-zero on failure.
  • Extended local-dev infrastructure and documentation (LocalStack in docker-compose.yml, new docs/local-dev.md, expanded backend dev guide).
  • Updated backend API test authority to serve /_localstack/health, and enabled Windows targeting on E2E host test projects to unblock Linux solution builds.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/AdaptiveRemote.EndtoEndTests.Host.Console/AdaptiveRemote.EndToEndTests.Host.Console.csproj Enables Windows targeting so restore/build can succeed on non-Windows agents.
test/AdaptiveRemote.EndToEndTests.Host.Wpf/AdaptiveRemote.EndToEndTests.Host.Wpf.csproj Enables Windows targeting so restore/build can succeed on non-Windows agents.
test/AdaptiveRemote.Backend.ApiTests/Support/TestJwtAuthority.cs Adds /_localstack/health endpoint to satisfy LocalStack startup checks during tests.
test/AdaptiveRemote.Backend.ApiTests/Support/ServiceFixture.cs Wires LocalStack__BaseUrl for the service process and adjusts health polling logging.
src/_doc_BackendDevelopment.md Defines the standing backend dev pattern and verification steps for ADR-187.
src/AdaptiveRemote.Backend.CompiledLayoutService/appsettings.Development.json Adds default LocalStack:BaseUrl for development.
src/AdaptiveRemote.Backend.CompiledLayoutService/Properties/launchSettings.json Adds a dedicated Development profile (console output capture + scalar launch).
src/AdaptiveRemote.Backend.CompiledLayoutService/Program.cs Implements LocalStack startup guardrail and OpenAPI/Scalar endpoint mapping.
src/AdaptiveRemote.Backend.CompiledLayoutService/Logging/MessageLogger.cs Adds a structured error log message for LocalStack dependency failures.
src/AdaptiveRemote.Backend.CompiledLayoutService/AdaptiveRemote.Backend.CompiledLayoutService.csproj Adds OpenAPI + Scalar package references.
docs/local-dev.md New local backend dependency/setup guide (Docker/LocalStack, Scalar, Lambda invocation examples).
docker-compose.yml Adds LocalStack service and wires CompiledLayoutService to it.
Directory.Packages.props Pins package versions for Microsoft.AspNetCore.OpenApi and Scalar.AspNetCore.

Comment on lines +84 to +101
const int LocalStackHealthCheckTimeoutSeconds = 5;

string baseUrl = app.Configuration["LocalStack:BaseUrl"] ?? "http://localhost:4566";

if (!Uri.TryCreate(baseUrl, UriKind.Absolute, out Uri? baseUri))
{
logger.LocalStackDependencyUnavailable(baseUrl, "configuration value is not a valid absolute URL");
Environment.Exit(1);
}

Uri healthUri = new(baseUri, "/_localstack/health");

using HttpClient client = new() { Timeout = TimeSpan.FromSeconds(LocalStackHealthCheckTimeoutSeconds) };

try
{
using HttpResponseMessage response = await client.GetAsync(healthUri).ConfigureAwait(false);
string body = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
EventId = 1108,
Level = LogLevel.Error,
Message = "LocalStack dependency check failed at {HealthUrl}: {FailureReason}. LocalStack is required for local development. See docs/local-dev.md for setup instructions")]
public static partial void LocalStackDependencyUnavailable(this ILogger logger, string healthUrl, string failureReason);
Comment on lines 14 to 18
/// Exposes two endpoints on a dynamically-assigned localhost port:
/// GET /.well-known/openid-configuration — OIDC discovery document
/// GET /.well-known/jwks.json — RSA public key in JWK format
/// GET /_localstack/health — LocalStack-compatible health response
///
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 18, 2026

@copilot confirm that you can dotnet run the two backend services and get a successful response from their scalar endpoints. If they don't work after following the setup instructions provided, then...

Confirmed and fixed. dotnet run for AdaptiveRemote.Backend.CompiledLayoutService now starts successfully with LocalStack running, and GET /scalar returns 200 with the Scalar UI. Root cause was LocalStack 4.8 health JSON no longer always including status; startup check now accepts either status: running or required service states (dynamodb, lambda, sqs) as available/running. Also updated docs/local-dev.md to match actual LocalStack responses and clarified current branch scope. Commits: 48cbb0a, 012f888.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 127.0.0.11
    • Triggering command: REDACTED, pid is -1 (packet block)
  • 8.8.8.8
    • Triggering command: REDACTED, pid is -1 (packet block)
  • analytics.localstack.cloud
    • Triggering command: /opt/code/localstack/.venv/bin/python /opt/code/localstack/.venv/bin/python -m localstack.runtime.main (dns block)
  • api.localstack.cloud
    • Triggering command: /opt/code/localstack/.venv/bin/python /opt/code/localstack/.venv/bin/python -m localstack.runtime.main (dns block)
  • assets.localstack.cloud
    • Triggering command: /opt/code/localstack/.venv/bin/python /opt/code/localstack/.venv/bin/python -m localstack.runtime.main (dns block)
  • localhost.localstack.cloud
    • Triggering command: /opt/code/localstack/.venv/bin/localstack /opt/code/localstack/.venv/bin/localstack status services --format=json (dns block)
    • Triggering command: /opt/code/localstack/.venv/bin/localstack /opt/code/localstack/.venv/bin/localstack status services --format=json --detach --pid-file /run/containerd/io.containerd.runtime.v2.task/moby/b7aeb5cc38c80c98f5aa2e2f9cbf2caad00554e1be80be65eede46de63ffddbf/e00d436d581686461dea6c9bfd203695654579c462bfb605f213f1ccf649/run/containerd/io.containerd.runtime.v2.task/moby/b7aeb5cc38c80c98f5aa2e2f9cbf2 caad00554e1be80be65eede46de63ffddbf/log.json (dns block)
    • Triggering command: /opt/code/localstack/.venv/bin/localstack /opt/code/localstack/.venv/bin/localstack status services --format=json f295.pid --pid-file /run/containerd/io.containerd.runtime.v2.task/moby/b7aeb5cc38c80c98f5aa2e2f9cbf2caad00554e1be80be65eede46de63ffddbf/2b5ee4c9b8628234ac55bacde9404ee84262be62ee30459efd4806fc7407048d.pid b7aeb5cc38c80c98f5aa2e2f9cbf2caad00554e1be80be65eede46de63ffddbf (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 18, 2026

Test Results

407 tests  ±0   407 ✅ ±0   2m 21s ⏱️ +2s
 12 suites ±0     0 💤 ±0 
 12 files   ±0     0 ❌ ±0 

Results for commit 8844b71. ± Comparison against base commit af07885.

♻️ This comment has been updated with latest results.

@jodavis
Copy link
Copy Markdown
Owner

jodavis commented Apr 19, 2026

@copilot address code review comments. Make sure the repo builds without warnings or errors, that all tests pass, that dotnet run works, and that the scalar endpoint returns successfully.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 19, 2026

@copilot address code review comments. Make sure the repo builds without warnings or errors, that all tests pass, that dotnet run works, and that the scalar endpoint returns successfully.

Addressed the review comments in commits 86890db, 242807c, and d0c9a9e.

  • Added LocalStack startup retry/backoff (~30s) in EnsureLocalStackRunningAsync.
  • Updated LocalStackDependencyUnavailable to accept/log Exception? for diagnostics.
  • Fixed TestJwtAuthority XML docs to say three endpoints.
  • Verified dotnet build /warnaserror succeeds at repo root.
  • Verified dotnet run for AdaptiveRemote.Backend.CompiledLayoutService in Development and GET /scalar returns 200 with Scalar UI.
  • Verified backend API tests pass (AdaptiveRemote.Backend.ApiTests: 6/6).

Note: in this Linux sandbox, WindowsDesktop testhost projects cannot execute (Microsoft.WindowsDesktop.App unavailable), so full cross-target execution of every test project is environment-limited.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 127.0.0.11
    • Triggering command: REDACTED, pid is -1 (packet block)
  • 8.8.8.8
    • Triggering command: REDACTED, pid is -1 (packet block)
  • analytics.localstack.cloud
    • Triggering command: /opt/code/localstack/.venv/bin/python /opt/code/localstack/.venv/bin/python -m localstack.runtime.main r 20260419T025833/In/ProgrammaticSettings.ini tive�� (dns block)
  • api.localstack.cloud
    • Triggering command: /opt/code/localstack/.venv/bin/python /opt/code/localstack/.venv/bin/python -m localstack.runtime.main r 20260419T025833/In/ProgrammaticSettings.ini tive�� (dns block)
  • assets.localstack.cloud
    • Triggering command: /opt/code/localstack/.venv/bin/python /opt/code/localstack/.venv/bin/python -m localstack.runtime.main r 20260419T025833/In/ProgrammaticSettings.ini tive�� (dns block)
  • localhost.localstack.cloud
    • Triggering command: /opt/code/localstack/.venv/bin/localstack /opt/code/localstack/.venv/bin/localstack status services --format=json (dns block)
    • Triggering command: /opt/code/localstack/.venv/bin/localstack /opt/code/localstack/.venv/bin/localstack status services --format=json -j DNAT --to-destination 172.18.0.2:4566 ! -i br-8d6b9689f739 (dns block)
    • Triggering command: /opt/code/localstack/.venv/bin/localstack /opt/code/localstack/.venv/bin/localstack status services --format=json --detach --pid-file /run/containerd/io.containerd.runtime.v2.task/moby/726c74d170c80711ca832925d0cbeaf2d365c916fe92b5b0f3f652cfa05110b2/93e96080c81795d0696a280435cb3d1608fcb9f293e09d1221270320f8c7026d.pid 726c74d170c80711ca832925d0cbeaf2d365c916fe92b5b0f3f652cfa05110b2 veRemote/Adaptiv/usr/sbin/iptables est/AdaptiveRemo--wait (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from jodavis April 19, 2026 03:18
@jodavis jodavis force-pushed the feature/ADR-161-cusrtomization-service branch 2 times, most recently from 9a1ea3f to af07885 Compare April 21, 2026 03:35
ElwoodMoves and others added 9 commits April 22, 2026 16:49
@jodavis jodavis force-pushed the copilot/adr-187-implement-layout-customization branch from 3cb3a45 to 8844b71 Compare April 23, 2026 00:18
@jodavis jodavis merged commit 5866773 into feature/ADR-161-cusrtomization-service Apr 23, 2026
2 checks passed
@jodavis jodavis deleted the copilot/adr-187-implement-layout-customization branch April 23, 2026 00:36
jodavis added a commit that referenced this pull request Apr 23, 2026
… checks, and docs) and unblock Linux full-solution builds (#145)

* Update global.json to allow installed .NET SDKs in different environments

* Implement ADR-187 backend dev environment foundations

Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/b1ffa40a-c569-45a6-ad54-bf0f1a3681b0

Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>

* Enable windows targeting for non-headless E2E host projects

Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/b1ffa40a-c569-45a6-ad54-bf0f1a3681b0

Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>

* Refine LocalStack health check diagnostics in backend startup

Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/b1ffa40a-c569-45a6-ad54-bf0f1a3681b0

Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>

* Fix LocalStack health parsing for dotnet run startup verification

Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/d15fa3e9-7842-4324-aade-379b3c18dde0

Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>

* Clarify LocalStack health response docs

Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/d15fa3e9-7842-4324-aade-379b3c18dde0

Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>

* Add LocalStack startup retries and exception-aware dependency logging

Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/af738fc3-eb45-4437-8bb9-b96b3afb41f0

Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>

* Address reviewer nits in LocalStack startup checks

Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/af738fc3-eb45-4437-8bb9-b96b3afb41f0

Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>

* Refine LocalStack timeout constants and naming consistency

Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/af738fc3-eb45-4437-8bb9-b96b3afb41f0

Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>

* Update _doc_Auth.md with details on how to get an access token for scalar testing.

---------

Co-authored-by: Joe Davis <ElwoodMoves@hotmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>
jodavis added a commit that referenced this pull request Apr 29, 2026
… checks, and docs) and unblock Linux full-solution builds (#145)

* Update global.json to allow installed .NET SDKs in different environments

* Implement ADR-187 backend dev environment foundations

Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/b1ffa40a-c569-45a6-ad54-bf0f1a3681b0

Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>

* Enable windows targeting for non-headless E2E host projects

Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/b1ffa40a-c569-45a6-ad54-bf0f1a3681b0

Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>

* Refine LocalStack health check diagnostics in backend startup

Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/b1ffa40a-c569-45a6-ad54-bf0f1a3681b0

Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>

* Fix LocalStack health parsing for dotnet run startup verification

Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/d15fa3e9-7842-4324-aade-379b3c18dde0

Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>

* Clarify LocalStack health response docs

Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/d15fa3e9-7842-4324-aade-379b3c18dde0

Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>

* Add LocalStack startup retries and exception-aware dependency logging

Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/af738fc3-eb45-4437-8bb9-b96b3afb41f0

Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>

* Address reviewer nits in LocalStack startup checks

Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/af738fc3-eb45-4437-8bb9-b96b3afb41f0

Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>

* Refine LocalStack timeout constants and naming consistency

Agent-Logs-Url: https://github.com/jodavis/AdaptiveRemote/sessions/af738fc3-eb45-4437-8bb9-b96b3afb41f0

Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>

* Update _doc_Auth.md with details on how to get an access token for scalar testing.

---------

Co-authored-by: Joe Davis <ElwoodMoves@hotmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jodavis <6740581+jodavis@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants