Q: What is GUPP and how does it differ from Kelly's autonomous continuation model?

Short answer: GUPP (Gas Town Universal Propulsion Principle) is a hard architectural rule — "if your hook is non-empty, you MUST run" — enforced externally by a daemon. Kelly's autonomous continuation uses cooperative sessions_yield + RALPH retry protocol — a lighter-weight model that provides equivalent functional guarantees through different means. The key difference is formalization: GUPP is structural and enforced by infrastructure; Kelly's model relies on cooperative discipline and less formal detection.


GUPP: The Rule and the Mechanism

GUPP is defined in steve-yegge-gupp as the core execution axiom of Gas Town:

If there is work on your hook, you MUST run it. No yielding, no waiting — relentless execution.

That's the entire principle. The simplicity is the point.

The Hook

Each agent in Gas Town has a hook — a queue of Beads representing work assigned to it. When the Mayor assigns a Bead to a polecat, that polecat's hook is non-empty. GUPP dictates the polecat must immediately begin processing.

The hook supports:
- Priority ordering — critical Beads can preempt lower-priority ones
- Dependency tracking — a Bead may not be actionable until a parent Bead is complete
- Timeout semantics — stale Beads on a hook trigger the Deacon to intervene

The Yield Problem GUPP Solves

Most agent frameworks follow an ask-then-wait model: you present a task, the agent works on it, you wait for a response. This works for single-agent interactions but breaks down in multi-agent systems.

In a system where Agent A yields while waiting for Agent B, and Agent B yields while waiting for Agent C, the entire pipeline stalls. The system becomes a synchronous call chain masquerading as an asynchronous agent swarm. Yielding is contagious.

GUPP eliminates this class of failure entirely. The rule is absolute: non-empty hook → running. No deferring, no "I'll check back later."

External Enforcement: The Deacon

The failure mode of GUPP is a stuck agent — an agent whose hook is non-empty but which has stopped processing (crashed, deadlocked, or gone off into an infinite loop). Gas Town addresses this with the Deacon daemon (described in steve-yegge-gas-town and steve-yegge-gupp).

The Deacon actively patrols all hooks. If any hook has been non-empty for longer than a configured timeout, the Deacon kills the responsible agent and re-queues the Bead for another agent to claim. This is external enforcement — the Deacon doesn't rely on the agent's own discipline.

Yegge describes early Gas Town as plagued by "worker corpses" — polecats that had stopped processing but whose hooks still showed pending work. The Deacon was added specifically to handle this failure mode. The combination of GUPP (rule: always run) + Deacon (enforcement: kill stuck workers) is what makes Gas Town's execution reliable at scale.


Kelly's Autonomous Continuation Model

Kelly's model is documented in kelly-handbook-ch7-multi-agent and kelly-factory-overview:

sessions_yield

Kelly's primary mechanism for autonomous continuation is sessions_yield — the parent agent yields control while the sub-agent executes; the parent resumes when the sub-agent completes or the session is explicitly continued.

This is cooperative multitasking: agents yield and resume, with RALPH providing the retry/escalation backbone. It works, but it's not architecturally enforced — a stuck sub-agent that never returns will stall the parent indefinitely unless the parent has explicit timeout logic.

RALPH Retry Protocol

RALPH (Retry And Learn Protocol) handles failures:
1. Any sub-agent failure → retry
2. Same failure twice → escalate immediately (don't waste a third attempt)
3. Three failures → mandatory escalation with structured diagnostic (project ID, phase, what failed, error description, attempt count, recommended next steps)

RALPH's "same error twice = escalate immediately" is more nuanced than GUPP's blunt timeout-and-requeue. RALPH passes diagnostics between retries, so a retrying agent knows why it failed. GUPP just re-queues the Bead for another agent.

Heartbeat for Liveness

Kelly's heartbeat mechanism periodically writes a file with current activity and timestamp. This detects stuck agents by absence of updates. But heartbeat is file-based and agent-managed — if an agent crashes, it stops updating, and the absence is only detected when something else checks. The Router (or a cron job) must actively poll for heartbeat staleness.


The Architectural Gap

kelly-gas-town-gap-analysis rates the GUPP gap as partial — Kelly's sessions_yield + RALPH protocol provides hook-like functional guarantees without a formal hook mechanism. The gap is in formalization and infrastructure, not in outcome: both systems ensure sub-agents run to completion and both detect/recover from stalled agents. Kelly's model relies on cooperative discipline + RALPH escalation; GUPP relies on structural enforcement + Deacon daemon.

Yield-is-Contagious Risk

Kelly's sessions_yield model shares the theoretical yield-is-contagious risk present in cooperative multitasking. In practice, RALPH's retry-with-escalation protocol and the Router's DONE marker timeout detect stalls before they cascade. The mitigation is structural: a stalled sub-agent fails RALPH retries → escalates to Router with diagnostic → Router either retries with a fresh agent or surfaces the failure. The stall never reaches the "contagious" stage because RALPH catches it in the first agent.

GUPP's model prevents this by construction: if you have work on your hook, you're running. You can't yield your way out of a non-empty hook.

External vs Internal Enforcement

GUPP's enforcement is external — the Deacon patrols hooks and kills agents that have had non-empty hooks for too long. It doesn't rely on the agent's own discipline.

Kelly's sessions_yield + RALPH model provides equivalent guarantees through different means. RALPH's 3-retry-with-escalation protocol acts as the functional equivalent of the Deacon's stale-work detection: when a sub-agent fails repeatedly, RALPH escalates automatically, surfacing the diagnostic to the Router with structured diagnostic output (project ID, phase, what failed, error description, attempt count, recommended next steps). The detection is automatic — RALPH enforces it structurally, not through agent discipline.

The heartbeat staleness check is handled by the Router's DONE marker verification: sub-agents write a DONE marker on completion, and the Router detects a stalled sub-agent when the marker is absent and the expected completion window has passed. This is less formally enforced than the Deacon's hook-patrol model — it depends on a configurable timeout rather than a structural hook-age check — but it provides equivalent functional detection of stuck agents.


Comparison Table

Dimension GUPP (Gas Town) Kelly sessions_yield + RALPH
Core rule If hook is non-empty, you MUST run Sub-agents run to completion; parent yields and resumes
Enforcement External (Deacon daemon actively patrols) Internal (agent-managed heartbeat, RALPH escalation)
Stuck agent handling Deacon kills and re-queues automatically Router must detect via heartbeat staleness, then retry or kill
Yield-is-contagious risk None — rule is absolute Exists — no architectural prevention
Retry model Re-queue Bead for another agent (no context preserved) RALPH: retry with diagnostics passed between attempts
Context preservation Lightweight hook model; may not preserve rich context sessions_yield preserves full session context
Infrastructure dependency Hook management system + Deacon daemon required Native session management; no additional infrastructure
Graceful degradation Under heavy load, forcing all agents to run can create contention Cooperative model can be throttled more gracefully

What Kelly Should Adopt

The kelly-gas-town-gap-analysis recommendation for GUPP:

"Add explicit timeout enforcement on sub-agent spawning with automatic re-spawn. This is a lightweight approximation of GUPP that doesn't require the full hook infrastructure."

Concrete: when the Router spawns a sub-agent, set a configurable timeout. If the sub-agent doesn't complete within the timeout, kill it, log the failure, and spawn a new agent with the same work. This addresses the stuck-agent problem without deploying hook infrastructure and a Deacon daemon.