Skip to content

release: durable Sessions, unified Automations, and trustworthy Runs#982

Merged
dennisonbertram merged 180 commits into
mainfrom
develop
Jul 12, 2026
Merged

release: durable Sessions, unified Automations, and trustworthy Runs#982
dennisonbertram merged 180 commits into
mainfrom
develop

Conversation

@dennisonbertram

@dennisonbertram dennisonbertram commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Why

Promotes the completed product-reset epic #931 from develop to production.

The protected product is now intentionally smaller and more coherent:

  1. durable interactive Sessions;
  2. one Automations product for single-step background work and multi-step loops;
  3. one source-qualified Runs product for honest status, evidence, and recovery;
  4. Repositories as context; and
  5. focused Settings.

This release also completes the runtime-snapshot epic #944: queued unattended work executes immutable versioned intent while current security policy can only revoke or narrow it. Background persistent workspaces and loop disposable-step workspaces remain source-correct.

What changed

Trust and contracts

Unified product

Trustworthy unattended execution

Storage decision

Out of scope

  • No deletion of legacy routes, tables, APIs, definitions, Runs, or evidence.
  • No big-bang executor/workspace convergence.
  • No general GitHub PR/issue/Actions administration replacement.
  • No claim that authenticated production automation journeys are configured or passed.
  • Dev backing-service isolation is not fixed here; ops: isolate dev Postgres and Redis from production #981 tracks the confirmed operator configuration defect.

Database and migration impact

Three ordered migrations are included and were audited against origin/main:

  • 0085_familiar_chronomancer.sql: makes agent_loop_runs.loop_id nullable and changes the source FK to ON DELETE SET NULL, preserving Run history. This constraint replacement is acknowledged by the migration-safety gate. After retained null-source rows exist, schema rollback is fix-forward, not a reverse migration.
  • 0086_clammy_greymalkin.sql: additively adds nullable V1 execution-snapshot/version/hash columns and an all-or-none validation constraint to background_agent_runs.
  • 0087_useful_shen.sql: adds the equivalent compatible snapshot tuple/constraint to agent_loop_runs.

The journal indices/tags and snapshot chain are sequential through 0087. The snapshot migrations are legacy-compatible; old rows remain nullable and use bounded, observable fallback. App rollback can keep the forward-compatible columns. Do not drop snapshot evidence during rollback.

Important environment finding: safe fingerprint audit proved dev currently shares production Postgres and Redis/KV. No destructive dev journey was run. This is tracked in #981. The migrations have already been exercised by isolated per-PR Vercel Preview builds and their Preview Smoke/API Contract gates.

How it was verified

Release head on develop: 044a49d1c59cd8f36fea5ecd3acf886853d77489.

Ancestry sync PR #983 merged prior main release history back into develop without changing the file tree; all required gates, Vercel dev deployment, Preview Smoke, and API Contract Tests reran on the synced head.

Deterministic/local gates on the final feature head and cumulative release diff:

  • bun --bun run ci — all 882 isolated test files passed; formatting, lint, typecheck, and migration sync passed.
  • bun run --cwd apps/web build:ci — production build passed; 109 static pages generated.
  • BASE_REF=origin/main bun run check:migration-safety — three migrations checked; destructive constraint change explicitly acknowledged.
  • bun run --cwd apps/web db:check — schema and migration journal in sync.
  • Focused retention/snapshot/idempotency schema tests — 10 passed.
  • Storage decision harness — 8 passing invariants after two RED/GREEN pairs and adversarial review.
  • Every child PR passed required lint-and-typecheck, build, and guards; relevant preview deployments, Preview Smoke, API Contract Tests, and per-slice browser/runtime proof are recorded on those PRs.

Shared dev proof for exact SHA 044a49d1:

  • Vercel deployment dpl_zvJbQL75cmpzYGgqEQMkpbmxRPav READY at https://open-agents-klvckwsyg-dennisons-projects.vercel.app.
  • Stable alias: https://open-agents-env-dev-dennisons-projects.vercel.app.
  • Public smoke: home, /api/auth/info, and /api/models all returned 200.
  • Agent Browser signed-out smoke verified the new landing journey and safe redirects from /runs and /automations; no page errors. One non-blocking Vercel Web Analytics script warning was observed.
  • Authenticated/destructive dev smoke was intentionally not run because the environment-isolation audit failed; no production state was mutated by a test journey.

Evidence quality: deterministic full-suite/build proof, isolated preview deploy/migration proof, source-specific preview/browser/runtime proof, and exact-SHA non-destructive shared-dev smoke. Production proof will be added after merge and deployment.

Risk and rollback

Risk tier: high because this release includes workflow/executor changes and migrations, despite each slice being additive or backward-compatible.

Rollback/fix-forward:

  1. If public production smoke fails, use vercel rollback first and inspect logs second.
  2. App rollback is compatible with additive snapshot columns/constraints.
  3. Do not reverse 0085 after null-source Runs exist; fix forward while preserving retained evidence.
  4. Source-specific executors and legacy routes remain available, so canonical product presentation can be reverted without data conversion.
  5. Missing allowlists/canary credentials must remain blocked_by_configuration, never passed or recovered.

