Repository navigation
feat: orchestrator core extraction + API hardening - #35
Merged
Merged
Conversation
Add CapabilitySet (uint32 bitmask) with named capability constants and Capabilities() as a required Platform method. Adapters advertise base lifecycle caps; CapOptimize/CapMeasure only when contract.Optimizer is implemented. As[T] generic escape hatch documented in adding-platform.md.
Concrete Orchestrator struct with fallible functional options, loud duplicate-registration errors, capability-driven optimizer dispatch, eventually-consistent List (partial platform failure degrades, not fails) and idempotent lifecycle actions. pkg/orchestrator imports only pkg/contract + stdlib. internal/core deleted.
Single bootstrap.BuildOrchestrator used by serve, mcp, and service modes. pkg/mcp becomes a thin transport over the orchestrator (tool names and schemas unchanged). iOS Platform gains ReconcileProfile so the orchestrator's profile policy can converge devices after wipe and boot.
conformance.RunSuite drives an adapter through the orchestrator (list, state, stop idempotency, capability honesty); wired into ios and android test suites behind SDK detection guards. go-apidiff CI step watches pkg/contract and pkg/orchestrator public API. bench-slim gains an orchestrator-level wipe convergence smoke.
User docs (docs/, hosted): light architecture overview with embed example, agent-setup guide, agentic README pass. Contributor record in .agents/docs/ARCHITECTURE.md (unhosted) per the docs placement rule. CHANGELOG entry for the orchestrator extraction.
The simslim branch left two '## [Unreleased]' headers; merge them into one section with proper Added/Changed grouping.
Add aosp_atd/google_atd image tag support to the Android adapter: config fields (image_tag, api, abi, ram_size, heap_size, auto_provision) with MCPSIM_ANDROID_* env equivalents, config.ini tag detection, ATD launch flags (-no-window -no-audio -no-boot-anim -no-snapshot -gpu swiftshader_indirect -memory), boot-time AVD auto provisioning via sdkmanager/avdmanager, and atd/est_ram_mb annotations on Device. Issue #34 (M2).
Add platforms/redroid implementing contract.Platform over the Docker CLI (docker run redroid/redroid:<ver>_64only, adb connect to the mapped port). Build-tag guarded to linux so macOS builds are unaffected; registration no-ops unless MCPSIM_REDROID_ENABLED is set. Wipe equals container removal (fresh container, fresh data). Documented as WIP and untested, including host kernel binder requirements and the macOS non-viability finding. Issue #34 (M2).
Add a stream_info tool returning scrcpy over TCP guidance for running Android devices (adb tcpip 5555, adb connect, scrcpy --tcpip) and an explicit unsupported response for non running devices. Document the screencap fallback for ATD images and the agent-first rationale for not embedding streaming. Issue #34 (M2).
The MCP server dispatches tool calls concurrently, and get_state or await_ready racing boot_device could mutate the unsynchronized avdPortMap from two goroutines, crashing the process with a fatal concurrent map writes error (caught by the live ATD boot smoke). Serialize all reads and writes with a mutex. Issue #34 (M2).
…WW-Authenticate challenge
boot_device spawned the emulator with exec.CommandContext bound to the HTTP request context, so the emulator was killed as soon as the boot response was flushed and the client disconnected. The AVD boot smoke on a remote host caught it: qemu died right after every boot_device call. Spawn with a detached context (context.WithoutCancel) in Start and in the Wipe restart so the emulator outlives the request. Also stop surfacing raw adb get-state errors from State: a cold adb server or unregistered serial is a stopped device, not a hard error; the old path aborted Boot before Start could run and leaked bare 'exit status 1' messages to tool callers.
get_state never reported the optimizer block: contract.As[Optimizer] asserts the registered Platform itself, but only the internal slimmer type implemented the interface, so the assertion always failed and OptimizerState silently returned nil. Delegate Optimize, Restore, OptimizeStatus and Measure to the slimmer (unsupported error when slim is disabled) so capability gating and the assertion agree. Caught by the mac mini POC after enabling platforms.ios.slim.
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.
Closes #31. Plan:
.agents/plans/2026-09-09-orchestrator-core.md(repo). Decision record:.agents/docs/ARCHITECTURE.md.What
Three-layer pivot: MCP transport (pkg/mcp) <-> Go orchestrator core (pkg/orchestrator) <-> simulator adapters (pkg/contract).
internal/coredeleted.pkg/contract:CapabilitySet(uint32 bitmask) + requiredCapabilities()onPlatform;As[T]escape hatch.Optimizerstays the optional interface, advertised via caps.pkg/orchestrator(new, public): concreteOrchestratorstruct, fallible functional options (WithLogger/WithPlatform/WithController/WithWipePolicy), loud duplicate-registration errors,ShutdownAll(ctx). Imports onlypkg/contract+ stdlib.Wipereturns the device to its configured baseline (erase + re-apply slim profile whenon_bootset) via the iOS adapter's newReconcileProfile;Bootis the universal convergence point.list_devicesskips a failing platform (warn log) instead of failing the whole call; errors only when all platforms fail.bootstrap.BuildOrchestratorfor serve/mcp/service modes;pkg/mcpis a thin transport (tool names + schemas byte-identical, verified via live tools/list).conformance.RunSuitewired into ios (passes vs real simulators) and android (skips w/o SDK); go-apidiff CI onpkg/contract+pkg/orchestrator; bench-slim orchestrator smoke behindMCPSIM_BENCH_TARGET.docs/(light architecture overview + embed example, newagent-setup.md, agentic README pass); contributor decision record in.agents/docs/ARCHITECTURE.md(unhosted). CHANGELOG Unreleased sections deduplicated; version bumped to 0.3.0-dev.Intended behavior deltas
boot_device(running)already_runningerrorstop_device(stopped)not_runningerrorwipe_device(slim + on_boot)list_devices(one platform down)Validation
task validategreen (typecheck + lint + test),task buildok