| name | fabric-rlm |
| description | Recursively decomposes oversized tasks into bounded child Pi agents with fresh context windows. Use for whole-repo audits, massive-context analysis, and multi-file refactors that do not fit one context. |
| disable-model-invocation | true |
Fabric Recursive Decomposition
Use recursion for context size, not mere difficulty. If the relevant material fits one context, work directly. Otherwise pass the root task as strings.task and use one fabric_exec program to size up → orient → delegate bounded chunks → combine.
rlm.query() is agents.run({ runner: "pi", recursive: true }): each child gets a fresh context and may recurse up to subagents.maxDepth. Use plain agent() for leaves that do not need recursion.
await workflow.configure({
name: "Recursive decomposition",
description: "Size up, delegate bounded subtasks, combine",
});
await phase("Orient", { total: 1 });
const scope = await agent<{ paths: string[] }>(
`Identify only the files relevant to this task.\n\nTask:\n${π.task}`,
{
label: "scope",
tools: ["read", "grep", "find", "ls"],
schema: {
type: "object",
properties: { paths: { type: "array", items: { type: "string" } } },
required: ["paths"],
additionalProperties: false,
},
},
);
await phase("Decompose", { total: scope.paths.length });
const findings = await parallel(
scope.paths.map((path) => () =>
rlm.query({
task: `Analyze ${path} for this objective; return concrete evidence.\n\nObjective:\n${π.task}`,
name: `analyze ${path}`.slice(0, 50),
tools: ["read", "grep", "find", "ls"],
}),
),
{ concurrency: 4 },
);
await phase("Combine", { total: 1 });
return agent(
`Deduplicate, reconcile, and synthesize these findings; drop unsupported claims:\n${JSON.stringify(findings)}`,
{ label: "combine", tools: ["read", "grep", "find", "ls"] },
);
Guardrails:
- Size scope before spawning; deeper children should make fewer calls and act more directly.
- Partition edit ownership by path or use
worktree: true; concurrent children must not edit the same files.
subagents.maxDepth bounds each branch. The shared subagents.budgetUsd ledger is a best-effort whole-tree spend guard, not a hard cap; concurrent branches can overshoot its pre-spawn check. maxPerExecution and top-level agentBudget cap calls only in the current process.
budget.remaining() reports the current execution's token budget from completed usage; it does not expose agent-call or USD budget. Concurrent fan-out can overshoot that observation, so dispatch sequentially or in checked batches when the token ceiling matters.
- Initial approval delegates only agent risk; network, execution, and write approvals are not inherited. Redirect a valuable drifting child with
agents.steer rather than discarding its context.