State machine · 07 of 19 · Run lifecycle

A run always ends, whether or not anyone is watching

Every path ends in deletion. The deadline is enforced by the composition, not by the gateway, so a dead or compromised Clearance cannot leave a run alive. A tripped breaker freezes a run for review instead of destroying the evidence.

A run always ends, whether or not anyone is watching State machine of an agent run: requested, provisioning, running, draining and deleted, with a frozen state entered when the session breaker trips that cuts egress but keeps the logs for a hold period, and a fail-closed path that drains a run that never became ready. ADMITTEDREADYENDEDDELETEDBREAKERHOLD ENDSNEVER READY · 2 MINRequestedclaim createdProvisioningnamespace + policyRunningagent executesDrainingttl · done · budgetFrozenegress cut · logs keptExpiry needs no Clearance: past expiresAt the composition renders nothing and Crossplane removes the namespace.LEGENDWorking stateHeld for forensicsTransition stateBreakerFail closed

Principle honored

Fail closed, and never depend on one component being alive. This mirrors the existing PR-namespace pattern: primary cleanup plus an independent backstop.

What changes

  • Primary: expiresAt reached, so the function renders nothing and Crossplane garbage-collects.
  • Backstop: a sweep for agent-run namespaces with no live AgentRun. It must NOT reuse hangar.io/ephemeral-env, or the existing PR sweep will reap live runs.
  • Freeze holds 15 minutes by default, then drains.

Verify first

Stop Clearance and confirm a run still ends on time. Then kill the function pod mid-run. Time-driven re-invocation via the response TTL is unverified on your Crossplane version, so this is the first thing to test.

Hangar · Autopilot