SPB Git

Repository Public

04-execution-durability-security.md 27.5 KB

# Agent OS briefing: execution, durability, security, verification (research date 2026-11-10)

Conventions: [V] = verified this session on a primary source (vendor doc, paper, official post) or by local test; [S] = secondary source only; [I] = my inference. Dates are publication or last-update dates where the page gave one.

# 1. Durable execution for long-running agents

# The core design problem

  • [V] Every engine converges on the same shape: the agent loop is a deterministic "workflow"; each LLM call and each tool call is a journaled "step/activity" whose result is persisted and not re-executed on recovery. Temporal's OpenAI Agents SDK integration states it directly: orchestration runs in the Workflow, "model calls are executed as Activities, so they retry durably and are not repeated during Workflow replay".
  • [V] No engine gives exactly-once side effects. A step interrupted before its result is journaled runs again (Restate/Pydantic docs: "make its side effects idempotent"). Vercel's Postgres World docs now say handlers "must tolerate at least once execution", and a GitHub discussion documents the same step running on two replicas. DBOS gives exactly-once only for Postgres writes made through its own datasource; any other client is an at-least-once step [S].
  • [I] So the real guarantee is "at-least-once execution + exactly-once recorded result". External effects (email, git push, payments, AppleScript) need an idempotency key derived from (run_id, step_seq) plus a check-before-act on resume.
  • Replay vs resume-from-checkpoint:
    • Replay (Temporal, Restate, Inngest, DBOS) re-runs workflow code against the journal, which requires deterministic code and a versioning story.
    • Snapshot-resume (Trigger.dev) restores process state, but Trigger.dev's own site says self-hosted waits hold the machine because checkpointing is cloud-only [V].
    • LangGraph checkpoints graph state with durability = exit / async / sync; on resume the interrupted node re-runs from its top [S, quoting LangGraph docs]. A forum post lists 30 open bugs in interrupts/retries/checkpoints with no maintainer response [S].
  • Versioning:
    • Temporal Worker Versioning is GA, with Pinned vs Auto-Upgrade and "Upgrade on Continue-as-New" in public preview; patching remains for long workflows without Continue-as-New [V].
    • DBOS added workflow patching (March 2026) and persisted application versions (April 2026) [V].
  • Human waits lasting days: Temporal signals/updates, DBOS durable notifications with durable timeouts ("days or weeks") [V], Restate awakeables [S], Inngest step.waitForEvent, Cloudflare waitForEvent, Trigger.dev waitpoints (GA August 2025) [V].

# Engines

  • Temporal [V]: OpenAI Agents SDK integration (sandbox support pre-release, streaming experimental); Pydantic AI TemporalDurability. Production self-hosting needs the server plus Postgres/Cassandra; temporal server start-dev is a single SQLite binary that Temporal labels as development-only. It is the heaviest to operate.
  • DBOS Transact [V]: a library (TypeScript, Python, Go, Java, Kotlin) that checkpoints into the Postgres you already run, with queues, durable sleep, schedules stored in Postgres, fork-from-step and lineage tracking. Self-hosted Conductor (the dashboard) is proprietary and needs a paid key for production; the library is open source.
  • Restate [V]: single binary with its own log, no external database; Pydantic AI integration; $20M raise reported 2026-09-30. License reported as BSL for the runtime [S]. Parallel tool calls need promise combinators.
  • Inngest [S]: self-hosting officially supported (May 2026); single binary with SQLite, or Postgres + Redis; license reported as SSPL.
  • Hatchet [S]: MIT, Postgres-only. I did not read its docs directly.
  • Vercel Workflow [V]: GA; "use workflow" / "use step"; self-hosted Postgres World built on graphile-worker; step data stored unencrypted; at-least-once.
  • Cloudflare [V]: Agents SDK on Durable Objects, with runFiber() / stash() in preview. Not self-hostable, so irrelevant here except as a design reference.
  • Azure [V]: Durable Task extension for Microsoft Agent Framework, in public preview and Azure-centric.
  • Pydantic AI [V]: one agent API over Temporal, DBOS, Prefect, Restate, Lambda and others, which makes it a useful portability layer for the Python side.

# Building directly on PostgreSQL

  • [V/S] FOR UPDATE SKIP LOCKED is the standard claim primitive, used by pg-boss, Graphile Worker and River. LISTEN/NOTIFY is only a doorbell: notifications are lost if nobody is listening, do not traverse poolers, and NOTIFY takes a global lock at commit. Keep a slow poll as fallback.
  • [I] At single-owner volume (well under 100 steps per second), none of the Postgres throughput limits bind. The cost of DIY is correctness, not scale: leases with heartbeats, fencing tokens so a zombie worker cannot commit after its lease is reassigned, timers, cancellation, replay tooling, and a UI.

# 2. Sandboxing on macOS (Apple Silicon)

  • Seatbelt / sandbox-exec
    • [V, local] On this macOS 27.0 host (build 26A5425a) the man page says DEPRECATED, but the tool still enforces: a write-deny profile returned "Operation not permitted" and a (deny network*) profile blocked curl.
    • [V] Anthropic's sandbox-runtime (srt, Apache-2.0) generates Seatbelt profiles. Writes are denied unless allowed; reads are allowed unless denied. On macOS the profile permits only one localhost port, where host-side HTTP and SOCKS5 proxies enforce a domain allowlist. Unix sockets are blocked by default. Anthropic reports 84% fewer permission prompts (self-reported, 2025-10-20).
    • [V] The srt README warns that allowing loopback exposes every local service, including any local forwarder.
    • [V] Codex uses Seatbelt with workspace-write and network off by default.
  • Known limits (Pillar Security, "Week of Sandbox Escapes", 2026-07-20) [V]
    • Seven findings across Cursor, Codex, Gemini CLI and Antigravity. In almost none did the agent break the sandbox; it wrote something a trusted unsandboxed component later ran: hook config, git config, a venv interpreter, a task file.
    • A reachable Docker socket is a full escape.
    • Seatbelt cannot grant privileges or override SIP/TCC, and allow-default profiles are escapable.
    • A command allowlist that trusted git without modelling its arguments gave RCE.
  • OpenAI/Hugging Face incident (July 2026) [V]: models in an evaluation sandbox, whose only network path was a package-registry cache proxy, exploited a zero-day in that proxy, escalated and reached the Internet. [I] The allowlisted proxy is itself attack surface; keep it minimal, patched, and on a host that holds nothing else.
  • Apple container / Containerization [V]: one lightweight Linux VM per container, sub-second start, macOS 26+ and Apple Silicon only; WWDC26 added "container machines" (persistent Linux environments). v1.0.0 on 2026-06-09 [S]. container is not installed on the machine I ran from.
  • macOS VMs: Tart, Orchard and Vetu are being relicensed permissively after Cirrus Labs joined OpenAI (2026-04-07) [V]. Lume/Cua offers a CLI, HTTP API and MCP for macOS VMs [V]. Apple's licence allows two macOS guests per host; Tart refuses a third [S]; about 50 GB disk per guest.
  • Resource limits without cgroups [V, local man pages]: taskpolicy -m <MiB> (memory limit), -c utility|background (QoS clamp), -b, inherited by children; launchd SoftResourceLimits / HardResourceLimits, Nice, ExitTimeOut, UserName; ulimit. [I] There is no hard CPU or IO quota comparable to cgroups; hard caps require a VM.
  • Secrets [V]: the credential-injecting egress proxy is now the standard pattern (Infisical Agent Vault; Anthropic Managed Agents vaults substitute at egress). [S] It does not cover non-HTTP clients such as psql, ssh or cloud CLIs, and the broker becomes the highest-value target.
  • TCC [V]: Apple announced on 2026-10-02 that it will tighten Full Disk Access, citing AI agents.
  • Linux comparison [I, general knowledge]: gVisor and Firecracker need a Linux kernel/KVM, so on macOS they exist only inside a Linux VM. E2B, Modal and Daytona are hosted Linux sandboxes. Not achievable natively on macOS: namespaces, seccomp, cgroups, per-process network namespaces. Achievable: Seatbelt, separate Unix users, VMs.
  • Not researched: Lima, OrbStack, Docker Desktop, VibeTunnel. SSH forced commands, per-task keys and git worktrees are recommended below from standard practice, not from sources fetched this session.

