/** * SwarmMemoryBranches — per-agent Copy-On-Write memory branching for swarms. * * ## Why this exists * * The v3.14.4 release uncovered a tarball-bloat regression: the Darwin * git-worktree-per-agent pattern accumulated 3.3 GB of disk because each * agent got a *full copy* of shared state. `agenticow` (a sibling RVF-based * COW vector store by the same author) forks a branch in a measured **162 * bytes** regardless of base size — read-through semantics (parent ∪ edits, * child wins) instead of a linear-growth snapshot. * * This service is the swarm-facing consumer of that primitive. The pattern * mirrors `agenticow`'s own `examples/parallel-agents`: * * shared base .rvf * → each agent forks a 162-byte COW branch (nativeAnn:true) at spawn * → the agent reads/writes its branch in isolation * → on success: promote branch → base (merge its edits back) * → on failure: discard the branch file (throw the edits away) * * ## Honest scope (the seam) * * The current `agent_spawn` MCP path (src/mcp-tools/agent-tools.ts) stores an * agent as pure JSON metadata — it does **not** create, copy, or hold any * per-agent `.rvf` workspace today. So there is no full-copy for a COW branch * to "replace" inline. This service therefore wires in as an **opt-in**: a * swarm/agent that actually wants an isolated memory workspace passes a base * memory path, and only then does a branch get forked. Default behavior is * unchanged. * * ## Non-fatal + kill-switch (ADR-150) * * - `agenticow` is an optional dependency — every method degrades to * `{ degraded: true }` when it is absent (never throws MODULE_NOT_FOUND). * - The `CLAUDE_FLOW_NO_COW_MEMORY=1` env var hard-disables branching so an * operator can kill the feature without a redeploy. * - agenticow is loaded lazily (dynamic import inside `loadAgenticow`), so * importing this module does NOT pull agenticow onto the CLI startup path. * * @module @claude-flow/cli/services/swarm-memory-branches */ /** Env var that hard-disables per-agent COW branching (operator kill switch). */ export declare const COW_KILL_SWITCH_ENV = "CLAUDE_FLOW_NO_COW_MEMORY"; /** True unless the operator set the kill switch. */ export declare function cowMemoryEnabled(): boolean; /** Persisted mapping so promote/discard (a later, separate call) can find the branch. */ export interface BranchRecord { agentId: string; basePath: string; branchPath: string; label: string; createdAt: string; } export interface BranchResult { success: boolean; agentId: string; basePath?: string; branchPath?: string; label?: string; /** Set when the operation was a no-op because COW is unavailable/disabled. */ degraded?: true; reason?: string; } export interface PromoteResult { success: boolean; agentId: string; promoted: boolean; branchPath?: string; basePath?: string; degraded?: true; reason?: string; } export interface DiscardResult { success: boolean; agentId: string; discarded: boolean; branchPath?: string; reason?: string; } /** * Manages the branch→base COW lifecycle for a swarm's agents. One instance per * project cwd; state is persisted to `.claude-flow/swarm/cow-branches.json` so * a branch forked in `branchForAgent` survives to a later `promoteAgent` / * `discardAgent` call in a different process. */ export declare class SwarmMemoryBranches { private readonly registryPath; /** * @param registryPath Override the registry location (tests point this at a * temp dir). Defaults to `/.claude-flow/swarm/cow-branches.json`. */ constructor(registryPath?: string); private loadRegistry; private saveRegistry; /** Look up the branch record for an agent, if one was forked. */ getBranch(agentId: string): BranchRecord | undefined; /** * Deterministic per-agent branch path: `/.swarm-cow/..rvf`. * Keeps branch files namespaced next to their base so cleanup is obvious. */ private branchPathFor; /** * Fork a 162-byte COW branch off `base` for `agentId`. The agent then owns * an isolated read/write view (parent ∪ its own edits). Idempotent: a second * call for the same agent returns the existing branch record. * * @param base Path to the shared base `.rvf` (absolute or cwd-relative). * @param agentId Agent that owns the branch (used as the COW label). * @param opts.dimension Required only when `base` does not yet exist. * @param opts.nativeAnn Fork with the native Rust ANN path (default true — * agent branches are meant to be queried). */ branchForAgent(base: string, agentId: string, opts?: { dimension?: number; nativeAnn?: boolean; }): Promise; /** * Promote an agent's branch back into its base (merge its edits + tombstones * atomically), then delete the branch file and drop it from the registry. * Call on agent success. No-op (`promoted:false`) when the agent has no * branch. */ promoteAgent(agentId: string): Promise; /** * Discard an agent's branch — delete the branch file + lineage manifest and * drop the registry entry, WITHOUT merging anything into base. Call on agent * failure. No-op (`discarded:false`) when the agent has no branch. Never * touches agenticow (pure filesystem), so it works even in the degraded path. */ discardAgent(agentId: string): Promise; private removeBranchFiles; private forgetBranch; } //# sourceMappingURL=swarm-memory-branches.d.ts.map