Where Is Interactive Runtime State Stored in Apache Maka?
Apache Maka stores interactive runtime state in a dedicated user-private storage root under the system cache directory, managed by the @maka/storage package through marker files, unique root IDs, and file-based locking.
The interactive runtime state in Apache Maka persists data like command history, tool outputs, and invocation traces across sessions. Unlike transient memory, this state survives process restarts and is scoped to specific workspaces. The storage system in apache/maka implements a robust, platform-aware directory structure with guaranteed exclusive access during writes.
How the Storage Root System Works
Apache Maka uses a storage-root abstraction to organize runtime data. Every storage root has a kind, a canonical path, and a durable identifier. For interactive sessions, this kind is explicitly set to 'interactive'.
Root Kind Identification
The StorageRootKind type distinguishes between different storage purposes. Interactive state uses the literal value 'interactive' as defined in packages/storage/src/root-authority.ts:
// lines 36-38
export type StorageRootKind = 'interactive' | 'workspace' | 'global';
const INTERACTIVE_KIND: StorageRootKind = 'interactive';
This kind value determines where files are placed and which locking semantics apply.
Resolving a Storage Root
The entry point for accessing interactive state is resolveStorageRoot() in packages/storage/src/root-authority.ts (lines 10-16). This function:
- Verifies or creates a storage-root directory at the specified path
- Writes a marker file
.maka-storage-root.jsoncontaining metadata - Returns a
StorageRootCapabilitywith the canonical path androotId
import { resolveStorageRoot } from '@maka/storage';
const capability = await resolveStorageRoot({
path: '/absolute/path/to/my-workspace',
kind: 'interactive',
});
// capability.rootId: durable UUID for this root
// capability.path: verified absolute path
The rootId is a stable identifier that survives directory moves and renames because it's stored in the marker file, not derived from the path.
Control Namespace: The Actual Storage Location
While the storage root has a logical path, the interactive runtime state files live in a separate control namespace directory. This separation keeps user data clean while allowing Maka to manage its own metadata.
Platform-Specific Cache Directories
The function resolveRootControlNamespace() (lines 39-52 in root-authority.ts) returns the base control directory:
export function resolveRootControlNamespace(): string {
// Linux → $HOME/.cache/maka/runtime-hosts
// macOS → $HOME/Library/Caches/Maka/runtime-hosts
// Windows → $HOME/AppData/Local/Maka/runtime-hosts
}
Each interactive root receives a private subdirectory named by its rootId:
$CONTROL_ROOT/
<rootId>/
usage.db # SQLite database for interaction traces
events.jsonl # Append-only runtime event log
snapshots/ # Periodic state snapshots
<rootId>.lock # Exclusive access lock file
Persisted Data Types
The control directory contains multiple store types. The usage-stores implementation in packages/storage/src/usage-stores.ts (lines 146-156) creates SQLite databases and JSON files under this root for:
- Command invocation history
- Tool input/output streams
- Performance metrics
- Error traces
Locking and Exclusive Access
Interactive state requires exclusive write access to prevent corruption from concurrent processes. The storage system implements advisory locking through three mechanisms in packages/storage/src/root-authority.ts:
| Function | Lines | Purpose |
|---|---|---|
tryAcquireInteractiveRootOwner |
90-94 | Attempt to become exclusive owner |
runWithStorageRootLease |
127-136 | Execute operation with guaranteed lease |
acquireStateRootLock |
804-810 | Low-level lock file implementation |
Complete Workflow Example
import {
resolveStorageRoot,
tryAcquireInteractiveRootOwner,
runWithStorageRootLease
} from '@maka/storage';
// 1. Resolve the interactive storage root
const capability = await resolveStorageRoot({
path: '/home/user/projects/my-app',
kind: 'interactive',
});
// 2. Acquire exclusive ownership
const owner = await tryAcquireInteractiveRootOwner(capability);
if (!owner) {
throw new Error('Another Maka process holds the interactive lock');
}
// 3. Perform stateful operations with automatic cleanup
await runWithStorageRootLease(
owner.lease,
'interactive',
'write',
async (rootPath) => {
// rootPath resolves to:
// $HOME/.cache/maka/runtime-hosts/<rootId>
const usageDbPath = `${rootPath}/usage.db`;
// Open database, append interaction record, etc.
}
);
The lease automatically releases the lock when the operation completes or throws, preventing deadlocks.
On-Disk Layout Summary
For a workspace at /home/user/projects/my-app with rootId = 'abc-123-def':
| Location | Contents |
|---|---|
/home/user/projects/my-app/.maka-storage-root.json |
Marker file with rootId and metadata |
$HOME/.cache/maka/runtime-hosts/abc-123-def/ |
Interactive runtime state directory |
$HOME/.cache/maka/runtime-hosts/abc-123-def.lock |
Active lock file (present when owned) |
This two-level structure (marker in workspace, data in cache) enables workspace portability while keeping runtime data centralized and cleanable.
Key Source Files
The implementation spans these files in the apache/maka repository:
packages/storage/src/root-authority.ts— Core API for storage root lifecycle, marker management, and lockingpackages/storage/src/usage-stores.ts— Concrete store implementations that persist interaction datapackages/core/src/runtime-event.ts— Event definitions written into interactive storage
Summary
- Interactive runtime state is stored in a platform-specific cache directory returned by
resolveRootControlNamespace() - Each workspace gets a unique
rootIdstored in a local marker file (.maka-storage-root.json) - Actual data files reside under
<control-root>/<rootId>/including SQLite databases and JSON logs - Exclusive access is enforced through file-based locks acquired via
tryAcquireInteractiveRootOwner() - The
@maka/storagepackage providesresolveStorageRoot(),runWithStorageRootLease(), and related functions for safe, concurrent access
Frequently Asked Questions
What happens if multiple Maka processes access the same workspace?
Only one process can hold the interactive lock at a time. Subsequent calls to tryAcquireInteractiveRootOwner() return null until the lock is released. Processes should either wait with exponential backoff or operate in read-only mode using runWithStorageRootLease with 'read' access.
Can I relocate or delete the interactive state manually?
Yes. Deleting the control directory ($HOME/.cache/maka/runtime-hosts/<rootId>) removes all runtime history for that workspace. The next resolveStorageRoot() call will create fresh state. Deleting the marker file (.maka-storage-root.json) causes Maka to generate a new rootId, effectively orphaning the old control directory.
How does Maka handle platform differences for the cache directory?
The resolveRootControlNamespace() function follows XDG Base Directory specifications on Linux, Library/Caches/ conventions on macOS, and AppData/Local/ on Windows. This ensures state persists appropriately across platform standards while remaining user-accessible for debugging or cleanup.
Is the interactive state encrypted or protected from other users?
The control directory inherits standard filesystem permissions from the parent cache directory (typically 0700 on Unix systems). Maka does not currently implement application-level encryption for interactive runtime state; protection relies on operating system file permissions.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →