AppSurface Search
Release

Release 0.1.0-rc.2

Coordinated AppSurface release 0.1.0-rc.2, tagged on 2026-06-03.

Source of truth

View source Edit this page

Last updated

Status

Tagged

This page is the final narrative release note for AppSurface 0.1.0-rc.2.

Safe To Consume

Scope: Repository-wide. Packages, CLI tooling, examples, and docs-facing behavior ship in one coordinated version.

Freshness: Tagged on 2026-06-03.

Record

The matching compact ledger entry lives in CHANGELOG.md.

  • Release artifacts were generated by ./eng/release prepare.
  • Package release note paths are recorded in packages/package-index.yml.
  • The GitHub Release is created from the annotated tag commit.

This release note records the delta from AppSurface 0.1.0-rc.1 to 0.1.0-rc.2. The broader coordinated prerelease story remains in v0.1.0 RC 1; this page only calls out what changed after that candidate.

What changed since RC 1

RC 2 turns the first release candidate into a more publishable package surface. The main changes are new AppSurface Auth and Flow package families, harder AppSurface Docs archive boundaries, safer RazorWire streams and exports, and release/package documentation that now points at the RC 2 note as the current package-facing record.

Included in RC 2

New package surfaces

  • AppSurface now has ForgeTrust.AppSurface.Auth as a surface-neutral auth vocabulary package for module authors and host integrations. It defines passive user, session, context, result, login/logout prompt, audit-event, and metadata-key contracts while avoiding runtime authentication, authorization policy evaluation, redirects, audit sinks, and identity-provider integration.
  • AppSurface Flow is now a first-class package family. ForgeTrust.AppSurface.Flow provides stable net10.0 typed process contracts, discriminated outcome records, graph validation, a definition registry, and an in-memory runner.
  • ForgeTrust.AppSurface.Flow.DurableTask adds a passive Durable Task adapter boundary with runner/client services, resume-event authorization, timeout handling, late-event and retry behavior, and context serialization validation. Semantic Kernel remains out of v1 scope.
  • The new examples/flow-approval-local sample demonstrates local typed flow execution before a host opts into durable infrastructure.

Release and package operations

  • Public package READMEs and generated package chooser/readiness pages now link to the v0.1.0 RC 2 release note for current release risk, migration guidance, and package readiness.
  • Older v0.1 preview release-note routes now redirect to the RC 2 release note, keeping legacy preview links on the current candidate instead of a stale pre-RC page.
  • Package maintainers now have a generated packages/readiness.md evidence dashboard that groups packages by product family, reports package-index readiness evidence, and keeps blocker/notes annotations separate from live NuGet publish status.
  • The AppSurface CLI now reports package SemVer from appsurface --version, preserving prerelease labels such as 0.1.0-rc.2 while omitting leading v tags and build metadata. Tool smoke validation now installs the package and checks --version exactly against the package manifest.
  • Release preparation now leaves CHANGELOG.md as a compact ledger, moves detailed release narrative into tagged release notes, and makes generated release PR reports stop at a manual maintainer review gate before merge, tag, or publish.
  • The release authoring checklist now records the preview-rollup rule: when a tagged or release-candidate note supersedes a preview, remove the preview source file and carry its browser routes as redirect_aliases on the canonical note.

