Release 0.1.0
Coordinated AppSurface release 0.1.0, tagged on 2026-06-27.
Source of truth
This is the release note for AppSurface 0.1.0 after 0.1.0-rc.4. This page is finalized on 2026-06-27.
From scattered startup paths we came, To AppSurface, clear by name. Packages first, with proof in hand, The smallest path through Surface land.
Browsers bloom while APIs stay clean, Secrets stay dark, diagnostics seen. Flows trace forward, contracts align, Docs and releases leave proof behind.
No mystery hop, no hidden gate, Ready, or flagged, for teams to evaluate. From dotnet new web to trust made clear, v0.1.0 has surfaced here.
Why this release matters
AppSurface 0.1.0 is the first release where AppSurface becomes more than a repository of useful pieces. It becomes a product surface: packages, CLI tooling, docs, examples, validation, and release evidence that move together.
Every growing ASP.NET Core team eventually reaches the same point. Program.cs stops being just startup code. It becomes the place where security posture, configuration policy, browser and API behavior, local development setup, docs, and release proof quietly accumulate. ASP.NET Core gives teams the primitives. AppSurface 0.1.0 gives teams a way to name those concerns, test them, document them, package them, and reuse them across services.
That is the story of 0.1.0: application infrastructure decisions can become product-grade contracts.
This release does not ask teams to stop using ASP.NET Core. It starts from plain ASP.NET Core and adds structure only where structure helps. When a startup concern is local and obvious, keep it local. When a concern has a name your team uses in conversation, when it has sharp edges, when it must behave the same way across services, or when it deserves its own docs and tests, AppSurface gives it a surface.
The first adoption path is intentionally small. Create a fresh ASP.NET Core app, install ForgeTrust.AppSurface.Web, start through WebApp<TModule>, map one endpoint, and prove that the package-consumer path works without cloning the repository. From there, adoption can stay incremental. Teams can add web behavior, auth boundaries, flow contracts, local secret posture, docs, coverage gates, RazorWire UI behavior, or release tooling only when those surfaces match the app they are building.
The clearest proof is not a smaller Program.cs. The clearest proof is a policy that becomes named, tested, and reusable. Browser status pages and production exception pages show the shape of that idea: browser requests get recovery-oriented HTML, API requests stay API-friendly, production 500 pages avoid leaking sensitive details, and the behavior can be verified through package tests and local proofs instead of copied from service to service.
Four release candidates tightened that surface before v0.1.0; their old note routes now redirect here, while the final release narrative keeps the focus on what shipped.
The final stable branch adds the release proof needed to make that story safe to publish. Stable package release automation now has a protected NuGet publish gate for annotated vX.Y.Z tags, stable-only package-version validation, trusted-publishing environment checks, fresh smoke-install proof, publish-ledger evidence, and ./eng/release publish --base-ref support so GitHub Release creation can be tied to the intended release branch after NuGet proof is complete.
The result is a release built for inspection. First-time adopters get a package chooser, first success path, and proof examples. Application teams get safer, reusable conventions for startup behavior and app-facing infrastructure. Platform teams get installable standards instead of copied setup blocks. Maintainers get release evidence, package readiness, coverage output, stable publish gates, and a docs surface that moves with the packages.
AppSurface 0.1.0 is our first stake in the ground: app infrastructure should be visible, named, tested, documented, and safe to adopt. The future is surface.
Highlights
- A coordinated .NET 10 package family with package chooser guidance, package readiness evidence, release notes, and release metadata tied to the same repository state.
- A first success path from
dotnet new webto a package-consumer AppSurface Web endpoint. - Named web behavior for browser status pages, production exception pages, endpoint-aware middleware, OpenAPI and Scalar exposure gates, CORS safety, and static export expectations.
- Auth and Flow foundations that give module authors host-neutral contracts without taking ownership of identity providers, stores, Durable Task hosting, or app infrastructure.
- Configuration, LocalSecrets, Caching, Autofac, Aspire, Console, and Intelligence packages that turn common app-side infrastructure concerns into documented, testable package surfaces.
- RazorWire and AppSurface Docs improvements for streams, export, page navigation, section copy, form interactions, search, provenance, archive integrity, and release publishing.
- Release evidence, coverage commands, package verification, stable NuGet gates, and docs QA treated as product behavior rather than private maintainer ceremony.
What we built
A coordinated package family
AppSurface v0.1 now presents itself as a coordinated .NET 10 package family. The package chooser gives first-time adopters an install map instead of asking them to infer package order from repository structure.
The release covers public packages for AppSurface Core, Config, Config.LocalSecrets, Caching, Auth, Auth.AspNetCore, Intelligence, Flow, Flow.DurableTask, Console, Dependency.Autofac, Aspire, Web, Web.OpenApi, Web.Scalar, Web.Tailwind, RazorWire, and the AppSurface CLI. Support and proof-host packages remain documented where they help validate the public install path.
A first success path
The first proof is deliberately small: install ForgeTrust.AppSurface.Web, start with WebApp<TModule>, map an endpoint, and verify the response.
That path matters because it tests AppSurface as a package consumer would use it. A team can evaluate AppSurface from a fresh ASP.NET Core app before deciding whether Auth, Flow, RazorWire, LocalSecrets, AppSurface Docs, or release tooling belongs in the same application.
Named web behavior
The Web surface turns startup policy into behavior contracts:
- Conventional browser
401,403, and404pages for empty HTML responses. - Opt-in production
500pages with safe copy and request id evidence. - Endpoint-aware middleware composition for root or host integration modules.
- Development-friendly OpenAPI and Scalar defaults with explicit non-development exposure gates.
- AppSurface-managed production CORS validation that rejects the exact literal wildcard origin
*outside Development. - Export-aware error-page behavior so static sites can carry useful browser recovery paths without changing API responses.
Auth boundaries
Auth starts as a passive vocabulary package. It gives module authors user, session, context, result, prompt, audit, and metadata contracts without owning schemes, cookies, redirects, ASP.NET Identity, OIDC providers, user stores, or policy definitions.
ForgeTrust.AppSurface.Auth.AspNetCore maps host-owned ASP.NET Core authentication and named policies into AppSurface-shaped request context and result values. The adapter keeps middleware, schemes, policy definitions, challenges, forbids, redirects, audit sinks, and UI with the host.
Flow foundations
Flow gives teams typed process contracts before they commit to durable infrastructure. ForgeTrust.AppSurface.Flow includes typed input/output ports, generated-case authoring, graph validation, discriminated outcomes, a definition registry, in-memory execution, benchmark coverage, and lower-overhead execution metadata.
ForgeTrust.AppSurface.Flow.DurableTask adds the passive Durable Task boundary: runner and client services, resume-event authorization, timeout handling, late-event and retry behavior, and context serialization validation. Durable worker hosting, storage providers, ASP.NET endpoints, and UI remain host-owned.
Configuration and local-secret posture
Config covers typed wrappers, DataAnnotations validation, source-aware audit reports, discovered-key evidence, redaction, safe collection traversal, and explicit configuration access patterns.
LocalSecrets adds OS-backed local development secret posture before a remote vault exists. It includes CLI commands for init, set, get, list, delete, and doctor; trusted Linux secret-tool resolution; fail-closed provider-chain behavior; and Unix file fallback hardening for deterministic examples and tests.
Console, dependency, Aspire, and product intelligence
Console gives CLI apps and worker-style entry points the same AppSurface startup pipeline used by the rest of the package family.
Dependency.Autofac gives Autofac-specific registrations and module hooks without making Autofac the default container.
Aspire gives .NET Aspire app-model projects AppSurface-style modular composition for service defaults and distributed resources.
ForgeTrust.AppSurface.Intelligence gives packages and hosts a reusable product-intelligence contract layer. Hosts can register event contracts, validate safe property shapes, compose package event catalogs, and choose their own sink without pulling analytics vendor SDKs into AppSurface packages.
RazorWire and AppSurface Docs
RazorWire now has stronger server-rendered UI mechanics: safe text stream helpers, result-bearing stream authorization, SSE admission limits, hybrid islands, page navigation, section copy, failed-form UX, and stable local form interactions for conditional targets and one-dimensional ASP.NET Core model-bound collections.
Static and hybrid export now has clearer boundaries. Artifact-producing redirects are checked before response bodies are read or written. Generated artifacts and release archive traversal reject symlinks, junctions, reparse points, and lexical output-root escapes. Anti-forgery forms, static assets, 404.html, publish-root extras, and docs archive routes all have explicit diagnostics.
AppSurface Docs grew into a product proof surface: release hub, package chooser, reader-intent search, source provenance, exact release archive integrity, catalog-pinned manifests, section copy, page navigation, canonical routes, versioned archives, search quality signals, and a trusted maintainer harvest rebuild loop.
CLI, coverage, and release evidence
The AppSurface CLI now carries docs preview/export, coverage run/merge/gate, LocalSecrets, release support, and package validation proof.
Coverage tooling moved from ad hoc CI glue into package-consumer commands. appsurface coverage run orchestrates private .NET test projects and managed JUnit diagnostics. appsurface coverage merge supports matrix fan-in and custom producers. appsurface coverage gate enforces Cobertura thresholds and patch coverage with explicit diff provenance.
Release prep now produces reviewable release notes, sidecars, manifests, evidence bundles, changelog rollover, package release-note path updates, and readiness reports. Stable v0.1.0 publishing is deliberately blocked until protected NuGet stable publish and smoke-install proof exists, so the stable release cannot become a GitHub-only artifact.
What it means
For application teams
Important setup policy no longer has to live as repeated local convention. If a behavior matters enough to name, AppSurface lets the team make it testable, documented, and reusable.
For platform teams
Service standards can become installable package behavior. Instead of copying startup blocks across applications, teams can point service owners at one module contract and one proof path.
For maintainers
The release itself becomes observable. Package readiness, coverage output, release artifacts, docs routes, protected publishing, smoke-install proof, and evidence bundles become reviewable state tied to the repository.
For first-time adopters
The release is evaluable before it is fully adopted. A team can start with one package, prove one endpoint, inspect the chooser, and decide which optional surfaces belong in its app.
How to start
1. Prove the base web path
Create a fresh ASP.NET Core app, install ForgeTrust.AppSurface.Web, start through WebApp<TModule>, map one endpoint, and verify the response.
dotnet new web -n AppSurfaceProbe
cd AppSurfaceProbe
dotnet package add ForgeTrust.AppSurface.Web
Use the first success path when you want the step-by-step walkthrough.
2. Move one policy into a module
Pick a behavior that already matters, such as browser status pages, production exception pages, endpoint-aware middleware, or AppSurface-managed CORS. Give it one named AppSurface contract and verify it through package tests or a local proof.
3. Add optional surfaces only when needed
Use Auth when reusable modules need host-neutral auth results. Use Flow when process behavior needs typed contracts and validation. Use LocalSecrets for local development secret posture. Use RazorWire for server-rendered reactive UI and export behavior. Use AppSurface Docs and CLI tooling when docs, coverage, and release evidence should move with the code.
4. Evaluate readiness through proof
Use the package chooser, first success path, package readiness evidence, release notes, and product-readiness lab to inspect adoption risk before standardizing AppSurface across more services.
Release-candidate history
The old RC note routes redirect here; future RCs should be stabilization milestones, not separate narrative releases.
0.1.0-rc.1- 2026-05-290.1.0-rc.2- 2026-06-030.1.0-rc.3- 2026-06-080.1.0-rc.4- 2026-06-16
Migration guidance
- Web apps that intentionally expose AppSurface-owned OpenAPI or Scalar outside Development should set
AppSurfaceWebOpenApi:ExposeEndpoint=Alwaysand, when using Scalar,AppSurfaceWebScalar:ExposeEndpoint=Always. - Web apps using custom conventional
404views should move fromForgeTrust.AppSurface.Web.NotFoundPageModeltoForgeTrust.AppSurface.Web.BrowserStatusPageModel. - Middleware that needs selected endpoint metadata, including global authentication or authorization middleware, should move from
ConfigureWebApplicationto the root or host integration module'sConfigureEndpointAwareMiddlewarehook. - Production AppSurface-managed CORS no longer accepts
AllowedOrigins = ["*"]. Use explicit origins, keep permissive all-origin behavior behindEnableAllOriginsInDevelopment, or register host-owned ASP.NET Core CORS for intentionally public wildcard APIs. - RazorWire stream markup callers should keep text updates on
Append,Prepend,Replace, andUpdate, and move trusted server-authored markup toAppendHtml,PrependHtml,ReplaceHtml, orUpdateHtml. - RazorWire stream endpoints now apply admission limits and authorization outcomes before SSE starts. Public or demo streams should configure the intended stream authorization mode explicitly.
- RazorWire hybrid islands no longer import
data:text/javascript,...or protocol-relative//...module specifiers. Serve modules from relative, root-relative, same-origin, explicit HTTPS, or import-map specifiers. - RazorWire and AppSurface exports now fail artifact-producing cross-boundary redirects with
RWEXPORT008. Model cross-origin targets as external references instead of exporter-managed artifacts. - RazorWire generated artifacts and AppSurface Docs release archives now reject output-root escapes, symlinks, junctions, and reparse points with
RWEXPORT009. - AppSurface Docs exact release catalog entries should pin the release manifest SHA-256 emitted by export before public archives are mounted.
- AppSurface Config audit output may redact more values than earlier candidates. Treat conservative redaction as the intended default and use explicit sensitivity options for package-owned keys.
- Hosts using AppSurface-managed production CORS should replace the literal wildcard with explicit browser origins or host-owned ASP.NET Core CORS before publishing.
Release proof
- Package chooser: packages/README.md
- Package readiness evidence: packages/readiness.md
- First success path: start-here/first-success-path.md
- Release authoring and stable publish checklist: releases/release-authoring-checklist.md
- Changelog entry: CHANGELOG.md
- The old RC note routes redirect here so the final
v0.1.0note is the singular human release narrative.