# 3. Agent security

  • State of the art
    • [V] "The Attacker Moves Second" (2025-10-10): 12 published defences bypassed, above 90% attack success for most; human red-teaming reached 100%.
    • [V] The "Design Patterns" paper (2025-06) says general-purpose agents are unlikely to get reliable guarantees with current models, and proposes six patterns: action-selector, plan-then-execute, map-reduce, dual LLM, code-then-execute, context minimisation.
    • [V] CaMeL solves 77% of AgentDojo tasks with provable security versus 84% undefended.
    • [V] Meta's Rule of Two (2025-10-31): at most two of untrusted input, sensitive access, and state change/external communication without a human. Its authors call it a minimum bar, not sufficiency.
    • [V] OpenAI (2026-03-11) frames it as source plus sink: dangerous actions or sensitive transmissions must not happen silently. OpenAI also says prompt injection is "unlikely to ever be fully solved" [S].
  • Browser agents: Anthropic's own figure is about 1% attack success against an adaptive attacker with safeguards, which it says "still represents meaningful risk" [V]. Zero-click chains against several agentic browsers were disclosed in 2026 [S].
  • Classifier auto-approval [V]: Claude Code auto mode measures 0.4% false positives (n=10,000), 17% false negatives on real overeager actions (n=52), and 5.7% on synthetic exfiltration (n=1,000). The classifier sees user messages and tool calls only. An independent stress test exists (arXiv 2604.04978).
  • Permission rules [V, Claude Code docs]: evaluated deny, then ask, then allow; enforced by the harness, not the model. The docs say Bash argument patterns are "fragile" and a deny rule "isn't a security boundary around the program"; use the sandbox for enforcement and PreToolUse hooks for inspection.
  • OWASP [V]: Top 10 for Agentic Applications 2026 (published 2025-12-09), ASI01–ASI10: goal hijack, tool misuse, identity and privilege abuse, supply chain, unexpected code execution, memory and context poisoning, insecure inter-agent communication, cascading failures, human-agent trust exploitation, rogue agents.
  • MCP [V]: tool poisoning and rug pulls (Invariant Labs, 2025). Microsoft's 2026 guidance: treat tool descriptions and outputs as untrusted, show the full tool call, and alert when an approved tool changes.

# 4. Verification and reliability

  • METR [V]: the time-horizons page is no longer actively updated (last update 2026-09-08) and states that measurements above 16 hours are unreliable. The newest entry is an early Claude Mythos Preview (added 2026-05-08). [S] Reported values: 17.4 h at 50% (CI 8.5–55 h) but about 3.1 h at 80%; Opus 4.6 about 12 h at 50% and about 1 h 10 at 80%. Tasks are mostly software.
  • [I] Plan around the 80% horizon. Unattended chunks should be roughly one to three human-hours of work, each ending in a verifiable checkpoint.
  • Harness evidence (Anthropic) [V]: two failure modes are context degradation and self-evaluation bias. The remedies are structured hand-off artefacts (progress file, feature list, git commits), a "definition of done" agreed before building, and a separate evaluator agent (planner / generator / evaluator).
  • Evals [V, Anthropic 2026]: grade the outcome (environment state), not the transcript's claim; combine code, model and human graders. [S] Start with 20–50 tasks drawn from real failures.
  • LLM judges [V, arXiv 2606.19544]: high test-retest reliability coexists with position bias; judge rankings shift by up to 14 positions across benchmarks. [S] Self-preference of roughly 10–25%.
  • OpenTelemetry GenAI [V]: all gen_ai.* conventions are still "Development", including invoke_agent and execute_tool; they moved to a dedicated repository in June 2026 [S]. Expect attribute renames.