AppSurface Docs hardening

  • AppSurface Docs exact release trees now carry catalog-pinned archive integrity: export writes .appsurface-docs-release-manifest.json, prints the releaseManifestSha256 catalog snippet, runtime verifies pinned archives before mounting them, and keeps unpinned public archives unavailable until HTML, JavaScript, CSS, SVG, and search payloads are pinned and verified.
  • AppSurface Docs version catalogs now mount exact release trees only from AppSurfaceDocs:Versioning:TrustedReleaseRootPath, which defaults to the catalog directory for colocated catalog.json plus releases/ layouts. Absolute exactTreePath values are no longer mountable; set the trusted release root to the old parent directory and make catalog paths relative.
  • Published AppSurface Docs search indexes now reject unsafe documents[].path values before a release tree is mounted. Absolute URLs, executable schemes, protocol-relative URLs, traversal, encoded separators, request path bases, custom deployment roots, and docs operational routes make only the affected published version unavailable until rebuilt or rewritten.
  • AppSurface Docs published release trees now enforce AppSurfaceDocs:Versioning:MaxRewrittenFileSizeBytes for request-time rewrites of exported .html files and root search-index.json. Oversized search payloads are rejected during catalog validation, while oversized request rewrites fail closed with a controlled 404.
  • Built-in Markdown and C# harvesters now skip file and directory reparse points during direct and aggregated source traversal, and Markdown root LICENSE plus paired sidecar metadata reads use the same no-reparse boundary.
  • JavaScript harvesting now applies the same no-reparse boundary to explicit includes, global include roots, recursive traversal, child files, and child directories. Symlinked include roots emit appsurfacedocs.javascript.reparse_point_skipped with redacted recovery guidance and block strict JavaScript health when JavaScript participates.
  • AppSurface Docs configured branding directories now deny SVG by default because SVG is active document content under the docs origin. Operator-owned SVG logos and favicons can still be served by setting AppSurfaceDocs:Identity:BrandingAssets:AllowSvgAssets=true.
  • AppSurface Docs parser input budgets now bound Markdown, C#, and JavaScript source reads so extremely large authoring files fail as controlled harvest diagnostics instead of consuming unbounded memory.
  • The standalone AppSurface Docs host now owns its docs-specific 404 recovery page, including search links resolved from DocsUrlBuilder.Routes.Search, while embedded docs consumers remain responsible for their own app-wide browser error UX.
  • AppSurface Docs JavaScript API pages can now resolve public doclets into reader-facing API families. Explicit @namespace and @module tags remain authoritative, ordered GroupNameRules can name known source trees, and untagged fallback groups use path-aware identities so same-stem files in different folders do not merge.

RazorWire streams and export

  • RazorWire stream builder text APIs now HTML-encode template content by default. Append, Prepend, Replace, and Update are safe text helpers, while new AppendHtml, PrependHtml, ReplaceHtml, and UpdateHtml methods preserve trusted server-authored markup without encoding or sanitizing.
  • RazorWire stream endpoints now enforce single-process public SSE admission guardrails before allocating hub subscriber state. Channel names are validated before authorization, malformed channels return 400, authorization denials return 403, and live capacity exhaustion returns 429 before SSE headers are written.
  • RazorWire's in-memory stream hub now releases empty live channel tracking after the last subscriber disconnects or publish-time cleanup prunes stale writers. Replay buffers remain separate from live subscriber state and are pruned by retained-channel limits instead of live subscriber disconnects.
  • RazorWire stream admission limits are configurable through RazorWireOptions.Streams.MaxChannelNameLength, MaxLiveChannels, MaxLiveSubscriptions, and MaxLiveSubscriptionsPerChannel. These are per-process limits for live SSE requests, not distributed user, tenant, IP, or cluster quotas.
  • Static and hybrid export now handle RazorWire-owned anti-forgery forms safely: hybrid exports remove crawler-minted tokens and refresh them lazily from /_rw/antiforgery/token, while CDN exports fail early with RWEXPORT006 guidance instead of publishing stale request tokens.
  • RazorWire and AppSurface hybrid export now fail missing browser-delivered static assets with RWEXPORT003 instead of returning success for a folder that would keep serving broken CSS, image, script, stylesheet, module preload, icon, font, or asset-shaped preload/prefetch requests.
  • RazorWire CLI process execution now follows an explicit reliability contract for one-shot commands and launched target apps. Target-app failures that were previously hidden behind startup or readiness timeouts may now surface earlier with captured output and recovery guidance.
  • RazorWire now has first-class page navigation for server-rendered brochure and docs pages. Native anchors opt in with rw-page-nav / rw-page-nav-link / rw-page-nav-toggle / rw-page-nav-panel, while the runtime owns active state, hash navigation, lifecycle-safe rebinding, diagnostics, and optional panel close.

