← Back to blog
Engineering note2026-08-10 00:00 UTC

Pressure-testing Ota on nopCommerce: managed .NET verification across native and container CI

nopCommerce pressure-tested Ota's managed GitHub projection for a .NET restore-and-build lane across native and container Linux, while preserving provider-owned CI policy.

The question

nopCommerce is a useful test of where Ota should stop owning CI. Its .NET repository has substantial provider-owned workflow and deployment policy; Ota should not turn that into a second CI language. The pressure question was narrower: can Ota own a restore-and-build verification lane while GitHub retains triggers, runners, permissions, environments, and release policy?

The setup task expresses restore as typed dependency hydration, then the workflow runs a finite aggregate verification task:

SELECTED .NET VERIFICATION LANEyaml
setup:  prepare:    kind: dependency_hydration    medium: package_dependencies    source:      kind: dotnet_restore      cwd: src/Tests/Nop.Tests verify:  aggregate:    tasks:      - build workflows:  verify:    setup:      task: setup    run:      task: verify

The pressure result

The contract declares native and container execution for the same workflow. Ota projects each into an Ota-owned reusable workflow, binds it to a target OS and projection identity, and asks the human-owned GitHub caller to supply that identity. The caller is an adapter, not a second authority.

Moving the contract from the old implementation branch to released v1.6.25 changed both projection identities. The old caller refused immediately. That was the useful failure: it made stale governance YAML visible before any verification task ran. We regenerated the native and container projections with the released Ota binary, updated the caller bindings, and re-ran them.

The result is two linked release-backed proofs at commit 409bcc073d: the contract matrix installed Ota v1.6.25, executed restore and build on native and container Linux, and dry-ran the selected surface on macOS and Windows. The managed governance run verified both regenerated identities before executing the finite task and archiving its receipt.

This is the ownership split Ota needs: the contract owns restore, verification, admission, mode, and projection identity; GitHub retains its provider policy. Neither side has to duplicate the other's truth.

Why the refusal matters

Bootstrap truth is execution truth. Changing an Ota source from an implementation branch to a release changes the engine that interprets the contract, so it must change the projected lane's identity too. Treating that as a cosmetic edit would let a caller keep asserting governance that it was no longer able to reproduce.

The initial refusal made the mismatch actionable: no task ran, the expected identity was reported, and ota ci github sync could regenerate the Ota-owned files from the same release that CI would install. That is a better failure mode than a hand-maintained workflow silently drifting until a toolchain or execution change reveals it later.

Why the split is practical

This is not an argument that all GitHub workflow YAML should disappear. nopCommerce still needs provider-owned decisions that are specific to the repository: when to run, which runner to use, what credentials are available, and how releases are protected. Those are not contract defaults.

What Ota can own without overreaching is the governed lane inside that caller: the selected workflow, its toolchain fulfillment, native or container mode, agent admission, and the stable check identity branch protection can require. That leaves a small human-owned adapter instead of two independently authored execution plans.

Boundary

This is a restore-and-build baseline, not full nopCommerce proof. The modeled test task was admitted and dry-run but not executed. Database-backed behavior, frontend workflows, runtime readiness, Windows execution, and deployment remain outside the claim. The container image uses a tag rather than a digest, so the container result is run-specific execution evidence, not immutable image provenance.