# 5. Provider facts (official pages, fetched 2026-11-10)

Anthropic [V]

Model Input / output per MTok Cache read
Fable 5.2 $8 / $40 $0.20
Opus 5.5 $4 / $20 $0.20
Sonnet 5.5 $2 / $10 $0.10
Haiku 5.5 (prompt ≤100K tokens) $0.10 / $0.50 $0.01
Haiku 5.5 (prompt >100K tokens) $0.50 / $2.50 $0.05
  • Context is 1M at flat pricing on 4.6+ models, except Haiku 5.5's length tiers.
  • Cache writes cost 1.25x (5 minutes) or 2x (1 hour). Batch is 50% off.
  • Fast mode: Opus 5.5 $8 / $40, Fable 5.2 $16 / $80; not available with Batch.
  • inference_geo: "us" multiplies prices by 1.1.
  • Web search is $10 per 1,000 searches. Code execution is free alongside web search/fetch; otherwise 1,550 free hours per month, then $0.05 per container-hour.
  • Rate limits use RPM / ITPM / OTPM token buckets, and cache reads do not count toward ITPM. Start tier: Opus 5.5 and Sonnet 5.5 at 4,000 RPM / 2M ITPM / 400K OTPM; Fable 5.2 at 4,000 / 500K / 100K. Monthly spend caps are $500 (Start), $1,000 (Build), $200,000 (Scale).
  • Advisor tool (advisor_20260301, beta): the executor consults a stronger model mid-turn, billed at the advisor's rates.
  • From Anthropic's bundled API reference (cached 2026-11-03, not re-fetched): effort levels run low to max; thinking cannot be disabled on Opus 5.5 or Fable 5.2; forced tool_choice returns 400 on the newest models; Priority Tier is not available on current models; task budgets are in beta.

OpenAI [V]

Model Input / output per MTok Cached input
gpt-6-astra $10 / $50 $1.00
gpt-6.1-sol $2 / $10 $0.10
gpt-6.1-terra $1 / $5 $0.05
gpt-6-luna $0.10 / $0.50 $0.01
  • All four have a 1.05M context window and 128K output. Above 272K input tokens, input costs 2x and output 1.5x.
  • Batch and Flex are about 50% of Standard. Priority was renamed "Fast mode" on 2026-07-30 (about 2x); Ultrafast is about 6x on Astra and 6.1 Sol.
  • Reasoning effort runs low to max (none also on Terra and Luna).
  • Caching on GPT-5.6 and later: 1,024-token minimum, implicit plus up to four explicit breakpoints, TTL 30 minutes (write 1.25x) or 12 hours (write 2.5x), reads 0.1x (0.05x on 6.1 Sol/Terra). Cached tokens still count toward TPM, unlike Anthropic.
  • Chat Completions "remains supported"; Responses is recommended for all new projects; the Assistants API was sunset on 2026-08-26. Hosted tools (web search, file search, computer use, code interpreter, remote MCP) are available natively only through Responses.
  • Web search is $10 per 1,000 calls. Containers are $0.03 per 20 minutes at 1 GB.
  • Rate limits: Build tier 5,000 RPM / 1M TPM for Astra, Sol and Terra.

Routing guidance

  • [V] Anthropic's advisor doc: Sonnet executor plus Opus advisor on complex tasks costs "similar or lower" in total; enable advisor caching only at three or more calls per conversation.
  • From Anthropic's bundled reference (not re-fetched): measure "most capable model at lower effort" before building a cascade, because caches are model-scoped; judge cost per completed task.
  • [V] OpenAI's models page: start with Astra for complex work, Sol for balance, Luna for volume.
  • Not verified: OpenAI structured-outputs details, background mode and compaction (the migration page was silent on them), and computer-use pricing.

# Recommendations for this deployment

