DEV Community

Emery Li
Emery Li

Posted on

A Residency Lease for Agent Runs: Expiring Placement Decisions Instead of Static Config

A Residency Lease for Agent Runs: Expiring Placement Decisions Instead of Static Config

Reproducing the failure takes about a minute on any laptop: start an agent turn against a remote model endpoint, then drop the network with nmcli networking off halfway through. The run rarely fails loudly. It stalls, retries, and eventually writes a truncated artifact that still validates against the schema.

The placement config said remote, and nothing in that config knew the link had disappeared ten minutes earlier. A boolean flag cannot expire, so the run kept honouring a decision whose supporting evidence was gone. The fix is not a better flag; it is a decision that carries its own expiry date.

Why a static placement flag cannot survive a long run

Placement is normally decided once, at process start, on the assumption that the conditions measured at start still hold. Agent runs break that assumption in ordinary ways: tool calls take minutes, laptops sleep, tunnels drop, and a shared office uplink degrades at the exact moment a batch job begins. A static config records intent; it does not record evidence, and it cannot tell you when it stopped being true.

A lease replaces the flag with a small, immutable record: the chosen placement, the moment it expires, and the measurements that justified it. Invariants such as "this payload must not leave the host" produce long leases because they do not change with the weather. Measurements such as round-trip latency and packet loss produce short leases because they do.

The lease record

The data model is deliberately boring. Constraints are inputs, a lease is an output, and validity is a pure function of the clock, which makes every decision testable without a network.

# lease.py — a self-expiring placement lease for local-first agent runs
from __future__ import annotations
import os, re, statistics, socket, time
from dataclasses import dataclass
from enum import Enum

class Placement(str, Enum):
    LOCAL = "local"
    REMOTE = "remote"

@dataclass(frozen=True)
class Constraints:
    secret_free_local: bool   # payload may not leave the host
    offline_capable: bool     # must finish with no network at all
    p95_budget_ms: int        # per-turn latency budget

@dataclass(frozen=True)
class Lease:
    placement: Placement
    expires_at: float
    evidence: dict

    def valid(self, now: float | None = None) -> bool:
        return (time.time() if now is None else now) < self.expires_at
Enter fullscreen mode Exit fullscreen mode

Because Lease is frozen and carries evidence, a failing run can log the exact probe numbers that produced it. That single property removes most of the "why did it go remote last Tuesday" archaeology from incident reviews.

Step 1 — Probe the remote seat before trusting it

The probe measures the transport path to the server seat, not model quality. Point it at whatever health endpoint the deployment exposes; the socket version below is the minimum viable substitute when no HTTP endpoint is published.

# lease.py (continued) — transport probe, five samples by default
def probe(samples: int = 5, timeout: float = 2.0) -> dict:
    host = os.environ["SEAT_HOST"]
    port = int(os.environ.get("SEAT_PORT", "443"))
    latencies: list[float] = []
    for _ in range(samples):
        t0 = time.perf_counter()
        try:
            with socket.create_connection((host, port), timeout=timeout):
                latencies.append((time.perf_counter() - t0) * 1000)
        except OSError:
            latencies.append(float("inf"))
    ok = [x for x in latencies if x != float("inf")]
    return {
        "samples": samples,
        "p50_ms": round(statistics.median(ok), 2) if ok else None,
        "p95_ms": round(max(ok), 2) if ok else None,
        "loss": round(1 - len(ok) / samples, 2),
        "at": round(time.time()),
    }
Enter fullscreen mode Exit fullscreen mode

Illustrative output on a degraded link looks like {"samples": 5, "p50_ms": 88.1, "p95_ms": 1940.6, "loss": 0.2, "at": 1792471200}. The gap between p50 and p95 matters more than either number alone: a median of 88 ms with a 1.9 s tail is a link that will pass a smoke test and ruin a long run.

Step 2 — Turn constraints into invariants

Two constraints should outrank every measurement. If the payload contains secrets, or if the run must complete with no network, the lease goes local with a long expiry and no probe at all, because no amount of good latency changes the requirement.

SECRET_PATTERNS = [re.compile(p) for p in (
    r"sk-[A-Za-z0-9]{16,}",
    r"-----BEGIN [A-Z ]*PRIVATE KEY-----",
    r"(?i)aws_secret_access_key\s*=\s*\S+",
)]

def looks_secret_bearing(payload: str) -> bool:
    return any(p.search(payload) for p in SECRET_PATTERNS)
Enter fullscreen mode Exit fullscreen mode

This pattern list is a coarse gate and nothing more. A dedicated redaction gate for the payload itself belongs upstream; the check here exists to catch the case where a secret appears mid-run, in turn seven, long after placement was settled.

Step 3 — Derive the expiry from measured latency

The expiry is the interesting part, because it determines how quickly a bad decision gets reconsidered. Short leases re-probe often and cost little; long leases save probe overhead and risk staleness. The table below is the rule set this module implements.

Condition observed Placement Lease TTL Evidence recorded
Payload secret-bearing local 3600 s constraint flag, no probe
Run must survive offline local 3600 s constraint flag
Probe loss at or above 34% local 90 s samples, loss, timestamp
p95 above per-turn budget local 120 s p95, budget
p95 at or below half the budget, zero loss remote 300 s p95, loss
Everything else remote 120 s p95, loss
# lease.py (continued) — probe result becomes a lease
def decide(c: Constraints, now: float | None = None) -> Lease:
    now = time.time() if now is None else now
    if c.secret_free_local or c.offline_capable:
        return Lease(Placement.LOCAL, now + 3600,
                     {"reason": "invariant", "probe": None})
    p = probe()
    if p["p95_ms"] is None or p["loss"] >= 0.34:
        return Lease(Placement.LOCAL, now + 90, {"reason": "loss", **p})
    if p["p95_ms"] > c.p95_budget_ms:
        return Lease(Placement.LOCAL, now + 120, {"reason": "latency", **p})
    ttl = 300 if p["p95_ms"] * 2 <= c.p95_budget_ms else 120
    return Lease(Placement.REMOTE, now + ttl, {"reason": "measured", **p})
