Skip to content

feat(router): ship the Go router image and remove the Python implementation - #10359

Merged
rabeckett merged 4 commits into
mainfrom
rabeckett-router-go-cutover
Oct 20, 2026
Merged

rabeckett merged 4 commits into
mainfrom
rabeckett-router-go-cutover

Conversation

@rabeckett

Copy link
Copy Markdown
Collaborator

Closes #10358

Part of #10261 (step 5 of 7).

Summary

This PR makes the Go port the router:

  • the router image runs the static Go binary on scratch;
  • AWF's compose healthcheck runs the binary's healthcheck subcommand instead of Python;
  • the Python implementation, its tests, packaging, CI jobs and Dependabot entries are removed;
  • the Go module moves up from containers/router/go/ to containers/router/;
  • the router version becomes 0.2.0.

The HTTP API, the CLI, the image name, the port, the environment variables and the tables path stay the same. The only API change is that openapi.yaml no longer documents the 504 request_timeout response (see the decisions below).

Changes

  • Image (Dockerfile, .dockerignore):
    • A multi-stage build. The builder is golang:1.27.3-alpine, pinned by digest at go.mod's toolchain version. It runs on $BUILDPLATFORM and cross-compiles a static binary (CGO_ENABLED=0, -trimpath), so the release's two-platform build needs no emulation.
    • The runtime stage is FROM scratch. It holds only the binary at /usr/local/bin/gh-aw-router, the six tables in /routing, /app/openapi.yaml, and a CA bundle for HTTPS OTLP export later. The builder filters that bundle through AWF's CA distrust policy in trust/, as the Python image did. Directories and the binary are 0555; data files are 0444.
    • Every check runs in the builder, because the runtime has no shell. The build fails unless OPENAPI_SHA256 matches openapi.yaml, and unless the optional VERSION argument matches version in main.go. OPENAPI_SHA256 on its own is still enough for a build, so AWF's --build-local and supply-chain-scan.yml are unchanged.
    • Unchanged: the labels, USER 10001:10001, GH_AW_ROUTER_ROUTING_TABLES=/routing, EXPOSE 8737, STOPSIGNAL SIGTERM and the serve command.
    • The image sets GOMAXPROCS=2 and GOMEMLIMIT=384MiB, because AWF limits the router to 512 MiB and 100 processes but sets no CPU quota.
    • It declares no HEALTHCHECK, like the other AWF images.
    • .dockerignore is an allowlist: the Dockerfile, openapi.yaml, go.mod, the non-test Go files, routing/cost-*.json and trust/.
  • AWF:
    • src/services/router-service.ts: ROUTER_HEALTHCHECK_TEST becomes the exec-form CMD /usr/local/bin/gh-aw-router healthcheck, with the same timings. That command needs no tables and never uses a proxy, so the ROUTER_PORT constant is gone.
    • src/compose-generator.test.ts expects the new command.
    • tests/integration/model-routing.test.ts used to default ROUTER_IMAGE to the legacy Python image (ghcr.io/githubnext/gh-aw-router). Without ROUTER_IMAGE, its compose file now builds containers/router, so it can't pair the Go healthcheck with a Python image.
    • containers/api-proxy/fixtures/routing-corpus.js: a comment now says to refresh cases from testdata/routing-contract, since the contract exporter is gone.
  • Layout:
    • go/*.go and go.mod move up to containers/router/. They form one flat main package next to openapi.yaml, routing/, schemas/, examples/ and trust/.
    • The module path becomes github.com/github/gh-aw-firewall/containers/router.
    • tests/fixtures/ becomes testdata/.
  • Go tests for the Python-only tests: five new files, about 800 lines.
    • container_test.go replaces test_container.py and runs when GH_AW_ROUTER_TEST_IMAGE names a built image.
      • It checks the image config: user, port, entrypoint, no HEALTHCHECK, and labels.
      • It runs the image hardened as AWF does, plus a read-only root filesystem, and waits for healthcheck.
      • It checks that there's no shell and that the logs are JSON.
      • It checks that the router exits 0 within the 1 s that AWF's teardown (docker compose down -t 1) allows.
      • Then it replays the routing-contract corpus against the container.
    • corpus_test.go replaces the corpus replay in test_http.py.
      • It replays the corpus through the HTTP handler.
      • It checks that case IDs are unique, that every endpoint has a case, and that the explicit-* cases cover all six profiles.
      • A malformed corpus file fails the tests instead of being skipped.
    • openapi_test.go replaces test_openapi.py. It checks that openapi.yaml documents exactly the served paths, methods and error codes, and that every $ref resolves.
    • schema_test.go replaces test_table_schema.py. It pins the published table schema's hash, checks its enums and patterns against the Go types, and checks the bundled and contract tables against those patterns.
    • docs_test.go replaces test_examples.py and the documentation link check.
      • It posts the README's curl examples to a server with the bundled tables.
      • It checks the README's classifier and route examples against real responses.
      • It checks documentation links.
    • The shutdown tests now send the signal once the server holds the test request. They used to send it after a fixed 100 ms sleep, so under load it could arrive before the request.
    • The parity fixtures stay as data for the Go replay tests.
      • The known-differences maps are folded into the expectations, so the fixtures now record Go's behavior.
      • unicode/ is deleted.
      • The fixture README is rewritten, and its decisions table stays as the record of where Go differs from Python.
  • Removed, about 8,400 lines of Python and lock files:
    • src/gh_aw_router/;
    • the Python tests and helpers, including differential.py and the contract exporter;
    • pyproject.toml, uv.lock and requirements.lock;
    • the Python .gitignore entries.
  • CI and release:
    • test-router.yml:
      • drops the Python checks, advisories (pip-audit) and differential jobs;
      • runs the Go job from containers/router, still on Linux and Windows, with -race and govulncheck on Linux;
      • adds a container job that builds the image and runs the container tests.
    • release.yml build-router drops the QEMU step. Its build arguments and label checks are unchanged.
    • dependabot.yml drops the router's uv entry and its python ignore. The router's Docker entry now tracks the golang builder. There's no gomod entry, because the module has no dependencies.
  • Docs:
    • The router README is rewritten for Go: build, CLI, healthcheck, serving limits, log format, container and tests.
    • docs/releasing.md says that the build checks VERSION against main.go.

Decisions for maintainers

  • AWF keeps owning the healthcheck command.
  • No 504 response.
    • Go's net/http server closes a connection that passes its read or write deadline instead of answering it, so openapi.yaml drops the 504 request_timeout response.
    • The API proxy's router client (routing-router-client.js) marks both a 5xx and a dropped connection as transient, so it handles the two the same way.
  • Router 0.2.0. This is a minor bump for the runtime change and the removed 504. The API proxy checks only the router's name from /capabilities, not its version, so it needs no change.
  • Dropped rather than ported:
    • The contract-archive exporter. The routing-contract corpus is the source of truth, and the API proxy's tests copy the cases they need from it.
    • The tests that exercised only Python packaging or the 504 deadline.
    • The jsonschema validation of corpus requests and example responses against openapi.yaml's schemas, because Go's standard library has no JSON Schema validator. The corpus replay pins the runtime behavior. As the README asks, review keeps the OpenAPI schemas in step with it.
  • Fixture expectations. From now on they record Go's behavior and are edited by hand, only in a reviewed PR.

Validation

  • gofmt -l, go vet and go test ./... pass in containers/router, with Go 1.27.2 on Windows and in a golang:1.27.3 Linux container. TestServeShutdown passed 30 runs in a row on Windows and 20 on Linux.
  • The container tests pass against an image built from this branch: the image config, the hardened run, the bundled tables and the routing-contract corpus.
  • Release dry run.
    • docker buildx build --platform linux/amd64,linux/arm64 with build-router's VCS_REF and OPENAPI_SHA256, on a builder with only native linux/arm64 and no QEMU.
    • Both platforms built, with the expected revision label and version 0.2.0.
    • A wrong OPENAPI_SHA256 fails at the checksum step, and a mismatched VERSION fails at the version check.
  • AWF's src/compose-generator.test.ts and scripts/security/ca-trust.test.ts pass (Jest on Linux, in Docker).
  • End to end, locally (Docker Desktop 29.6.2, arm64):
    • I didn't run tests/integration/model-routing.test.ts as is, because its cleanup() prunes every stopped container and unused network on the host.
    • Instead I ran its compose file and smoke script by hand. The router was built from this branch and ran with AWF's healthcheck and hardening. The API proxy was 0.28.60 for arm64, because the test's pinned API proxy is amd64-only.
    • The router became healthy, and the smoke script's health, capabilities, classify and route checks passed from inside the API proxy.
    • The router exited 0 on docker stop -t 1.
  • Grype v0.116.0 with the repo's .grype.yaml finds no vulnerabilities in the image. This PR's supply-chain scan rebuilds the image and runs the same blocking gate.
  • test-model-routing runs only on main, so this PR gets no routed end-to-end run in CI. It will run on the merge commit.
  • After the AWF release that ships this change, I'll run the routing task set in the gh-aw sandbox, pinned to that release, and compare its firewall.model_routing records with a run on the previous release. gh-aw should bump its default AWF version only after that passes.

Rollback

AWF and its router image ship together, so roll back both together:

  • pin the previous AWF release, which brings its own Python router image and healthcheck;
  • or revert this PR before later Go-only changes build on it.

rabeckett and others added 3 commits October 20, 2026 14:12
Build the router image from the Go binary on scratch and switch AWF's
router healthcheck to the binary's exec-form `healthcheck` subcommand.
Bump the router to 0.2.0 and drop the 504 request_timeout from
openapi.yaml, since net/http closes connections at its deadlines. The
builder uses the Go 1.27.3 pin and filters the image's CA bundle through
AWF's CA distrust policy, as the Python image did.

Port the remaining Python-only tests to Go: the container tests, the
routing-contract corpus replay, and checks of openapi.yaml, the table
schema and documentation links. Fold the known Go differences into the
parity fixtures, which are now edited by hand, and delete the Python
package, tests, lockfiles, Unicode data, CI jobs and Dependabot entry.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The go/ directory only existed to sit beside the Python package's src/. With Python gone,
the router follows Go's layout for a single command: go.mod and the main package's files at
the module root, beside the Dockerfile, as the API proxy's sources sit beside theirs. Test
fixtures move from tests/fixtures/ to testdata/, which the go tool ignores.

The module path now matches its directory. The tests read the tables, schemas, examples,
fixtures and openapi.yaml relative to the package instead of through "..". The Dockerfile,
.dockerignore allowlist, .gitignore, test-router.yml, README and release docs follow the
new paths.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Port the remaining Python checks: the README's examples run against the
  bundled tables and match its classifier output and route response
  examples, every openapi.yaml $ref resolves, and the routing-contract
  corpus has unique IDs, a case for every endpoint and explicit-* cases
  for all six profiles.
- Fail on corpus files that are neither case lists nor a response_file,
  instead of skipping them.
- Check that the container exits 0 within the 1 s that AWF's teardown
  (docker compose down -t 1) allows, rather than timing docker stop.
- Signal the shutdown tests' server once it holds the request, instead of
  after a fixed sleep, which failed under load.
- Describe behavior in comments without the removed Python service, except
  where it explains a rule or where expected values came from, and say
  that the container tests also make the root filesystem read-only, which
  AWF doesn't.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI max review requested due to automatic review settings October 20, 2026 21:19
@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Documentation Preview

Documentation has been built for this PR.

Download preview artifact

To view locally:

  1. Download the docs-preview-pr-10359 artifact from the workflow run
  2. Unzip and open index.html in your browser

Built from commit 4b7f6ed

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

✅ Coverage Check Passed

Overall Coverage

Metric Base PR Delta
Lines 93.44% 93.45% 📈 +0.01%
Statements 92.03% 92.04% 📈 +0.01%
Functions 91.21% 91.21% ➡️ +0.00%
Branches 86.11% 86.12% 📈 +0.01%
📁 Per-file Coverage Changes (1 files)
File Lines (Before → After) Statements (Before → After)
src/nvx/one-shot-adapter.ts 82.9% → 83.4% (+0.56%) 80.2% → 80.7% (+0.52%)

Coverage comparison generated by scripts/ci/compare-coverage.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Literal VERSION validation and contract-table schema coverage must be fixed before approval.

1 open issue
What changed in this PR

Replaces AWF’s Python router with Go 0.2.0, shipping a static binary on scratch.

Changes:

  • Switches the router image and AWF healthcheck to Go.
  • Relocates Go sources and fixtures; removes Python implementation and tooling.
  • Adds replacement tests and updates CI, release configuration, and OpenAPI.
File Description
tests/​integration/​model-routing.test.ts Builds the local router unless an image is supplied.
src/​services/​router-service.ts Runs the Go healthcheck subcommand.
src/​compose-generator.test.ts Expects the Go healthcheck command.
docs/​releasing.md Documents Go version verification.
containers/​router/​version_test.go Checks version declarations in the relocated module.
containers/​router/​tests/​test_service.py Removes Python service tests.
containers/​router/​tests/​test_parity_corpus.py Removes Python corpus replay.
containers/​router/​tests/​test_heuristics.py Removes Python heuristic tests.
containers/​router/​tests/​test_examples.py Replaces Python example checks with Go coverage.
containers/​router/​tests/​test_contracts.py Removes Python contract tests.
containers/​router/​tests/​test_classification.py Removes Python classification tests.
containers/​router/​tests/​fixtures/​parity/​unicode/​whitespace.json Removes Python Unicode reference data.
containers/​router/​tests/​contract_corpus.py Removes the contract archive exporter.
containers/​router/​tests/​conftest.py Removes Python test setup.
containers/​router/​testdata/​routing-contract/​errors.json Relocates error contract cases.
containers/​router/​testdata/​routing-contract/​discovery.json Updates the expected router version.
containers/​router/​testdata/​routing-contract/​classify.json Relocates classification contract cases.
containers/​router/​testdata/​routing-contract/​classify-response.json Relocates the classifier response fixture.
containers/​router/​testdata/​parity/​labels.json Records Go Unicode behavior.
containers/​router/​testdata/​parity/​context.json Removes unsupported nonfinite-number cases.
containers/​router/​table.go Relocates routing-table loading and validation.
containers/​router/​table_test.go Updates table paths and comments.
containers/​router/​src/​gh_aw_router/​service.py Removes Python service composition.
containers/​router/​src/​gh_aw_router/​routing.py Removes Python context estimation.
containers/​router/​src/​gh_aw_router/​routing_table.py Removes Python table routing.
containers/​router/​src/​gh_aw_router/​py.typed Removes the Python typing marker.
containers/​router/​src/​gh_aw_router/​contracts.py Removes Python contract models.
containers/​router/​src/​gh_aw_router/​cli.py Removes the Python CLI.
containers/​router/​src/​gh_aw_router/​classification.py Removes Python classification.
containers/​router/​src/​gh_aw_router/​__main__.py Removes the Python entrypoint.
containers/​router/​src/​gh_aw_router/​__init__.py Removes Python package metadata.
containers/​router/​server.go Relocates the server and updates commentary.
containers/​router/​server_test.go Shares route expectations and updates comments.
containers/​router/​serve.go Relocates lifecycle and healthcheck logic.
containers/​router/​serve_test.go Synchronizes shutdown signals with active requests.
containers/​router/​schema_test.go Adds schema checks; contract tables are overwritten and skipped before validation.
containers/​router/​route_test.go Moves corpus replay into dedicated tests.
containers/​router/​requirements.lock Removes Python runtime dependency pins.
containers/​router/​pyproject.toml Removes Python packaging configuration.
containers/​router/​parity_test.go Uses relocated, consolidated Go expectations.
containers/​router/​openapi.yaml Updates version and removes the 504 response.
containers/​router/​openapi_test.go Adds API checks; optional correction retains every documented method per path.
containers/​router/​main.go Bumps the router version to 0.2.0.
containers/​router/​logging.go Clarifies historical log-level commentary.
containers/​router/​logging_test.go Relocates structured-logging tests.
containers/​router/​heuristics.go Clarifies Unicode behavior comments.
containers/​router/​heuristics_test.go Uses committed Go expectations directly.
containers/​router/​go/​go.mod Removes the old module location.
containers/​router/​go.mod Defines the relocated module and toolchain.
containers/​router/​docs_test.go Checks documentation examples and links.
containers/​router/​Dockerfile Builds the static Go image; VERSION validation incorrectly accepts regex matches.
containers/​router/​decode.go Updates decoding comments.
containers/​router/​decode_test.go Updates example fixture paths.
containers/​router/​corpus_test.go Adds HTTP corpus replay and coverage checks.
containers/​router/​contract.go Removes the timeout error constant.
containers/​router/​container_test.go Adds hardened-image tests; optional correction makes table files readable under restrictive umasks.
containers/​router/​cli.go Clarifies validation-order commentary.
containers/​router/​cli_test.go Updates paths and shutdown synchronization.
containers/​router/​classify.go Relocates classification implementation.
containers/​router/​classify_test.go Relocates classification coverage.
containers/​router/​.gitignore Replaces Python exclusions with binary exclusions.
containers/​router/​.dockerignore Allowlists Go image build inputs.
containers/​api-proxy/​fixtures/​routing-corpus.js Updates fixture-refresh guidance.
.github/​workflows/​test-router.yml Replaces Python jobs with Go and container checks.
.github/​workflows/​release.yml Removes router QEMU setup.
.github/​dependabot.yml Removes Python dependency tracking and tracks the Go builder.

Review effort: Max

Comment thread containers/router/schema_test.go Outdated
- The Dockerfile matches VERSION as a fixed string, so a regex such as
  0x2x0 no longer passes the version check.
- The schema test keys tables by source, so the bundled tables no longer
  replace the contract tables, and it checks that all of them are covered.
- The OpenAPI test keeps every documented method per path.
- The container corpus test sets the table files' modes with chmod, so a
  restrictive umask can't make them unreadable to the container user.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

✅ Copilot review passed with no inline comments.

@rabeckett Add the ready-for-aw label to this PR to trigger agentic CI smoke tests.

@rabeckett

Copy link
Copy Markdown
Collaborator Author

Thanks for the review. e2dee29 also fixes the three points that appeared only in the review summary:

  • Dockerfile VERSION check. It now uses grep -qxF, so the version must match exactly instead of as a regular expression. A build with VERSION=0x2x0 now fails with "VERSION must match the version constant in main.go", and VERSION=0.2.0 still builds.
  • OpenAPI test. The outline now keeps every method documented for a path, so a second method can't overwrite the first and go unnoticed. servedRoutes still maps each path to one method, because the server serves exactly one method per path and the 405 Allow test relies on that.
  • Container corpus test. After writing each table file, the test sets its mode to 0644 with chmod, so a restrictive umask can't leave the files unreadable to the container user.

gofmt, go vet and go test ./... pass, and so do the container tests against an image built from this commit.

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

📡 Smoke OTel Tracing completed. All tracing scenarios validated. ✅

📡 OTel tracing validated by Smoke OTel Tracing

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Smoke Cloud Hypervisor completed. Cloud Hypervisor + Copilot passed.

Cloud Hypervisor + Copilot smoke test by Smoke Cloud Hypervisor

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

✅ Build Test Suite completed successfully!

Generated by Build Test Suite for #10359

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

🔌 Smoke Services — All services reachable! ✅

🔌 Service connectivity validated by Smoke Services

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

✅ Smoke Copilot BYOK completed. Copilot BYOK mode operational. 🔓

🔑 BYOK report filed by Smoke Copilot BYOK

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

✅ Smoke Claude passed

Generated by Smoke Claude for #10359

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

🔮 The oracle has spoken through Smoke Codex

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

📰 BREAKING: Report filed by Smoke Copilot

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

✅ Smoke Gemini completed. All facets verified. 💎

💎 Faceted by Smoke Gemini

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

✅ Smoke Copilot BYOK AOAI (api-key) completed. Copilot AOAI BYOK (api-key) mode operational. 🔓

🔑 BYOK (AOAI api-key) report filed by Smoke Copilot BYOK AOAI (api-key)

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Security Guard has started processing this pull request

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded.

Tested by Smoke Chroot

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

✅ Smoke Copilot BYOK AOAI (Entra) completed. Copilot AOAI BYOK (Entra) mode operational. 🔓

🪪 BYOK (AOAI Entra) report filed by Smoke Copilot BYOK AOAI (Entra)

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

🛡️ Smoke Copilot Network Isolation confirmed the egress allowlist is enforced. ✅

🛡️ Egress verdict from Smoke Copilot Network Isolation

@github-actions

Copy link
Copy Markdown
Contributor

Cloud Hypervisor + Copilot smoke test

  1. Merged PR lookup: PASS
  2. github.com connectivity: PASS (HTTP 200)
  3. File write/read: PASS
  4. example.com blocked: PASS (HTTP 000)
    Overall: PASS

Cloud Hypervisor + Copilot smoke test by Smoke Cloud Hypervisor
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Copilot: PR "fix: repair Docker enclave smoke workflow compatibility"

  • GitHub MCP ✅
  • GitHub.com connectivity ✅
  • File write/read ✅
    Overall: PASS — @rabeckett

📰 BREAKING: Report filed by Smoke Copilot
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Claude Engine Validation

  • API status: ✅ PASS
  • GitHub check: ✅ PASS
  • File status: ✅ PASS

Overall result: PASS

Generated by Smoke Claude for #10359 · claude · haiku45 · 34 AIC · ⊞ 6.1K · ◷
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Services smoke test: ✅ Redis PONG, ✅ pg_isready accepting connections, ✅ SELECT 1 = 1. PASS

🔌 Service connectivity validated by Smoke Services
Add label ready-for-aw to run again

@github-actions github-actions Bot added smoke-claude smoke-copilot-network-isolation Copilot network-isolation egress smoke test labels Oct 20, 2026
@github-actions

Copy link
Copy Markdown
Contributor

EGRESS_RESULT allow=pass deny=pass

  • ✅ Allowed domain (api.github.com → 200)
  • ✅ Blocked domain (example.com failed: TLS cert error from proxy)

Overall: PASS — cc @rabeckett

🛡️ Egress verdict from Smoke Copilot Network Isolation
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Copilot BYOK (Direct Mode) Smoke Test

✅ GitHub MCP connectivity — Verified via API
✅ GitHub.com connectivity — HTTP 200
✅ File write/read test — Confirmed
✅ BYOK inference test — Active (agent → api-proxy → api.githubcopilot.com)

Overall: PASS

Running in direct BYOK mode (COPILOT_PROVIDER_API_KEY) via api-proxy sidecar.

🔑 BYOK report filed by Smoke Copilot BYOK
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

@rabeckett
fix: use Responses for Azure o4-mini smoke requests (#10355) ✓
Upgrade gh-aw to v0.92.6 prerelease (#10349) ✓

Tests: MCP API ✓ GitHub Connectivity ✓ File I/O ✓ BYOK inference ✓
Running in direct BYOK mode (COPILOT_PROVIDER_API_KEY + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw)
PASS

🔑 BYOK (AOAI api-key) report filed by Smoke Copilot BYOK AOAI (api-key)
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke OTEL tracing

  • ✅ S1 Module loading: otel.js loads; exports startRequestSpan, setTokenAttributes, setBudgetAttributes, endSpan, endSpanError, shutdown, isEnabled (+ internals)
  • ✅ S2 Tests: 3 suites, 68/68 OTEL tests pass
  • ✅ S3 Env forwarding: OTEL/trace vars present in env-passthrough.ts and api-proxy-env-config.ts
  • ✅ S4 Token tracker: onUsage hook present in token-tracker-http.js (10 refs)
  • ⚠️ S5 Diagnostics: no collector post-step output available in this run; span export not verified (checked locally only)

📡 OTel tracing validated by Smoke OTel Tracing
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Chroot Version Comparison

Runtime Host Version Chroot Version Match?
Python Python 3.12.15 Python 3.12.15 ✅
Node.js v24.22.0 v2.98.0 ❌
Go go1.22.12 go1.22.12 ✅

Node.js differs between host and chroot, so the tests did not all pass and the smoke-chroot label was not added.

Tested by Smoke Chroot
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Build Test Suite Results

Ecosystem Project Build/Install Tests Status
Bun elysia ❌ not run ❌ FAIL
Bun hono ❌ not run ❌ FAIL
C++ fmt ✅ N/A ✅ PASS
C++ json ✅ N/A ✅ PASS
Deno oak ❌ not run ❌ FAIL
Deno std ❌ not run ❌ FAIL
.NET hello-world ✅ N/A ✅ PASS
.NET json-parse ✅ N/A ✅ PASS
Go color ✅ 1/1 pkg passed ✅ PASS
Go env ✅ 1/1 pkg passed ✅ PASS
Go uuid ✅ 1/1 pkg passed ✅ PASS
Java gson ❌ not run ❌ FAIL
Java caffeine ❌ not run ❌ FAIL
Node.js clsx ✅ all passed ✅ PASS
Node.js execa ✅ all passed ✅ PASS
Node.js p-limit ✅ all passed ✅ PASS
Rust fd ✅ 1/1 passed ✅ PASS
Rust zoxide ✅ 1/1 passed ✅ PASS

Overall: 5/8 ecosystems passed — FAIL

All 8 clones succeeded.

Failures

  • Bun / Deno: the installer download (curl ... | bash / | sh) was denied by the sandbox permission layer, so the toolchains were never installed and no tests ran.
  • Java: Maven could not resolve maven-resources-plugin:3.5.0. The prescribed squid-proxy:3128 proxy host is not reachable in this run. ~/.m2 was also root-owned, so I used a temporary local repository.
  • .NET needed XDG_RUNTIME_DIR set to a writable path (NuGet mutex error). It then passed.

The build-test label was not added because some ecosystems failed.

Generated by Build Test Suite for #10359 · copilot · auto · 24.6 AIC · ⊞ 12K · ◷
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test

  • fix: use Responses for Azure o4-mini smoke requests
  • Upgrade gh-aw to v0.92.6 prerelease
  • Merged PRs ✅
  • PR details ✅
  • Playwright ❌
  • File write/read ✅
  • Build ✅
  • Overall: FAIL

🔮 The oracle has spoken through Smoke Codex
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test Results

  • Recent PR 1: fix: use Responses for Azure o4-mini smoke requests
  • Recent PR 2: Upgrade gh-aw to v0.92.6 prerelease
  • GitHub MCP Testing: ✅
  • GitHub.com Connectivity: ❌
  • File Writing Testing: ✅
  • Bash Tool Testing: ✅
    Overall status: FAIL

💎 Faceted by Smoke Gemini
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

fix: use Responses for Azure o4-mini smoke requests: ✅
Upgrade gh-aw to v0.92.6 prerelease: ✅
MCP connectivity: ✅
GitHub.com connectivity: ✅
File write/read: ✅
BYOK inference: ✅
Running in direct BYOK mode (AWF_AUTH_TYPE=github-oidc + AWF_AUTH_AZURE_* + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw) authenticated via Microsoft Entra
Overall: PASS
cc @rabeckett

🪪 BYOK (AOAI Entra) report filed by Smoke Copilot BYOK AOAI (Entra)
Add label ready-for-aw to run again

@rabeckett
rabeckett merged commit 5ced075 into main Oct 20, 2026
142 of 145 checks passed
@rabeckett
rabeckett deleted the rabeckett-router-go-cutover branch October 20, 2026 22:46

This branch was successfully deployed

1 active deployment
aoai-model — e2dee297 Deployed Oct 20, 2026 by rabeckett via conclusion #2065
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Router: ship the Go router in the container image and remove the Python implementation

2 participants