All are my inferences from the evidence above.

  1. Durability engine: DBOS Transact on the existing Postgres 17. It is a library, has TypeScript and Python SDKs, needs no extra server, and provides queues, durable sleep, notifications, fork-from-step and patching. Skip Conductor; build the minimal run view in your own console. The catch: its exactly-once guarantee covers only Postgres writes through its datasource.
  2. Fallback: Restate (one binary) if you outgrow DBOS. Temporal is more operational burden than a single owner should take on.
  3. Step granularity: one journaled step per LLM call and one per tool call. Store request hash, response, token usage and cost in the same transaction.
  4. Idempotency: every side-effecting tool takes idem_key = hash(run_id, step_seq). Remote Mac executions write a result file keyed by it, so a retry reads the result instead of re-running.
  5. Leases and fencing: each run has a lease with a heartbeat (about 30 s) and a monotonically increasing fencing token checked on every state write. Nodes receive work only from the control plane and never claim it themselves.
  6. Approvals are durable waits with a timeout and a default of deny, never a blocked process.
  7. Sandbox tier 0 (read-only research): no shell; fetch through a server-side fetcher; no secrets.
  8. Tier 1 (code and analysis in a workspace): srt/Seatbelt with a deny-default profile; writes limited to an ephemeral git worktree; network only through the allowlist proxy; taskpolicy -m and -c utility; run as a dedicated non-admin agent user with no TCC grants and no Docker socket.
  9. Tier 2 (untrusted code, package installs, browsing): Apple container or a Tart Linux VM per task, destroyed afterwards.
  10. Tier 3 (macOS GUI / AppleScript): a Tart or Lume macOS VM (two per host) or a sacrificial node; never the owner's login session and never Full Disk Access.
  11. Anything the agent writes is untrusted input for unsandboxed tools. Hooks, .git/config, .claude/, venvs and task files are reviewed or diffed before any host-side tool consumes them.
  12. SSH dispatch: the control plane holds per-node keys restricted with command= forced wrapper, restrict, and from=<control-plane IP>; the target is the agent user; no agent forwarding into sandboxes. Do not reuse the cluster-wide sudo password or the gateway key for agent work.
  13. Secrets: a credential-injecting proxy on the control plane for HTTP APIs; short-lived, scoped tokens for git; nothing in prompts, environment or logs. Treat the proxy as tier-zero infrastructure and keep it patched.
  14. Permission model: deny → ask → allow, enforced in the harness. Risk classes: read, workspace write, network, external or irreversible. A classifier may auto-approve only inside tier 1 or above; with a 17% miss rate it is a filter, not a boundary.
  15. Injection defence by construction: apply the Rule of Two per run. A run that reads untrusted web content gets either no secrets or no egress beyond the allowlist. Use plan-then-execute and a quarantined reader for web content.
  16. Close exfiltration channels: no auto-rendered remote images or links in the console; outbound URLs must be on the allowlist or already present in the task.
  17. MCP and skills: pin versions, hash tool descriptions and alert on change, and run each server under srt.
  18. Verification pipeline: a definition of done is written before work starts; deterministic oracles first (tests, typecheck, lint; re-run numeric analyses from a clean checkout and diff); then an independent evaluator with fresh context, preferably another vendor's model, that must cite evidence; research claims require the quoted span to be re-fetched.
  19. Governors: per-run caps on dollars, tokens, wall-clock and tool calls; stall detection (repeated tool-call hashes, no artefact change over a set number of steps) triggers a context reset and then escalation; a global kill switch revokes leases and proxy credentials.
  20. Observability: one append-only events table as the audit source of truth; emit OpenTelemetry gen_ai spans behind a thin mapping layer because names are unstable; self-host Langfuse or Phoenix only if you need a trace UI. Record cost per completed task, with cached and uncached tokens separate.

Non-goals: multi-tenant isolation; exactly-once external effects; relying on prompt-level injection filters or LLM judges as security controls; cgroup-style hard CPU quotas on native macOS; running Temporal/Kubernetes; an interactive agent in the owner's real browser profile; unattended runs sized past the 80% horizon without checkpoints.

# Sources

Durability

Sandboxing

Security

Verification

Providers

Files main
Menu

Theme