Release 0.2.0-preview.6
Coordinated AppSurface release 0.2.0-preview.6, prepared on 2026-08-11 for maintainer review.
Source of truth
This is the release note for AppSurface 0.2.0-preview.6 after 0.2.0-preview.5. It stays provisional until the next tag is cut.
What is taking shape
The named-canary adoption lab now gives application teams a hands-on Development-only trigger → proof → poll runbook for checking a consumer-defined release workflow before production. It includes deterministic pass, pending, and stale paths; candidate/environment-bound, capped local proof evidence; protected trigger and evaluation routes; safe CLI troubleshooting; and clear boundaries: the example neither proves rollout health nor selects a deployment decision. Its shell verifier keeps credentials out of command-line arguments, and its marker profile matches the protected canary route so accepted evidence remains pollable.
ForgeTrust.AppSurface.Auth.Aspire.Keycloaknow carries the optional login-theme path through an immutable release-evidence tuple: deterministic source and packaged manifests, a build-contract digest, pinned base/final image references, platform, and an optional template-baseline digest stay together. The requiredkeycloak-theme-evidencejob builds the checked-in Linux/amd64 sample image, verifies its labels/subtree, starts a disposable Keycloak realm, reads back the selected theme, and hash-checks its same-origin stylesheet without publishing credentials, realm imports, machine paths, or image layers. See the theme lifecycle guide and upgrade/rollback procedure.The Durable preview now provides a verified per-Flow retention lifecycle for terminal PostgreSQL Flows. An application can assess one bounded source closure, freeze its immutable manifest, write the reproducible
DFA1archive package to its own store, record an opaque receipt, verify live source correspondence, place or release a hold, and perform an idempotent authorized purge. The0007_flow_retention.sqlmigration and four-role recipe keep direct source mutation unavailable to the dedicated retention operator while preserving audit evidence and scope fencing. Archive availability, authorization, encryption, retention policy, and legal adequacy remain application-owned.appsurface durable schemanow provides a source-preview adoption path for PostgreSQL Durable schema status, offline deterministic scripts, compatibility preflight, and explicit migration-owner apply. Online commands read only a named environment variable and render no connection details;applyremains guarded by--apply, the package advisory lock, a bounded deadline, and recovery guidance that never deletes migration history. The local PostgreSQL tutorial demonstrates migration order0001–0007, the reviewed four-role recipe, development-only one-time epoch initialization, explicitAddWorkerHost()composition, bounded Work/Flow/Schedule processing, health/drain, and W3C trace-context evidence. Storage registration remains passive and application startup never applies DDL.appsurface canary pollnow turns one existing protected named-canary evaluation into a read-only, caller-owned deployment proof. It validates an application base URL and environment-only marker/credential sources before dispatch, preserves path bases, disables redirects and hidden client timeouts, parses the preview compatibility core by property name, and givespendingplus recoverable transport failures an explicit bounded polling lifecycle. Safe text and JSON outcomes expose only the canary name, attempts, elapsed time, diagnostic, bounded reason/summary, next action, and documentation URL; raw credentials, markers, headers, URLs, and response bodies never render.passalone exits0; semantic canary failures, protocol failures, transient exhaustion, deadlines, and cancellation use stable nonzero exits. The tool remains a caller rail, not a canary trigger, readiness probe, deployment controller, identity broker, or composite Action.ForgeTrust.AppSurface.Themingnow promotes the validatedAppSurfaceThemePair.Graphite()shared Light/Dark pair, and the explicitForgeTrust.AppSurface.WebRazor adapter renders it with native System/Light/Dark browser output. The Web opt-in can retain a presentation-only Light/Dark choice in browser-local storage while preserving one canonical URL and HTML tree: it has deterministic first paint, nonce/hash CSP support, session-only fallback when storage is blocked, no cookie/account/cache/SEO behavior, and a headless native-radio contract. Docs consumer proof and versioned published trees preserve the Graphite Web root together with the defaultAppSurfaceDarkDocs bridge metadata;GraphiteDarkremains the separate fixed Docs-local compatibility preset. Docs signature colors now consume semantic syntax roles, including a forced-colors readable gradient-title fallback. Protected Markdown downloads remain raw privatetext/markdownattachments. Package discovery, quickstart, diagnostics, Docs migration, test commands, and deliberate non-goals ship with the feature; tenant selection, remote packs, and adoption telemetry remain separate policy work.ForgeTrust.AppSurface.DurableFlow repair now offers an opt-in, evidence-backed operator path for a suspendedASDUR211child effect. An authorized host obtains a current payload-free assessment, submits its matching static repair request, and receives one immutable applied or duplicate receipt after the transaction verifies the descriptor, revisions, typed result identity orproven_not_appliedWork evidence, and scoped ledger. This controlled repair never invokes a Work executor, rewrites arbitrary state, or substitutes forReleaseSuspensionAsync; the Flow protocol defines the exact action matrix and remediation paths.
Included in the next coordinated version
Release and docs surface
- Generated package chooser and readiness guidance now link directly to the canonical GitHub maintainer guides instead of Docs-relative paths that could render as missing routes. The PackageIndex generator validates repository-guide paths with GitHub URI semantics and escapes each URL segment before emitting links, so rooted, drive-qualified, empty, traversal-like, and encoded-separator paths fail clearly during generation.
- The release tool now treats checked-in versioned sidecars as explicitly
prepared, then derives a transienttaggedprojection only after an annotated tag binds the prepared sidecar, manifest, and evidence digests. The newtag-messageandinspectcommands validate the tag object, tagger, base-branch reachability, V1/V2 evidence, package surface, and preparation commit before publishing. Docs publication uses the validated projection only in a disposable checkout and retains its inspect proof; prepared source files never acquire tag or GitHub Release claims. - AppSurface Docs adds an opt-in protected Markdown browser download. Hosts set
AppSurfaceDocs:MarkdownDownload:Enabled=true, provide a host-owned named ASP.NET Core reader policy, and may bound the aggregate exact-source snapshot withMaxSnapshotBytes(default8,388,608, range1..33,554,432). Pages require exact inlinedownload_markdown: true; sidecars, aliases, generated pages, noncanonical routes, and archives do not grant access. Successful canonicalGETresponses are private, no-storetext/markdownattachments containing the original valid UTF-8 bytes;HEADreturns the matching attachment metadata without a body. The feature is disabled by default and is browser-only v1; it adds no API, batch, vendor, or automatic synchronization integration. See the five-minute setup and package reference. appsurface coverage gatenow applies a configurable--tolerancegrace margin to overall and patch thresholds. The default0.5percentage point tolerance reduces rounding-related flakiness,0preserves strict enforcement, effective thresholds never fall below0, invalid values fail before evaluation, and console plus Markdown and JSON reports show the effective thresholds they enforce while retaining configured thresholds for automation.appsurface coverage gatenow supports--patch-line-mode measurable|codecov. The backwards-compatiblemeasurabledefault counts a mapped changed line when it has one or more hits;codecovalso requires complete condition coverage when branch data is present, while continuing to exclude unmapped lines. The repository coverage wrapper usescodecovmode for its patch gate so local checks reproduce Codecov's partial-condition treatment before CI.ForgeTrust.AppSurface.Web.OpenApinow usesMicrosoft.AspNetCore.OpenApi10.0.9 and directly requiresMicrosoft.OpenApiin the range[2.7.5, 3.0.0), keeping .NET 10 consumers on the supported 2.x line above the range affected by GHSA-v5pm-xwqc-g5wc while preserving existing OpenAPI and Scalar APIs and endpoint behavior.appsurface coverage runcan now start long-running non-exclusive test projects earlier with--schedule longest-first. It reuses priortimings.jsondata when available, preserves integration and Playwright projects as exclusive barriers, supports explicit priority projects, fails invalid explicit timing or priority input before tests run, warns and preserves input order for unmeasured projects when inferred prior timings are missing or unusable, and keeps artifact names stable.appsurface coverage runnow supports repeatable--exclude-test-projectsegment globs for solution-discovered tests. Exclusions are normalized and case-insensitive, reject stale or malformed patterns before side effects, remain visible in list and dry-run output, preserve solution compilation, and are proven through the packaged CLI consumer with an excluded failing sentinel project.- The ASP.NET Core DevAuth example now has deterministic, staged startup proof: synchronous build failures stop immediately, child exits and Kestrel readiness are observed separately, a child-owned listening record gates the real-loopback HTTP workflow, and cleanup targets only the recorded child. A child-scoped standard .NET host setting avoids configuration-reload stalls in restricted file-watcher environments without changing normal example or consumer behavior. Focused in-process host coverage complements rather than replaces the real-socket verifier, and failures preserve only bounded, sanitized, allowlisted evidence. This is a contributor-experience correction; it adds no package API, package or production-host runtime behavior, package version, or release implication.
- The coordinated package graph now addresses
GHSA-pgww-w46g-26qg by pinning AppSurface Docs to exact
AngleSharp[1.5.2],HtmlSanitizer[9.1.949-beta], andAngleSharp.Css[1.0.0-beta.216]dependencies. This is a dependency-only upgrade: AppSurface Docs public APIs, registration, configuration, and consumer usage are unchanged. The beta sanitizer/CSS pair is intentional only for preview releases; stable package verification rejects either prerelease dependency until issue #682 selects compatible stable versions. The Docs security boundary remains narrow: sanitization covers rendered package-documentation fragments, not general UGC or host CSP. The RazorWire CLI also carries the coordinated parser upgrade in its proof-only bundled tool graph, but remains excluded withpublish_decision: do_not_publish; see its installation and publication boundary. The sanitizer regression proof passed all four Chromium variants:text/htmlandapplication/xhtml+xml, each exercised throughtitleandstyleRCDATA handling. ForgeTrust.AppSurface.Webnamed canary evaluation is now available in preview: applications register typed, application-owned proof evaluators and explicitly map one fixed protected route family. Completed evaluations add requiredname,ready, andstatusfields plus optional typed evidence, a marker fingerprint, and up to 16 registration-declared bounded details. ExistingAppSurfaceCanaryResult(status)construction remains source-compatible. Consumers must tolerate optional omissions, unknown fields, and property reordering; the contract remains preview until the #625 caller proves polling and operator actions. The canonical guide includes a complete forwarding evaluator, a contrasting migration fixture, copyableSystem.Text.Jsonandjqconsumers, the #623-to-#624 upgrade contract, and separate under-5-minute authenticated-host and under-15-minute cold-path onboarding targets. The package emits fixed completion event62401with typed evaluation and host facts only; marker, reason, summary, correlation, and custom detail values remain response-only. Bounds and declarations constrain shape but do not classify or redact application-authored text. The default adapter still returns200only forpassand503for completed non-pass states; authenticated diagnostic consumers can opt into status-preservingAlwaysOk. Authorization remains host-owned and fail-closed, and triggering, retries, polling, aggregation, health-check adaptation, and/readybehavior remain outside this primitive.ForgeTrust.AppSurface.Webhealth and readiness probes are now opt-in. New hosts avoid ASP.NET Core health-check registration and/healthplus/readyendpoint mapping unlessWebOptions.Health.Enabledis explicitly set totrue; enabled probes also avoid general route-handler binding during startup. Hosts whose deployment or monitoring infrastructure consumes those probes must enable the shared flag; paths, readiness tags, response semantics, validation, and authorization behavior are unchanged.ForgeTrust.RazorWireupgrades its package-owned Turbo UMD payload from 8.0.12 to 8.0.23 while preserving the existingBundled, same-originCustomPath, andHostManagedruntime-source contract. Static CDN and hybrid exports continue to materialize the exact bundled runtime.ForgeTrust.AppSurface.WebandForgeTrust.AppSurface.Web.Pushnow provide privacy-safe, schema-versioned PWA push-readiness posture. Web diagnostics contain either a fixed, redacted VAPID key identifier, SHA-256 public-key fingerprint, and package-route mapping bit, or an explicit unavailable/not-configured state. The optional Push package contributes when validated active VAPID configuration is present and reports route mapping as a separate readiness bit; no private keys, endpoints, subscriptions, payloads, or provider exception text are published.appsurface pwa verifynow preserves its schema-v2 install default while--surface push|allemits schema-v3 server-known readiness evidence. It verifies worker/helper discovery, direct JavaScript responses, headers, and cache behavior, and clearly marks browser, permission, subscription, notification, and delivery observations as not evaluated.appsurface secrets transfernow supports version-2, one-way Google Secret Manager-to-LocalSecrets materialization for an IAM-authorized developer's local integration testing. Each source is a full numeric version resource, plans and receipts remain value-free, existing local values require guarded--replaceplus exact confirmation, and prepared local writes can resume only after an in-memory equality check. The local-testing guide explains prerequisites, recovery, and the explicit runtime posture required for aProduction-named local namespace.ForgeTrust.AppSurface.Webnamed canaries now include a bounded protected aggregate snapshot atGET /_appsurface/canaries. Operators can select registered canaries by exact name or durable tag, receive ordinal partial outcomes under explicit concurrency and deadline caps, and parse a privacy-safe envelope with fixed telemetry. The feature does not add triggers, retries, polling, readiness effects, or authorization-policy ownership; hosts retain those decisions.ForgeTrust.AppSurface.Config.LocalSecretsnow uses an entitlement-free macOSSecItemv2 Keychain namespace for cross-process LocalSecrets parity. Readable retained v1 records surface a terminal migration diagnostic instead of being silently consumed; operators can useappsurface secrets migrateto copy them safely without exposing values. The migration guide covers namespace matching, resumable recovery, canonical-v2 precedence, and the interactive three-key smoke.- The PostgreSQL durable schema adds the Schedule ledger, payload-free dispatch leases, forced-RLS history partitions, and a reviewed role recipe. Operators can use the migration and role setup guidance before enabling the manual processor.
- The PostgreSQL durable source preview now provides explicit worker-host composition. Passive registration resolves the
bounded runtime pump, typed health and drain control, and authorized Work and scope control clients without starting a
worker or applying DDL;
AddWorkerHost()is the separate opt-in for one polling host with metadata-only PostgreSQL wake hints. The host records payload-free worker liveness and drain state through0005_runtime_heartbeat.sql, fails closed on incompatible schema or epoch state, and leaves application authorization, external activation, dashboards, and trace instrumentation outside the package boundary. Follow the worker-host quickstart before enabling it. ForgeTrust.AppSurface.Durablenow preserves bounded W3C causal evidence for PostgreSQL Flows without treating waits or process gaps as live spans. Command acceptance and every committed event, timer, Activity Work, or evaluation transition retain only the validatedtraceparent, optional boundedtracestate, a runtime-generated correlation token, and a fixed cause kind. The next real execution becomes a short-lived Activity linked to that committed cause; baggage, Flow payloads, scopes, caller identities, and raw trace headers are neither persisted nor emitted. Start with the Durable Flow trace-context guide for source registration, tags, diagnostics, migration order, and the under-five-minute local proof. The current TestHost proof verifies crash/restart causality under the explicitly opted-in hosted-runtime boundary.- Coordinated package documentation now follows the release that was current when that documentation tree was published: current docs use the stable
releases/current.mdpointer, while historical trees retain their original versioned release notes. The release tool records and validates that contract through versioned manifest and evidence V2 artifacts, preserving V1 evidence compatibility and rejecting incomplete, conflicting, or unknown package release-link declarations.
Release-note workflow
- Public release-note changes now use independently named append-only entries under
releases/unreleased.entries/. AppSurface Docs and release preparation assemble them at the bottom of their declared section, and preparation archives only the entries it consumed. This avoids silently merging a release reset with concurrent feature notes.
Coverage workflow
appsurface coverage gatenow writes threshold-independentcoverage-patch-targets.jsonandcoverage-patch-targets.mdwhenever a patch source is supplied. Contributors can use the local, untracked queue to find the exact uncovered or partially conditioned changed locations from the normalized Cobertura evidence, distinguish branch-only work from patch-line work, and remove stale targets by running a nonpatch gate.appsurface coverage runnow supports opt-in--require-non-sandbox; the repository coverage wrapper enables it by default, withCOVERAGE_REQUIRE_NON_SANDBOX=falseas the explicit restricted-run escape hatch. The preflight recognizes only explicit sandbox markers, fails withASCOV116before discovery, cleanup, build, or tests, never renders marker values, and deliberately does not classify generic container or CI hosts as sandboxes.
Contributor test feedback
- Contributor test runs now reuse shared package fixtures and construct only the source trees their Docs and package-publication regressions exercise, reducing repeated integration setup without changing the covered behaviors.
Durable package availability
- The next coordinated prerelease publishes
ForgeTrust.AppSurface.Durable,ForgeTrust.AppSurface.Durable.Provider, andForgeTrust.AppSurface.Durable.PostgreSqlas public previews. Start with the package chooser, then follow the PostgreSQL schema and role deployment path before enabling the explicit worker host. The packages retain their preview boundaries: no automatic DDL or worker activation, public endpoints, exactly-once external effects, or production support. The first supported publication and any persisted deployment independently freeze command canonical bytes; after either, a change requires a new fingerprint schema id.
Release-note preparation
- Tagged release notes now remove reset-only template bullets without rewriting identical prose, fenced code examples, or HTML fragments. The package chooser and readiness guidance for the coordinated Theming release now point to the versioned current release note.
Migration watch
Apply
0004_schedule_protocol.sqlwith the migration-owner workflow before constructing Schedule clients or processors. Runtime credentials must remain distinct non-owner, non-BYPASSRLSdispatcher and scoped-runtime roles; useconfigure-postgresql-roles.sqlrather than granting table access directly.Apply
0005_runtime_heartbeat.sqland rerun the role recipe before enablingAddWorkerHost(). Initialize or rotate the active runtime epoch through the migration-owner workflow first; application startup intentionally performs no DDL.Apply
0006_flow_trace_context.sqlonly after0005_runtime_heartbeat.sql, then rerunconfigure-postgresql-roles.sql. The scoped runtime receives the reviewed trace-context relation grants under forced RLS; the payload-free dispatcher receives no access.Apply
0007_flow_retention.sqlonly after0006_flow_trace_context.sql, then rerunconfigure-postgresql-roles.sql. PostgreSQL's trustedpgcryptoextension must be installed in thepublicschema before applying the migration or granted to the migration owner for installation on first use.Schedule history partitions cover the current and following UTC months. Before the boundary is crossed, an operator must run
appsurface_durable.ensure_schedule_history_partitions()as the migration owner; a missing partition fails writes visibly rather than routing data elsewhere.The repository-only
scripts/coverage-solution.shwrapper now has one no-argument run-and-gate path over the publicappsurface coveragecommands. Its former group, filter, build, output, and merge compatibility inputs now fail before work starts with an exit-2 command-specific migration message; select projects, own assembly filters, or merge shards through the package-consumer CLI instead. The legacyForgeTrust.AppSurface.CoverageRunnerimplementation and test project have been removed.Apply
0008_flow_repair.sqlonly after0007_flow_retention.sql, then rerunconfigure-postgresql-roles.sqlbefore enablingIFlowRepairOperatorClient. The scoped runtime receives the reviewed repair-ledger grants under forced RLS; the payload-free dispatcher receives no access. Existing suspensions without V1 descriptor identity remain unsupported; migration0008does not backfill missing evidence.