← Back to blog
Engineering note2026-07-08 18:10 UTC

Pressure-testing Ota on OrchardCore: first-class dotnet restore and honest narrow .NET proof

How OrchardCore helped prove Ota's .NET contract story on a real ASP.NET Core repo: toolchain-owned dotnet truth, first-class dotnet restore hydration, structured finite dotnet commands, and disciplined narrowing to one truthful contributor slice.

Overview

OrchardCore mattered because it is a real .NET repo, not a toy starter.

Even a narrow slice of the repo carries several different truths at once:

  • dotnet as the real toolchain owner
  • restore as a real dependency-hydration lane
  • build and test as finite CLI surfaces, not shell glue
  • native and container execution both advertised by the contract
  • a much larger repo outside the selected slice that the contract should not pretend to own

That made OrchardCore a useful pressure repo for a simple question:

can Ota represent a serious .NET contributor path cleanly without collapsing back into raw shell or overclaiming the whole repository?

Why this repo mattered

OrchardCore is a broad ASP.NET Core codebase with:

  • many projects
  • broader CI workflows
  • functional and browser-heavy test surfaces
  • asset and documentation paths outside the selected unit-project slice

That is exactly why the repo is useful.

A weak readiness contract would try to flatten all of that into one vague “build and test” surface. A stronger contract narrows intentionally and says what it really owns.

The selected OrchardCore slice is honest:

  • restore one unit-test project
  • build that same project
  • test that same project
  • prove the slice on host and container paths where the contract advertises them

That is the right pressure bar for this repo.

What OrchardCore proved

1. Ota's .NET story is stronger when restore is first-class

The mature setup lane is not:

OLDER SHELL SETUPyaml
setup:  run: dotnet restore test/OrchardCore.Abstractions.Tests/OrchardCore.Abstractions.Tests.csproj

The stronger contract shape is:

FIRST-CLASS DOTNET RESTOREyaml
setup:  prepare:    kind: dependency_hydration    medium: package_dependencies    source:      kind: dotnet_restore      cwd: test/OrchardCore.Abstractions.Tests

That matters because the contract now owns:

  • the hydration lane itself
  • the fact that it is package dependency preparation
  • the requirement on the dotnet toolchain
  • the network semantics of the lane

Instead of leaving all of that implicit inside one shell string.

2. Finite .NET task bodies should stay structured

OrchardCore also proved that plain dotnet build and dotnet test lanes do not need to stay as raw run bodies.

The stronger shape is:

STRUCTURED DOTNET BUILDyaml
build:  command:    exe: dotnet    args:      - build      - --no-restore    cwd: test/OrchardCore.Abstractions.Tests

and:

STRUCTURED DOTNET TESTyaml
test:  command:    exe: dotnet    args:      - test      - --no-restore      - --verbosity      - minimal    cwd: test/OrchardCore.Abstractions.Tests

That gives Ota a better execution boundary:

  • executable identity is explicit
  • arguments are explicit
  • working directory is explicit
  • mode branches only need to vary context, not duplicate command text

That is more mature governance than copying the same shell body across native and container modes.

3. Honest narrowing is more valuable than fake full-repo coverage

OrchardCore did not force a dramatic new Ota core bug.

What it proved instead is equally useful:

Ota can already carry a real .NET repo slice cleanly when the contract is disciplined about what it is and is not claiming.

This contract does not pretend to own:

  • the entire OrchardCore solution
  • every functional test lane
  • every database-backed or browser-backed path
  • every asset or documentation workflow

It owns one clear contributor-readiness slice and proves that slice well.

That is better than a broader but less trustworthy contract.

What changed in the contract

The important changes were not dramatic. They were governance upgrades.

Toolchain ownership is explicit:

DOTNET TOOLCHAINyaml
toolchains:  dotnet:    version: "10.0"    fulfillment:      source: dotnet      mode: run

The workflow now owns the setup boundary directly:

VERIFY WORKFLOWyaml
workflows:  verify:    prepare:      task: setup    run:      task: verify

And verification stays aggregate-owned instead of shell-chained:

VERIFICATION AGGREGATEyaml
verify:  aggregate:    tasks:      - build      - test

That final shape is small, but it is honest and machine-readable.

What the matrix proves

The current green OrchardCore matrix run for this narrowed slice is #28971743168.

That run is enough to support the note because it proved the slice the contract actually claims:

  • ota validate
  • ota doctor
  • ota tasks --use
  • ota tasks --safe --use
  • dry-run task coverage
  • dry-run workflow coverage
  • native execution on the selected unit-project slice
  • container planning and execution for the same declared task surfaces
  • matrix coverage across Ubuntu, macOS, and Windows for the contract branch at that time

That matters more than pretending the branch should already prove every broader OrchardCore lane.

The linked pressure branch is now pinned to released Ota v1.6.23 for stable reference. This green matrix run is the proof artifact for the narrowed slice this note describes.

Why this repo mattered for Ota

OrchardCore helped confirm that Ota's current .NET surfaces are no longer theoretical.

They are strong enough to model a real ASP.NET Core repo slice with:

  • first-class restore hydration
  • structured finite dotnet commands
  • workflow-owned setup
  • explicit host/container mode truth

without falling back to raw shell or overclaiming repo coverage.

That is the real value of this pressure repo.

It did not need to expose a dramatic bug to matter. It proved that Ota's newer .NET contract story is mature enough to use on a serious repository, provided the contract narrows honestly.