Release 0.2.0-preview.10
Coordinated AppSurface release 0.2.0-preview.10, prepared on 2026-09-28 for maintainer review.
Source of truth
AppSurface 0.2.0-preview.10 is a coordinated prerelease for hosts using Config, Durable, Docs, and the AppSurface CLI. It brings consistent configuration keys and file-declared secrets, typed Durable Work and test helpers, richer documentation, and more actionable coverage diagnostics. Follow the upgrade steps below before moving an existing preview installation.
Preview.9 was tagged but its protected workflow stopped before any package was packed or pushed. Preview.10 carries forward that unpublished candidate plus the release retry repair; install matching preview.10 packages.
Upgrade first
- Configuration providers: The logical-key and provider contract changes are a coordinated source and binary break. Upgrade Config packages together, rebuild external providers, and follow the configuration-key migration guide before deploying. File-declared secret references are opt-in and have a separate root migration procedure.
- Durable PostgreSQL: Apply the forward-only schema migrations through
0011in order, then reconcile the complete role-pair manifest and run structural preflight before reactivating workers. The operational assessment rollout and heartbeat retention guide explain compatibility, rollback, and maintenance boundaries. - Coverage automation: The
coverage runwatchdog now defaults tofail. Review long-running tests and the migration choices before adopting the new default in CI.
Start here
- Choose a package for new installations or matching-version upgrades.
- Migrate configuration keys and adopt typed Work definitions when those contracts affect your host.
- Review the pre-1.0 upgrade policy before moving an existing preview installation.
Opt-in capability
- Add opt-in, static Python docstring harvesting for mixed .NET/Python repositories, with bounded parser-package inspection evidence that never executes third-party package code.
Included in this prerelease
Rich Markdown authoring for Docs
ForgeTrust.AppSurface.Docsnow renders bounded Markdown callouts and contextual two-to-four-path tabs without requiring raw HTML or a client-only component. Pages keep a complete source-ordered baseline for static export and no-JavaScript readers; the optional accessible tabs enhancement preserves fragments, browser history, and Turbo-frame navigation. Invalid directives remain visible as literal source and appear in harvest health with stable remediation diagnostics, so documentation repositories can adopt the feature incrementally.
Coverage evidence execution
appsurface coverage runandappsurface coverage gatenow share one private execution engine with the built-inevidence runcoverage producer. Coverage policies therefore evaluate the same collection, merge, gate, patch-target, artifact, and watchdog behavior regardless of which supported workflow invokes it; the private support package is not a new consumer dependency or installation choice.- When an evidence policy supplies
--diff-file, planning captures a bounded immutable snapshot before execution starts. Replacing that file later in the run cannot change the patch coverage input that the resolved policy evaluates.
Ordered local Keycloak seeds
ForgeTrust.AppSurface.Auth.Aspire.Keycloaknow exposes an AppHost-only, strictly orderedRealmReady()andWithLocalSeed(...)lifecycle for finite consumer-owned local projects. It keeps Keycloak Admin API clients, credentials, retries, mutation policy, and idempotent application state in the consumer worker while AppSurface supplies only the baseline proof, dependency graph, typed secret-reference validation, and redacted diagnostics.- Start with the two-worker Keycloak AppHost sample. It demonstrates a persistent, rerun-safe broker/identity/fixture convergence chain and distinguishes startup-time local seeding from request-time DevAuth personas.
Tailwind host CLI cache
- ForgeTrust.AppSurface.Web.Tailwind now resolves its standalone CLI from a verified cache for the machine running the build, so normal consumers no longer restore a native runtime companion into application output. Direct runtime packages remain available for explicit compatibility workflows.
- Build automation that previously matched the missing-runtime
ASTW004diagnostic must handle the classifiedASTW012acquisition diagnostic instead; use the Tailwind diagnostic guide to distinguish cache, manifest, checksum, and offline recovery actions.
C# API semantic rendering
- AppSurface Docs now renders built-in C# namespace API pages from an internal semantic tree and constrained Razor partials, preserving the single shell heading, stable API anchors, source links, disclosures, and encoded XML documentation values. Consumer host setup, routing, and custom
IDocHarvestermigration are not required. Maintainers can follow the C# API rendering architecture and testing guide for the compatibility boundary, diagnostics, and focused verification commands.
Typed Durable Work exits
ForgeTrust.AppSurface.Durablenow letsProviderKeyedWork opt into a closed executor result: success, a proven pre-effect retry, terminal application failure, or an explicitly ambiguous external outcome. ExistingIDurableWorkerExecutor<TWork, TResult>registrations remain unchanged; the PostgreSQL provider keeps effect permits, retry timing, cancellation, and fencing authoritative rather than exposing a direct state mutation or retry hook.- Register the exit-aware contract as a new immutable Work version only after every worker that can discover it runs exit-capable Provider/PostgreSQL binaries. Follow the package guide's fleet-complete rollout and rollback boundary; a legacy provider fails conservatively instead of treating a non-success exit as a successful completion.
Durable operational assessments and admission certainty
ForgeTrust.AppSurface.Durable.ProvideraddsDurableRuntimeHealthState.Unavailable = 5, the computedWasStoreObserved,CanEnableActivation,CanAttemptPump, andIsReadypredicates, plusIDurableRuntimePumpAdmissionand its closed four-kind attempt result. Update exhaustive enum switches and allow serialized health-state consumers to receive value5; do not infer store observation fromObservedAtUtc.- External activators should call
TryRunOnceAsyncdirectly and handleCompleted,Refused,Unavailable, andIncompatible.Completedalways carries a result, including a zero-valued empty pass. Returned non-completed outcomes certify only that this invocation did not enter application execution; caller cancellation, execution failures, malformed provider state, and finalization failures still propagate. - The PostgreSQL rollout adds
0010_runtime_health_observation.sql. Apply migration 10 with the migration owner, rerun the canonical PostgreSQL role recipe, run status/preflight, and smoke-test the supportedv0.2.0-preview.8rollback binary before deploying the new runtime. Binary rollback keeps schema 10 in place; schema defects require a corrective forward migration. - Caller cancellation that arrives after application execution returns no longer cancels successful-sweep bookkeeping. The provider uses a fresh bounded finalization reserve, and any finalization failure propagates because execution may already have begun. Hosted shutdown budgets must include two reserves: one for finalization and one for best-effort failed-pass cleanup.
- See Adopt Durable operational assessments for complete existing-host and custom-composition examples, diagnostics/remedies, cancellation semantics, rollout, rollback, and the one-command local proof.
Typed Durable Work definitions
- Add immutable typed Durable Work definitions with ordinary, reconciled and exit-aware bindings. Define contract facts once, then create requests with explicit caller identities, retry overrides and due times. Guarded codec metadata and registry/Flow compatibility preserve existing request fingerprints and legacy registration APIs. See the migration guide and #800.
One logical configuration-key contract
- Config now uses immutable, case-insensitive colon paths across file, environment, LocalSecrets, and Google Secret Manager. Source spelling and exact native identifiers remain distinct from logical identity. Same-layer duplicates, aliases, and case-only spelling changes across ordered layers fail closed; exact overrides retain provenance.
- The provider SPI, environment snapshot,
wrapper initialization, and typed audit surfaces are a coordinated pre-1.0 source
and binary break. Upgrade all packages and rebuild external providers together.
Applications retain
IConfigManager.GetValue<T>; no V2 adapter is introduced. Config.Testing ships the framework-neutral provider conformance harness in the same release. - Follow the three-train migration guide. Train 1 automatically translates dot-only application strings with diagnostics. LocalSecrets moves use an exclusive maintenance lease and durable roll-forward journal. Google legacy convention IDs require inventory-generated explicit mappings; runtime lookup does not probe historical generated IDs.
- The no-credential source proof, clean packed consumer, previous/candidate package fixtures, and coverage gates verify adoption. No source or migration output displays configuration values.
File declared scalar secret references
Configuration models can use Secret<T> to declare a sensitive scalar destination. Its checked-in JSON descriptor
selects a resource, version, provider, and static activation state while keeping the payload outside the file. Start with
the reference guide and
network-free executable example.
The Google provider resolves enabled references; LocalSecrets can supply a sensitive whole-root base. Disabled references still validate locally. Exact environment values can supply or rescue a destination, and a valid direct environment root bypasses file and provider resolution. Effective audit performs the same reads as runtime and shows only opaque activation, availability, and source state.
This behavior is an explicit opt-in. Existing models keep their legacy resolution path. File loading now rejects duplicate JSON members, including case-only duplicates, and skips those invalid files with a safe diagnostic for legacy roots. Third-party base providers for opted-in roots must expose raw composition support or prove that they do not claim the root. Migrate a whole root and remove overlapping code mappings in the same change; descriptor layers replace one another atomically. See the migration and rollback guidance.
Stable publication remains gated on the separately scoped real Skoolit root migration, measured glue deletion, Google verification without environment rescue, and previous-artifact rollback rehearsal. The deterministic repository and packed-consumer proofs support this pull request; they do not replace that adopter rehearsal.
Tailwind release artifact provenance
- Release automation now packs
ForgeTrust.AppSurface.Web.Tailwindonce and passes the immutable package artifact to every native host. Each host checks the restored archive and extracted build payload against the producer's package and release manifest before it reports success. - Stable and prerelease publishing require one complete five-host evidence set for that same artifact, plus a frozen publication-start receipt. A failed or incomplete host proof blocks publication; retry the full native invocation or resume the original candidate as described in the release operations guide.
- The PackageIndex maintainer tool provides typed consumer and evidence verification commands. Local proof output is useful for development but does not authorize a release.
Coverage hang diagnostics
appsurface coverage runforwards each--test-argumentas one literal VSTest token, including tokens that begin with-. In fail mode, the supported collector and MSBuild drivers request a bounded, no-dump VSTest hang sequence and report scoped, safe “last started test” observations intimings.jsonand the terminal summary. The first-party Evidence coverage producer uses the same private policy within its producer deadline. See the #815 diagnostic and migration note for timing, artifact, and manual-override details.
Shared-store Durable PostgreSQL role pairs
- The PostgreSQL role recipe now reconciles a complete version-1
role_pairs_jsonmanifest, preserving existing pairs and refusing omitted roles. Keep migrations ahead of reconciliation and rerun the recipe with the same complete manifest after schema upgrades. The local integration example proves the forwardingfullpair remains operational after adding awork_onlydispatcher, which has no direct Durable table access. - Separate credentials establish a deployed-lane boundary; they do not provide PostgreSQL row isolation. Work discovery selectors and transaction-local scope values retain their existing semantics. See the #823 approved design and implementation plan for the manifest recipe and rollout proof.
Durable testing package
- Add the public-preview
ForgeTrust.AppSurface.Durable.Testingpackage for deterministic Durable test builders, provider fakes, host admission scenarios, and typed Work observations. Install it alongside matching Durable and Provider package versions. - The adoption guide covers the six-state health matrix, packed xUnit quick start, timeout and invocation-handle semantics, and history privacy and retention guidance.
Bounded PostgreSQL runtime heartbeat retention
ForgeTrust.AppSurface.Durable.PostgreSqlnow prunes stale runtime heartbeat identities after an admitted pass. The default diagnostic window is 24 hours; maintenance is asynchronous, deletes at most 500 rows per call, and does not make Work readiness depend on cleanup.- Schema 11 adds an age-ordered index and a bounded deletion function. Apply the forward-only migration during a maintenance window, reapply the exact role recipe, and run structural preflight before reactivating workers. Follow the heartbeat retention operations guide for rollout order, catch-up limits, protected rows, the exact prior-binary proof, and recovery constraints.
Google Secret Manager uncached reads
- Google Secret Manager configuration now starts a fresh client read after a previous uncached lookup completes. Hosts using
CacheTtl = nullcan observe the next secret version on the next sequential lookup; overlapping lookups may still share one in-flight request.
Typed Work migration guide link
- The typed Work migration guide remains reachable from the plan completion audit after the preview release archives its unreleased source entry.
Prerelease publication retries
- A protected prerelease publish can retry after required source checks skip its producer and publisher before either job starts. The retry still requires tag-bound artifact provenance before packages are published; package APIs are unchanged.
Migration guidance
Coverage watchdog default
- The
coverage runwatchdog now defaults tofailwith the existing 10-minute no-progress limit. Fail mode may end a healthy individual test that exceeds its computed VSTest hang timeout. Increase--no-progress-timeoutto give that test headroom, or explicitly select--watchdog warnoroffto disable automatic hang blame. An Evidence coverage declaration can increaseTimeoutSecondsonly when the remaining producer deadline shortens the automatic timer; Evidence's fixed watchdog caps that timer at 9 minutes and its producer deadline remains authoritative. The #815 migration guide gives the choices and outcome codes.