Live risks/limitations:

  • Authenticated canary requires a disposable identity/repo/cookie and both source allowlists; absence is a proof limitation, not success.
  • Dev isolation is currently an explicit violation (ops: isolate dev Postgres and Redis from production #981), so destructive shared-dev validation is blocked.
  • Local Vercel ops helpers defaulted to the wrong team until the checkout was explicitly linked to dennisons-projects/open-agents; production evidence below uses exact scope/deployment metadata.

Reviewer guide

Review in this order:

  1. docs/plans/sessions-automations-runs.md and [Epic] Product reset: durable Sessions, Automations, and trustworthy Runs #931 for the product boundary.
  2. Canonical adapters/routes under apps/web/lib/{automations,runs} and apps/web/app/{automations,runs}.
  3. Migrations 00850087, snapshot schemas, and source deletion behavior.
  4. apps/web/lib/unattended-runtime/normalized-step-input.ts plus background/loop executor adapters.
  5. docs/decisions/automation-run-storage.md for why storage/executors intentionally remain source-specific.
  6. ops: isolate dev Postgres and Redis from production #981 before any destructive dev testing.

dennisonbertram and others added 30 commits July 3, 2026 13:41
Adds failing coverage for BackgroundRunDetail: a run with
errorKind=permission_missing must render plain-language "what
happened / what to do" copy above the fold, before the Debug
section, and a healthy run must show no banner at all. Also adds
a coverage test for a new colocated background-runs error-copy
module mirroring the loops error-copy.ts exhaustiveness pattern.

Confirmed red: `bun test "apps/web/app/background-runs/[runId]/background-run-detail.test.tsx"`
failed with "Expected to contain: doesn't have write access" before
the RunErrorBanner component existed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…795)

The only accurate explanation for a failed background run (e.g.
permission_missing) was buried in the operator-facing Debug section,
several clicks past the surfaces a user actually looks at first.

Adds a new colocated error-copy.ts (mirroring apps/web/app/loops/error-copy.ts)
scoped to BackgroundAgentErrorKind, and a RunErrorBanner component rendered
above the fold on /background-runs/[runId], right after the page header and
before the proof strip / Debug section. Renders nothing when errorKind is
null. The existing sidebar "Run" card's raw errorKind/errorMessage text and
the Debug section are left untouched, per the ticket's scope.

Scope decisions recorded (per ticket's open questions):
- Forked a background-runs-specific error-copy.ts rather than sharing
  loops' module, since BackgroundAgentErrorKind is a distinct vocabulary
  (only 3 of 10 kinds overlap with ALL_KNOWN_LOOP_ERROR_KINDS).
- Deferred the trigger-surface (repo-agents-dashboard.tsx) status
  affordance — out of scope per the ticket, not implemented here.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
docs: define Sessions, Automations, and Runs product contract
ops: make authenticated production canary classifications truthful
…wlists

fix: fail closed unattended repository allowlists
product: gate experimental systems out of default Sessions
regression: lock durable Session reconnect semantics
@vercel

vercel Bot commented Jul 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
open-agents Ready Ready Preview, Comment Jul 12, 2026 7:15am
open-agents (dev) Ready Ready Preview, Comment Jul 12, 2026 7:15am

…elop-931

chore: merge main release ancestry back into develop
@dennisonbertram
dennisonbertram merged commit 5f5b6a9 into main Jul 12, 2026
9 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: faff303627

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +327 to +330
return lifecycleResponse(
{
success: true,
alreadyRunning: true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Persist active state before reporting resumed

When a hibernated session has only a saved sandboxName and the provider answers the resume call with “sandbox is already/still running,” this branch returns 200/alreadyRunning without calling updateSession or restoring an active runtime state. The client handles alreadyRunning by polling /api/sandbox/reconnect, but that route requires runtime state with an expiresAt; the still-paused DB state ({ type, sandboxName }) is reported as no_sandbox, so the user sees resume fail even though the VM is live. Persist a refreshed active state or perform a real reconnect before returning success here.

Useful? React with 👍 / 👎.

@dennisonbertram

Copy link
Copy Markdown
Owner Author

Production verification — 2026-07-12

Release merged and deployed.

  • Release PR merge: 5f5b6a91a6b462a3d3877304367221223947a90f.
  • GitHub Production deployment: 5410639522, exact SHA 5f5b6a91.
  • Vercel deployment: dpl_HJxQMYJAf4HT9icVCJmYx79m6jg3, READY.
  • Immutable deployment URL: https://open-agents-3eis6dc40-dennisons-projects.vercel.app
  • Stable production URL: https://open-agents-azure-xi.vercel.app
  • Manual public smoke: home, /api/auth/info, and /api/models all returned 200.
  • Automated Production Smoke: passed — https://github.com/dennisonbertram/fork-open-agents/actions/runs/29184048835
  • Recent production 500/502/503/504 query, 30-minute window: no logs found.
  • Agent Browser production smoke: landing renders the durable Session / Automation / Run story; signed-out /runs and /automations redirect safely; no page errors. One non-blocking missing Vercel Web Analytics script warning was observed.
  • Release ancestry: completed product/runtime/storage child merge SHAs are ancestors of origin/main through 044a49d1 and release merge 5f5b6a91.

Authenticated automation proof

Truthful result: blocked_by_configuration; no authenticated production journey executed.

  • Strict local config check exited 2 and printed Classification: blocked_by_configuration / Proof: No production proof occurred.
  • GitHub Actions canary variables PRODUCTION_CANARY_REPO and PRODUCTION_CANARY_IDENTITY are absent.
  • GitHub Actions secret PRODUCTION_CANARY_AUTH_COOKIE is absent.
  • Vercel production has AGENT_LOOPS_ENABLED, but both exact repository allowlists are absent, so unattended execution fails closed.
  • The scheduled canary was not manually dispatched without a configured disposable identity/repo, per the production-ops safety rule.
  • Remaining provisioning is tracked and updated in feat: unblock the authenticated production canary and wire both journey harnesses into it #866.

Known operational limitations

Production claim: the exact release is deployed, publicly healthy, migration/build gates passed, and signed-out product routes are smoke-proven. Authenticated unattended execution is implemented and fail-closed, but remains unproven in production until #866 is configured.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant