feat: Phase 48 β Multi-Agent Orchestration (v4.0.0-alpha.8) - #56
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements Phase 48 β Multi-Agent Orchestration (
ARCHITECTURE_V4.mdΒ§62), the natural successor of Phase 47 (sandboxed tool execution). One
top-level orchestrating reasoning process now delegates independent
sub-tasks to multiple parallel sandboxed tool-execution sub-chains
(each governed entirely by Phase 47's boundaries), then merges their
results back into its own context via the existing
ToolResultingestion path applied recursively.
Bumps the workspace version from
4.0.0-alpha.7to4.0.0-alpha.8,matching the
ROADMAP_V4.mdmilestone (git tag v4.0.0-alpha.8).What's new
crates/aarambh-studio-agent/src/orchestrator.rs(new file, ~1100 lines)Public API:
Orchestratorβ built once from operator-setOrchestrationLimitsand the orchestrator's own
AuthorizationScope.DelegationPlan+DelegatedSubTaskβ the model/operator-authoredplan, validated before any sub-chain runs.
SubChainOutcome+SubChainStatusβ one outcome per sub-task, inplan order, always present (never missing, never malformed).
OrchestrationLimitsβ operator-set, non-model-influenceableceilings:
max_sub_agents(default 4, range 1..=64) andmax_total_time_ms(default 30,000).Each sub-chain is a
ToolChainbacked by aSandboxedToolProviderconstructed with the sub-task's narrowed
AuthorizationScope(viaAuthorizationScope::intersect), so execution plugs into the existingchain with zero chain changes β sub-chain outputs re-enter the
orchestrator's own context via the unchanged
result_ingestionpath,applied recursively.
Three hard, non-negotiable bounds
Enforced as operator-set configuration, never as something the
orchestrator's own output can influence. Verified at
validate_plantime, before any sub-chain runs:
DelegationPlanwith more sub-tasksthan
max_sub_agentsis rejected. The model cannot requestunbounded fan-out by emitting a larger plan. Range 1..=64 matches
the per-chain
max_stepsceiling so an orchestrator cannot fan outwider than a single chain could step.
sub-chains, not per sub-chain, so many small sub-agents cannot
collectively exceed the same ceiling one large one would hit. Once
exhausted, every not-yet-started sub-task is refused with
SubChainStatus::BudgetExceeded.AuthorizationScopemay only be a subset of its orchestrator's. Verified by
parent.intersect(&child) == child(true iffchild β parent).Additionally, every tool name a sub-task declares must be
is_authorizedin that sub-task's own scope. Orchestration cannever be used as an escalation path to reach tools the operator
did not explicitly enable at the top level.
Failure isolation
One sub-agent's failure or execution error is contained to that
sub-chain's own outcome β it does not corrupt or silently swallow
sibling sub-agents' results. Each sub-chain runs inside a
std::panic::catch_unwindboundary; panics becomeSubChainStatus::Failedwith the panic payload rendered into thefail-closed
ToolResult::errortext. The orchestrator's aggregationstep receives an explicit failure marker for that sub-chain rather than
a missing or malformed entry.
CLI surface (
aarambh-studio/src/cmd/agent.rs)Five new opt-in flags on the
agentcommand:--orchestrate--delegation-plan <PATH>--orchestrate)DelegationPlan--max-sub-agents N--max-orchestration-budget-ms MS--sub-agent-allow-tool <NAME>--allow-tool)When
--orchestrateis absent, the command behaves exactly as inPhase 47 β zero behavior change for non-orchestrating use.
Tests
crates/aarambh-studio-agent/src/orchestrator.rs(5 roadmap-namedacceptance tests + 5 supporting tests), all using a
FakeDecodermirroring
chain.rs::tests::FakeDecoderandsandbox.rs::tests::FakeDecoderso they run in milliseconds:orchestrator_cannot_exceed_configured_max_sub_agent_countorchestrator_cannot_exceed_configured_total_execution_time_budgetsub_agent_sandbox_scope_is_never_wider_than_orchestrator_authorizationresult_aggregation_correctly_merges_multiple_sub_chain_outputsone_sub_agent_failure_does_not_silently_corrupt_sibling_sub_agent_resultslimits_validation_rejects_zero_ceilingsvalidate_plan_rejects_subtask_declaring_unauthorized_toolintersect_equals_child_when_child_is_subsetrun_revalidates_plan_defense_in_depthorchestrator_sub_chain_can_execute_tools_through_sandboxregressions.
scripts/phase48_smoke.shβ runs the orchestrator unit tests,verifies
agent --helpsurfaces the new flags, verifies--orchestrateerrors on missing--delegation-planand missing--allow-tool, verifies a plan exceeding--max-sub-agentsisrejected at validation time before any model is loaded, and writes a
scorecard to
artifacts/phase48_orchestration_smoke.json.CI gates β all green
cargo fmt --all --checkβcargo check --workspace --all-targets --lockedβcargo test --locked -p aarambh-studio-agent --libβ (32 passed)cargo clippy --workspace --all-targets --locked -- -D warnings -D clippy::undocumented_unsafe_blocksβRUSTDOCFLAGS="-D warnings -D missing_docs" cargo doc --workspace --no-deps --lockedβscripts/phase47_smoke.shβ (regression)scripts/phase48_smoke.shβ (new)Files changed
New files:
crates/aarambh-studio-agent/src/orchestrator.rs(~1100 lines, the implementation + 10 tests)docs/phase48_orchestration.md(319-line runbook mirroringdocs/phase47_sandbox.md)scripts/phase48_smoke.sh(smoke script mirroringscripts/phase47_smoke.sh)configs/orchestration_smoke.json(two-sub-task plan fixture)data/sandbox_workdir/notes.txt(sandbox fixture file)data/tools_sandbox_smoke.json(tool definitions referenced by both Phase 47 and Phase 48 smoke scripts)PHASE48_PLAN.md(the implementation plan document)Modified files (strictly additive):
Cargo.tomlβ workspace version4.0.0-alpha.7 β 4.0.0-alpha.8Cargo.lockβ updated to matchcrates/aarambh-studio-agent/src/lib.rsβ onepub mod orchestrator;line + re-exports + module docstringcrates/aarambh-studio-agent/src/chain.rsβ addedserde::Serialize, serde::Deserializederive toToolChainConfig(needed soDelegatedSubTaskcan round-trip through JSON)aarambh-studio/src/cmd/agent.rsβ added 5--orchestrateflags,run_orchestrate()function,SubChainSharedstruct,build_sub_chain_decoder()helper,validate_orchestration_config(),print_orchestration_outcomes()README.mdβ Phase 48 in intro paragraph, docs index, current boundaries, citation versionROADMAP_V4.mdβ "Status: shipped in v4.0.0-alpha.8" blockquote on the Phase 48 sectionARCHITECTURE_V4.mdβ "Implemented in v4.0.0-alpha.8" note on Β§62CHANGELOG.mdβ full## [4.0.0-alpha.8]entryHonesty boundary
Sub-chains run sequentially by default (CPU-first honest default).
The spec's wording β "Sub-chains run (conceptually parallel; actual
concurrency bounded by configured limits below)" β is honored:
max_sub_agentsandmax_total_time_mstogether bound the total workeven when run sequentially. True parallelism would require a
ChainDecoderwhose implementor isSend + Sync, which is out ofscope for the source release because the
InferenceEngineholds aCandle device that is not safely cloneable across threads. The CLI's
per-sub-task decoder factory rebuilds a fresh
InferenceEnginepersub-chain so each sub-chain owns its own
&mutdecoder. This isdocumented in the orchestrator module docs, the runbook, the
CHANGELOG, and the ARCHITECTURE_V4.md note.
No new crate. No new dependency. No new ingestion mechanism.
Orchestration is purely additive to what Phase 47 built.