AppSurface Search
Guide

Portable durable execution

Source of truth

View source Edit this page

Last updated

AppSurface Durable is a source-only public preview of portable durable contracts. It is split by audience:

All three packages are machine-held out of every publish plan pending coordinated release evidence. They can be built and packed directly for contract verification, but they are not a supported NuGet release.

For the internal W3C causal-link contract, safe telemetry attributes, deployment order, and reference proof, read Durable Flow trace context v1. It supplies persistence and crash-proof seams now; it does not make Slice 4 a hosted runtime.

Why this boundary

Reusable modules should describe durable intent without selecting storage or starting workers. Runtime providers need public, testable contracts without friend access to the application package. The dependency therefore points one way:

ForgeTrust.AppSurface.Durable.PostgreSqlForgeTrust.AppSurface.Durable.ProviderForgeTrust.AppSurface.Durable

The application package registers only passive registries. A provider is selected explicitly by the host. The PostgreSQL source preview adds explicit migrations (0001_work_shared, 0002_forced_rls, 0003_flow_protocol, 0004_schedule_protocol, 0005_runtime_heartbeat, 0006_flow_trace_context, and 0007_flow_retention) plus one-operation-at-a-time Work, Flow, and Work-first Schedule persistence with versioned W3C causal evidence. PostgreSQL registration remains passive; an application explicitly adds one bounded polling host through AddWorkerHost() only where it intends continuous activation. It adds no public endpoint, dashboard, or automatic migration.

Slice 7 discovery and reconciliation

Slice 7 is still a source-only public preview. Publication of the Durable packages remains held pending coordinated release evidence; the documentation below describes the intended discovery and reconciliation contract, not a shipped NuGet release or a replacement for deployment review.

Storage registration is passive. The PostgreSQL provider opens no worker and installs no hosted service until the host explicitly calls AddWorkerHost(). Startup validates the stored schema version and active runtime epoch, fails closed on incompatibility, and never applies DDL or silently advances schema history.

The forward-only deployment order is:

  1. 0001_work_shared.sql
  2. 0002_forced_rls.sql
  3. 0003_flow_protocol.sql
  4. 0004_schedule_protocol.sql
  5. 0005_runtime_heartbeat.sql
  6. 0006_flow_trace_context.sql
  7. Durable/configure-postgresql-roles.sql

The preferred production flow is to generate and review the Durable schema script offline, apply the reviewed migrations in the order above, apply the canonical role recipe, and run schema status/preflight before enabling the worker host. The durable schema CLI commands make those checks discoverable. apply --apply is an explicit migration-owner operation only; deployments normally pass --connection-env APPSURFACE_DURABLE_MIGRATION_CONNECTION, and it is never a startup side effect. Offline and online commands accept no connection-string argument and never print connection strings.

For recovery, inspect status first, produce a corrected and reviewed forward-only script, then retry the intended operation. Never delete or rewrite migration history. The durable-postgresql example is a local proof of the boundaries above, not production operations guidance.

Scale and transport boundary

PostgreSQL is the first planned authoritative provider, not the definition of AppSurface Durable. The adopter contracts describe accepted Work, Flow, Schedule, payload, and external-effect semantics without selecting a database, polling loop, queue, or broker. The Provider SPI likewise describes bounded activation and fenced execution without exposing a broker acknowledgement as durable truth.

A deployment may evolve in two distinct ways:

  • a wake-only broker or notification may activate IDurableRuntimePump; the authoritative provider still discovers, claims, fences, and completes eligible work, and a periodic pass remains the recovery path for lost notifications;
  • a future broker-backed provider may implement the Provider SPI directly when it can preserve the same acceptance, revision, execution-identity, provider-effect, schedule, and recovery contracts.

Slice 2 intentionally does not define a targeted broker-dispatch token or general event-bus API. Those shapes require a concrete broker and deployment need. Queue delivery alone must never authorize execution, prove completion, or replace the provider's authoritative history.

The preview persists explicit Work and Flow decisions rather than arbitrary async stack state. It also makes no exactly-once claim for external effects. Provider safety, immutable execution identity, revision fences, and versioned command fingerprints make ambiguity observable and fail closed.

Operational failures use the shared ASDURxxx diagnostics catalog, including the fixed hosted-runtime liveness and worker-generation codes.

For the PostgreSQL boundary, start with the slice 3 reference workload, slice 4 reference workload, Schedule protocol v1, and Durable Flow trace context v1, then use the normative Work protocol v1 and Flow protocol v1. The slice 3 reconstruction ledger and slice 4 reconstruction ledger account for every artifact in the superseded branches.

Terminal Flow evidence now has a verified retention lifecycle: a bounded per-Flow assessment, immutable manifest, reproducible archive package, receipt/source correspondence proof, optional hold, and separately authorized idempotent purge. It is intentionally not an age-based deletion feature. The application owns authorization, archive transport, encryption, availability, policy duration, and compliance.

The slice 2 API budget records which original public contracts were retained, moved, added, internalized, or removed. The package test projects enforce the corresponding member-level API snapshots.