Configuration diagnostics

  • Config audit entries can now be explicitly classified with ConfigAuditEntryOptions.Sensitivity, letting package authors mark domain-specific provider-only or wrapper-discovered keys sensitive without changing key names.
  • Config audit discovered-key reports now expose ConfigAuditDiscoveredValueDisplayState and omit raw scalar values for non-redacted unknown keys or descendants under broad audit registrations. JSON consumers should branch on ValueDisplayState instead of treating DisplayValue == null as complex-only.
  • Config audit redaction now recognizes additional secret-bearing fragments such as passphrase, DSN, assertion, certificate, cookie, client secret, private key, JWT, bearer, access/refresh tokens, session IDs, and shared access signatures.
  • Opted-in configuration audit collection traversal now reports environment-created collection elements when audit provenance can prove the lower-priority element was absent, and reports a separate base-unknown diagnostic when environment variables supplied the final element but provider evidence cannot prove prior presence.

Web and Tailwind polish

  • AppSurface preview startup now treats --port as a loopback-only shortcut that binds http://localhost:<port>. Add --all-hosts with --port only when LAN, container, or other all-interface preview access is intentional.
  • Tailwind build execution now uses a compiled MSBuild task with stable ASTW### diagnostics, structured CLI arguments, bounded output capture, cancellation support, and a packed-package smoke test that proves task/dependency loading from a real nupkg consumer.
  • Tailwind development watch mode now treats a missing standalone CLI as a recoverable local-tooling gap: the app keeps serving existing CSS and logs a warning that points to the runtime package or TailwindOptions.CliPath override.
  • The new examples/web-error-pages proof starts a production-mode AppSurface Web host and verifies the browser/API error-page split with one command, including response-body sentinel checks for the generic 500 page.

Tests and repository policy

  • Test fixture paths now use a shared ForgeTrust.AppSurface.Testing helper with TestPathUtils.PathUnder, RelativePath, and FindRepoRoot, replacing duplicated local helpers in high-risk test path construction.
  • A repository policy test now scans test sources for dynamic Path.Combine and Path.Join under-base fixture paths, reports maintainer-friendly replacement guidance, and keeps intentional platform-path behavior behind reasoned allowlist entries.
  • Static website export docs now spell out the deployment extras boundary: --seeds are crawl routes rather than local copy paths, AppSurface's conventional /_appsurface/errors/404 output can stage root 404.html, deployment-owned files such as CNAME belong in explicit post-export copy steps, and exporter-owned Netlify _redirects should still come from --redirects netlify.

Dependency maintenance

  • The central .NET dependency set now carries Microsoft.Extensions.Caching.Memory, Microsoft.Extensions.Hosting, and Microsoft.Extensions.Logging.Console 10.0.8, while the ABP benchmark host now uses ABP 10.4.0; solution lock files were regenerated so locked restore sees the same graph in CI and local development.

Migration watch

  • The stable pre-1.0 contract lives in Pre-1.0 upgrade policy.
  • RazorWire stream markup callers should audit .Append(, .Prepend(, .Replace(, .Update(, new RazorWireStreamResult(, and PublishAsync(..., string). Keep text/status/counter updates on the existing methods, move Razor markup to partial or component helpers when practical, and use AppendHtml/PrependHtml/ReplaceHtml/UpdateHtml only for trusted fragments with user values encoded before composition.
  • RazorWire stream consumers do not need application code changes for the live-channel cleanup update. Public or demo stream endpoints may now see 429 Too Many Requests under high live-connection fanout because RazorWire admits only a bounded number of live channels and live SSE requests per process.
  • Existing RazorWire CLI users do not need command or flag changes for the process-execution migration. The main behavior difference is that target-app failures may now appear earlier with captured output instead of being hidden behind startup or readiness timeouts.
  • AppSurface Docs version-catalog maintainers should copy the releaseManifestSha256 value printed by export into each public exact release entry. Existing unpinned public archives are unavailable until the release manifest is pinned and verified.
  • Operators may see more conservative redaction in config audit reports as the secret-fragment list expands. Treat that as the intended default, and use explicit sensitivity options only to document package-owned keys.
  • AppSurface preview users who depended on --port listening beyond loopback should add --all-hosts or pass explicit --urls. The wildcard host can expose the preview process beyond the local machine, so keep the default localhost binding for routine docs and web previews.
  • Tailwind package consumers do not need source changes for the compiled MSBuild task. Maintainers should keep the packed-package smoke path green when changing task dependencies or diagnostics.