Enter fullscreen mode Exit fullscreen mode

Note that a healthy link does not earn an unlimited lease. It earns five minutes, which is roughly the interval at which a moving laptop or a shared uplink can change its mind.

Step 4 — Check the lease at every turn boundary

Enforcement belongs at the boundary between turns, never inside a tool call. Migrating mid-call produces the duplicated-side-effect bug that takes a week to diagnose; letting the call finish locally or remotely and re-deciding afterwards does not.

# lease.py (continued) — per-turn enforcement
def next_lease(current: Lease | None, c: Constraints) -> Lease:
    if current is not None and current.valid():
        return current
    return decide(c)

def run_turn(state, payload: str, c: Constraints) -> str:
    lease = next_lease(state.lease, c)
    if lease.placement is Placement.REMOTE and looks_secret_bearing(payload):
        lease = Lease(Placement.LOCAL, time.time() + 3600,
                      {"reason": "secret_in_turn", "probe": None})
    state.lease = lease
    if lease.placement is Placement.REMOTE:
        try:
            return state.remote(payload)
        except RemoteUnavailable as exc:
            state.lease = Lease(Placement.LOCAL, time.time() + 90,
                                {"reason": type(exc).__name__, "probe": None})
    return state.local(payload)
Enter fullscreen mode Exit fullscreen mode

The state object is deliberately unspecified here, because the interesting contract is the lease, not the client library. Any existing local-first runner can adopt the four functions above behind its current dispatch point.

Step 5 — Revoke, do not restart

Three signals should revoke a lease immediately rather than wait for expiry. A secret appearing in the current turn revokes to local for an hour, because the constraint is structural. A transport exception revokes to local for ninety seconds, giving the link time to recover before the next probe. An explicit rate-limit response from the server revokes for at least the advertised backoff window, and the run stops rather than probing around the limit.

Clock handling deserves its own line. After a host suspend, wall-clock time can jump while monotonic time does not, so a lease that looks valid may be hours stale. Comparing time.monotonic() deltas against the lease TTL, and treating a mismatch as expiry, catches the resume case that a pure time.time() comparison hides.

A fault matrix worth running before you trust it

Fault injected Expected behaviour Assertion
Link dropped mid-run renewal probe fails, placement flips to local no remote call after drop
Lease expires during a tool call call completes, re-decision happens after exactly one execution per turn
Secret appears in turn 7 immediate revoke to local, one hour TTL remote client untouched after turn 7
Host suspend and resume wall-clock jump treated as expiry fresh probe on next turn
Server returns a rate-limit response revoke and stop, no retry loop request count stays flat

The decision function itself is testable in milliseconds by replacing the probe, which keeps the suite fast enough to run on every commit.

import pytest, lease

@pytest.mark.parametrize("constraints,probe_result,expected", [
    (lease.Constraints(True, False, 800), None, lease.Placement.LOCAL),
    (lease.Constraints(False, True, 800), None, lease.Placement.LOCAL),
    (lease.Constraints(False, False, 800),
     {"p95_ms": None, "loss": 0.6}, lease.Placement.LOCAL),
    (lease.Constraints(False, False, 200),
     {"p95_ms": 640.0, "loss": 0.0}, lease.Placement.LOCAL),
    (lease.Constraints(False, False, 900),
     {"p95_ms": 120.0, "loss": 0.0}, lease.Placement.REMOTE),
])
def test_decide(constraints, probe_result, expected, monkeypatch):
    if probe_result is not None:
        monkeypatch.setattr(lease, "probe", lambda samples=5: probe_result)
    assert lease.decide(constraints).placement is expected
Enter fullscreen mode Exit fullscreen mode

The module and tests above were written for this article and exercised only against a stubbed probe; treat the probe target as the part you must adapt to your own deployment.

Where the free tier actually fits in the lease

The lease does not care which remote seat it points at, only whether that seat is reachable inside the budget. That is precisely why a free server option is useful as the remote side of a first lease: it makes the probe step cheap to run on real traffic, and the remote branch of the decision table can be exercised without a procurement conversation.

Disclosure: This article was prepared as part of MonkeyCode's product outreach.

MonkeyCode is described by its maintainers as an open source project, and the operator states that it offers free model access together with a free server option, with a ten-million-token allowance. Both are availability claims that can change without notice, so verify the current terms in the project's own materials before sizing a batch run against them; this article makes no claim about model names, hardware, throughput, or how long the offer lasts.

Placed inside the lease, the free server is the default remote branch for turns that carry no secrets and tolerate a measured p95. The free models are the reason the remote branch is worth probing at all for routine summarisation, classification, and drafting work, where a two-second tail is annoying rather than disqualifying.

Limitations and who should skip this

The probe measures transport, not output quality, so a lease can be perfectly healthy while the remote model produces worse results than the local one. Teams with contractual data-residency requirements need attested infrastructure, and a lease record is not an attestation. Anyone whose per-turn budget sits under about 50 ms on a LAN will find the lease flipping to remote and back for no operational benefit.

Single-host runners get the most from this pattern. Multi-tenant systems need a lease per tenant and per credential scope, which is a larger design than four functions. If the run is a one-shot script under thirty seconds, a static flag plus a timeout is genuinely the better engineering choice.

A reasonable next step is to implement only probe() and log its output for a week before wiring the decision in; the numbers will tell you whether your workload has the latency variance this lease exists to handle.

Top comments (0)