# How Agent Lifecycles Are Managed in Munder Difflin: A Complete Technical Guide

> Discover how Munder Difflin manages agent lifecycles using Hive orchestration for AI workers. Learn about spawning, monitoring, and archiving agents technically.

- Repository: [Chaitanya Giri/munder-difflin](https://github.com/chaitanyagiri/munder-difflin)
- Tags: deep-dive
- Published: 2026-08-28

---

**Munder Difflin manages agent lifecycles through a Hive orchestration system that spawns AI workers via provider-specific bridges, monitors runtime events through Unix sockets or proxies, and archives agents on graceful stop, manual kill, or natural exit.**

Munder Difflin treats every AI-driven worker as a **hive citizen** with predictable, observable lifecycle phases. The system abstracts provider differences through a **bridge pattern**, ensuring that agents from Claude, Codex, Grok, or custom providers all report consistent lifecycle events. This article explains the complete agent lifecycle management implementation in the `chaitanyagiri/munder-difflin` repository.

## The Five Phases of Agent Lifecycle Management

Agent lifecycle management in Munder Difflin follows five deterministic phases: **Create**, **Run**, **Interact**, **Terminate**, and **Resume**. Each phase is handled by specific components with clear responsibilities.

### Phase 1: Spawn — Creating a Hive Citizen

The `Hive.ensureAgent()` function in [`src/main/hive.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/hive.ts) (lines 31–48) is the entry point for agent lifecycle management. This method builds the command line for the chosen provider, injects the initial **Hive protocol prompt**, and wires the provider-specific bridge that normalizes lifecycle hooks.

```typescript
// From src/main/hive.ts
await ensureAgent({
  id: 'agent-123',
  name: 'Code-Wizard',
  provider: 'codex' as AgentProvider,
  cwd: '/my/project',
  autoMode: true,
});

```

The spawn logic performs three critical tasks:

- Selects the provider preset from `AGENT_PROVIDER_PRESETS`
- Installs the appropriate hook shim or proxy bridge
- Sets the `HIVE_SOCK` environment variable for event communication

### Phase 2: Bridge Selection — Abstracting Provider Differences

The `bridgeOf()` function in [`src/shared/agentProvider.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/shared/agentProvider.ts) (lines 58–66) returns a **BridgeDescriptor** that determines how lifecycle events are captured. Munder Difflin supports two bridge types:

| Bridge Type | Use Case | Implementation |
|-------------|----------|----------------|
| **Hooks** | Native CLI support (Claude, Codex, Grok) | Per-agent configuration files that emit events |
| **Proxy** | Non-Hive-aware providers | Sidecar loop-back proxy that synthesizes events |

For providers without native Hive support, the system automatically spins up a proxy (see [`src/main/hive.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/hive.ts) lines 18–34) that translates API calls into standardized lifecycle events.

### Phase 3: Hook Installation — Capturing Runtime Events

Provider-specific installers like `installAgyHooks()` and `installCodexHooks()` write configuration files (e.g., [`CODEX_HOME/hooks.json`](https://github.com/chaitanyagiri/munder-difflin/blob/main/CODEX_HOME/hooks.json)) that cause the CLI to emit three critical event types:

- **PreToolUse** — Fired before tool execution
- **PostToolUse** — Fired after tool execution completes  
- **Stop** — Fired when the agent terminates normally

These payloads are forwarded to the Hive via the `HIVE_SOCK` Unix socket (lines 73–86 in [`src/main/hive.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/hive.ts)).

### Phase 4: Runtime Monitoring — Keeping the UI Synchronized

After spawning, `Hive.ensureAgent()` continues monitoring by:

1. Setting `HIVE_SOCK` (or the proxy's session ID) in the spawned process environment
2. Reading `log.jsonl` events including spawns, archives, and messages
3. Updating renderer state through [`src/renderer/src/hooks/useHive.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/renderer/src/hooks/useHive.ts)

The [`broadcast.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/broadcast.ts) module ([`src/shared/broadcast.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/shared/broadcast.ts), lines 40–45) determines which agents are **live**, **archived**, or **dead** and fans out messages accordingly. Archived agents never receive new inbox mail—they remain visible only for historical inspection.

### Phase 5: Graceful Termination and Archiving

Agent lifecycle management ensures consistent cleanup through three termination paths:

| Termination Trigger | Handler | Archive Behavior |
|---------------------|---------|------------------|
| **Stop hook** | Lifecycle shim or proxy | Automatic archive entry |
| **Manual kill** | [`pty.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/pty.ts) / [`procKill.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/procKill.ts) | Same archive routine invoked |
| **Natural exit** | Process exit handler | Guaranteed archive on termination |

The archive routine in [`src/main/hive.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/hive.ts) (lines 96–100) writes an entry to `log.jsonl`, drains pending inbox mail, and updates [`registry.json`](https://github.com/chaitanyagiri/munder-difflin/blob/main/registry.json) to show the agent as archived.

```typescript
// Force-archive an agent manually
import { archiveAgent } from './main/hive';

await archiveAgent('agent-123', { reason: 'manual-kill' });

```

## Session Resumption in Agent Lifecycle Management

The `resumeFlag` in [`src/shared/agentProvider.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/shared/agentProvider.ts) (lines 41–45) enables stateful agent lifecycle management. When a provider supports resumption (e.g., Claude's `--resume` flag), the Hive reuses the previous session ID on respawn:

- Preserves inbox state across restarts
- Maintains cost accounting continuity
- Avoids duplicate initialization overhead

```typescript
// From src/shared/agentProvider.ts
resumeFlag?: string;  // e.g., '--resume' for Claude

```

## Extending Agent Lifecycle Management to Custom Providers

Adding a new provider requires defining a **BridgeDescriptor** in [`src/shared/agentProvider.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/shared/agentProvider.ts):

```typescript
import { AGENT_PROVIDER_PRESETS, BridgeDescriptor } from '../shared/agentProvider';

AGENT_PROVIDER_PRESETS.push({
  id: 'myllm',
  label: 'MyLLM',
  defaultCommand: 'myllm',
  commandGroups: [],
  autoModeFlag: '--auto',
  supportsModel: true,
  modelFlag: '--model',
  hiveAware: false,
  canReceiveInbox: true,
  hookBridge: undefined,
  bridge: {
    kind: 'proxy',
    api: 'openai',
    baseUrlEnv: 'MYLLM_API_URL',
    inboxDelivery: 'terminal',
  },
});

```

With this descriptor, the Hive automatically manages the full agent lifecycle—including spawn, monitor, and archive—without additional provider-specific code.

## Key Files for Agent Lifecycle Management

| File | Role | Lines of Interest |
|------|------|-------------------|
| [`src/main/hive.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/hive.ts) | Core orchestration: spawn, bridge wiring, archive handling | 31–48, 69–86, 96–100 |
| [`src/shared/agentProvider.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/shared/agentProvider.ts) | Provider presets and bridge descriptor logic | 41–45, 58–66 |
| [`src/shared/broadcast.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/shared/broadcast.ts) | Message routing with archived status respect | 40–45 |
| [`src/main/pty.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/pty.ts) | PTY lifecycle and graceful termination | 309–312 |
| [`src/renderer/src/hooks/useHive.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/renderer/src/hooks/useHive.ts) | Renderer-side Hive event subscription | Full file |
| [`src/shared/grokCommands.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/shared/grokCommands.ts) | Example slash commands for lifecycle inspection | Full file |

## Summary

Agent lifecycle management in Munder Difflin implements **harness engineering**: the underlying LLM provides raw capability, while the Hive system guarantees reliable, observable, and safely-terminated agents. Key takeaways:

- **`Hive.ensureAgent()`** in [`src/main/hive.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/hive.ts) is the single entry point for spawning agents with consistent lifecycle hooks
- **`bridgeOf()`** abstracts provider differences through hooks (native) or proxy (synthesized) bridges
- **Three event types** (PreToolUse, PostToolUse, Stop) drive runtime monitoring and graceful termination
- **[`broadcast.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/broadcast.ts)** enforces archive boundaries—archived agents receive no new messages
- **`archiveAgent()`** unifies cleanup across Stop hooks, manual kills, and natural exits
- **Resume support** preserves state and cost accounting for compatible providers

## Frequently Asked Questions

### How does Munder Difflin handle agents from providers without native lifecycle hooks?

For providers lacking native Hive support, the system uses a **proxy bridge** (`kind: 'proxy'` in the BridgeDescriptor). The Hive spins up a loop-back proxy that intercepts API calls and synthesizes PreToolUse, PostToolUse, and Stop events. This allows any OpenAI-compatible API to participate in full agent lifecycle management without provider modifications.

### What happens to messages sent to an archived agent?

Archived agents are permanently excluded from message delivery. The [`broadcast.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/broadcast.ts) module checks agent status before fan-out and skips any agent marked archived in [`registry.json`](https://github.com/chaitanyagiri/munder-difflin/blob/main/registry.json). The inbox is drained during the archive routine, ensuring no queued messages remain. Archived agents remain visible in the UI solely for historical log inspection.

### Can I manually trigger the same archive routine used for graceful stops?

Yes. Call `archiveAgent(agentId, { reason: string })` from [`src/main/hive.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/hive.ts) to manually trigger the archive routine. This writes to `log.jsonl`, updates [`registry.json`](https://github.com/chaitanyagiri/munder-difflin/blob/main/registry.json), and drains the inbox—exactly matching automatic archive behavior from Stop hooks or process termination.