# Ledger System in agent-core-v2: Ordered Lifecycle Management Explained

> Discover the Ledger system in agent-core-v2. Learn how it provides ordered, rollback-capable registry for deterministic resource cleanup and manages disposers effects and child ledgers.

- Repository: [Moonshot AI/kimi-code](https://github.com/MoonshotAI/kimi-code)
- Tags: internals
- Published: 2026-08-13

---

**The Ledger system in agent-core-v2 is an ordered, rollback-capable registry that manages disposers, effects, and nested child ledgers, ensuring deterministic resource cleanup in reverse registration order.**

The Ledger system serves as the foundational lifecycle management primitive in the `agent-core-v2` package of the MoonshotAI/kimi-code repository. Unlike higher-level dependency injection containers, this pure bookkeeping component provides a robust mechanism for tracking resources and guaranteeing their orderly release. It underpins the entire scope lifecycle system through strict serial execution and uninterruptible teardown semantics.

## Core Responsibilities of the Ledger System

### Ordered Bookkeeping and Reverse Teardown

According to the source code in [`packages/agent-core-v2/src/_base/lifecycle/ledger.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/packages/agent-core-v2/src/_base/lifecycle/ledger.ts), the Ledger maintains an ordered registry where every registration—whether a disposer, effect, or child ledger—is stored in insertion order. During teardown, the system walks this list in strict reverse order, ensuring resources are released in the opposite sequence they were acquired. This LIFO (last-in-first-out) approach prevents dependency violations during cleanup.

The class header comments (lines 2-8) document this core responsibility, while the teardown implementation (lines 129-141) handles the reverse iteration logic.

### Uninterruptible Rollback with Error Handling

The Ledger implements a rollback-capable teardown process that remains uninterruptible even when individual disposers fail. If a registered disposer or effect throws an exception, the Ledger catches the error, prefixes it with the entry's label for debugging purposes, and continues processing remaining entries. This serial execution model guarantees that no resource leak occurs due to an early failure in the cleanup chain.

### Nested Scope Management

Through the `createChild()` method (implemented in lines 117-128), the Ledger supports hierarchical scope management. Child ledgers register themselves as entries within their parent, enabling automatic cascading teardown. When the parent Ledger invokes `teardown()`, it recursively triggers cleanup for all child ledgers before proceeding with its own direct registrations, maintaining the reverse-order invariant across the entire hierarchy.

### State Tracking and Safety

The Ledger tracks its current state (`active`, `disposing`, or `disposed`) and enforces strict validity checks. Any attempt to register new entries via `register()` or `effect()` while the Ledger is not in the `active` state throws a `LedgerDisposedError`, as defined in [`packages/agent-core-v2/src/_base/lifecycle/errors.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/packages/agent-core-v2/src/_base/lifecycle/errors.ts). This prevents resource leaks and use-after-dispose bugs in long-running applications.

## Implementation Details from Source Code

The Ledger class implementation spans several key sections in [`packages/agent-core-v2/src/_base/lifecycle/ledger.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/packages/agent-core-v2/src/_base/lifecycle/ledger.ts). The constructor and state management logic appear in the header comments and initial class definition (lines 2-8), while the registration methods are implemented in lines 49-66 for `register()` and lines 75-86 for `effect()`.

The system relies on type definitions from [`packages/agent-core-v2/src/_base/lifecycle/disposer.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/packages/agent-core-v2/src/_base/lifecycle/disposer.ts), which specifies the `Disposer` and `EffectBody` types, along with the `TeardownReason` parameter passed to all cleanup functions.

## Practical Usage Example

The following TypeScript example demonstrates creating a Ledger hierarchy, registering disposers and effects, and executing teardown:

```typescript
import { Ledger } from '#/packages/agent-core-v2/src/_base/lifecycle/ledger';

// 1️⃣ Create a top-level ledger
const root = new Ledger('root-ledger');

// 2️⃣ Register a simple disposer
const entry = root.register(
  (reason) => console.log(`Disposed because ${reason}`),
  'my-disposer'
);

// 3️⃣ Register an effect that returns a disposer
root.effect(() => {
  console.log('Effect started');
  return (reason) => console.log(`Effect cleanup (${reason})`);
}, 'my-effect');

// 4️⃣ Create a child ledger (nested scope)
const child = root.createChild('child-ledger');
child.register(() => console.log('Child cleaned up'), 'child-disposer');

// 5️⃣ Inspect current entries
console.log(root.entries());

/* 6️⃣ Tear down the whole hierarchy.
   Teardown happens in reverse registration order:
   - child ledger → its disposers
   - effect disposer
   - my-disposer
*/
await root.teardown('scope-close');

```

When executed, this code produces deterministic cleanup where the child's disposer runs first, followed by the effect cleanup, and finally the root's `my-disposer`, each receiving the `'scope-close'` reason string.

## Summary

- The **Ledger system in agent-core-v2** provides ordered lifecycle management for resources, ensuring cleanup happens in strict reverse registration order.
- It guarantees **uninterruptible teardown** by catching and logging errors from individual disposers without aborting the rollback process.
- **Nested ledgers** enable hierarchical scope management through automatic parent-child teardown propagation.
- **State validation** via `LedgerDisposedError` prevents operations on inactive or disposed ledgers.
- The implementation in [`packages/agent-core-v2/src/_base/lifecycle/ledger.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/packages/agent-core-v2/src/_base/lifecycle/ledger.ts) operates as a pure primitive without dependency injection concerns, making it reusable across different architectural layers.

## Frequently Asked Questions

### What happens if a disposer throws an error during Ledger teardown?

The Ledger catches the exception, prefixes it with the entry's label for traceability, logs the error, and continues with the next entry in the reverse-order list. This ensures that one failing disposer cannot prevent other resources from being cleaned up, maintaining the uninterruptible nature of the teardown process as implemented in lines 129-141 of [`ledger.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/ledger.ts).

### How does the Ledger system handle nested scopes or child ledgers?

Child ledgers are created via the `createChild()` method (lines 117-128) and automatically register themselves as entries in the parent Ledger. When the parent tears down, it invokes the child's teardown method before processing its own registrations, ensuring that inner scopes release resources before outer scopes, maintaining proper dependency ordering.

### Can you register new disposers after a Ledger has started tearing down?

No. The Ledger tracks its state (`active`, `disposing`, `disposed`) and throws a `LedgerDisposedError` if you attempt to call `register()`, `effect()`, or `createChild()` while the Ledger is not in the `active` state. This safety mechanism, defined in [`packages/agent-core-v2/src/_base/lifecycle/errors.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/packages/agent-core-v2/src/_base/lifecycle/errors.ts), prevents resource leaks and ensures teardown integrity.

### Is the Ledger system tied to dependency injection in agent-core-v2?

No. According to the source code comments in [`ledger.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/ledger.ts), the Ledger is intentionally designed as a pure bookkeeping primitive with no knowledge of dependency injection. Higher-level scopes and DI containers build their behavior on top of the Ledger's foundational lifecycle management capabilities, but the Ledger itself only handles disposer registration and ordered teardown.