Agent Coordinator Boundary
SciDEX should dispatch scientific judgment through agent containers, not through substrate-internal prompt runners. The coordinator contract is the agent-owned surface for that
Source: docs/agent-coordinator.md
Agent Coordinator Boundary
SciDEX should dispatch scientific judgment through agent containers, not through substrate-internal prompt runners. The coordinator contract is the agent-owned surface for that dispatch.
Ownership
-
scidex-substrateowns durable facts:agent_work_packetartifacts, schemas, lifecycle state, auth, links, rankings, bounties, signals, events, and verb APIs. -
scidex-agentsowns agent behavior: persona context, skill selection, provider/runtime choice, budget policy, artifact authoring, review routing, and container execution. -
Prism reads substrate state and logs. It should not need to know whether a packet was acted on by Operon, Claude, Codex, Rosalind, or another harness.
Dispatch Modes
The same request shape supports two execution modes:
-
queued: publish or reuse anagent_work_packetand let eligible runtime containers claim it based on assignee, skills, budget, priority, and current context. -
synchronous: hand a bounded request to a selected agent container and return when the container either writes deliverable refs through substrate APIs or records a blocked/failure state.
Substrate code should not import persona_runner, prompt builders, provider
SDKs, or agent skills to satisfy these modes. It can create packets through
scidex.create, update packet state through lifecycle verbs, or call a future
agent-coordinator HTTP endpoint using this request envelope.
Python Contract
scidex_agents.coordinator exposes the stable dictionary payloads used by
operator tools and future services:
from scidex_agents.coordinator import coordinator_request_from_packet
request = coordinator_request_from_packet(
packet,
run_id="work-selection-20260523T000000Z",
mode="queued",
)
The helper returns ordinary dictionaries and dataclasses only. It has no
substrate Python imports, no database access, and no provider SDK dependency.
Work-selection publication uses the same module to create first-class
agent_work_packet payloads and the temporary open_question fallback.
The same contract can normalize substrate API responses back into runnable requests:
from scidex_agents.coordinator import coordinator_request_from_artifact
request = coordinator_request_from_artifact(
artifact, # agent_work_packet or open_question fallback dict from substrate
mode="synchronous",
timeout_seconds=120,
)
This is the handoff point for claim/review/improvement loops: substrate owns packet lifecycle and ranking, while the agent runtime chooses whether to accept the packet, which skills to load, and how much compute to spend before writing deliverable refs back through substrate verbs.
Implemented Dispatch
The first implemented coordinator dispatch surface is queued dispatch into a selected runtime’s state directory:
from scidex_agents.coordinator import dispatch_coordinator_request
result = dispatch_coordinator_request(
request.to_dict(),
state_root="/home/ubuntu/scidex-agents/state",
)
For mode="queued", this writes or replaces the packet in
state/<assigned_runtime>/work-selection.json using the same runtime-visible
packet shape as runtimectl review work-selection --write-runtime-state.
Replacement is keyed by packet_id, so retries are idempotent and do not
duplicate work.
The equivalent local CLI accepts the JSON envelope on stdin:
python tools/scidex_agent_coordinator.py \
--state-root /home/ubuntu/scidex-agents/state < envelope.json
mode="synchronous" is intentionally explicit rather than fake: the dispatch
result returns status="synchronous_dispatch_not_implemented". The follow-up
executor must run a selected container, collect deliverable refs, usage, and
workspace evidence, then update the packet through substrate APIs.
Lifecycle Updates
Agent runtimes update first-class agent_work_packet artifacts through normal
substrate optimistic-lock updates. The coordinator package provides payload
helpers for the lifecycle states substrate already validates:
from scidex_agents.coordinator import deliver_work_packet_update_payload
payload = deliver_work_packet_update_payload(
artifact, # read from substrate, includes content_hash
actor_ref="persona:kyle",
deliverable_refs=["hypothesis:h-2"],
result_summary="Published a reviewed hypothesis draft.",
)
The helper returns a scidex.update payload with type, id, patch,
base_content_hash, and an idempotency key. It never writes directly. Agents
should read the packet, reason about the next state, send the update through
substrate, and retry on version conflict after re-reading current state.
Migration Rule
When a substrate worker or verb needs judgment, it should:
-
detect the deterministic condition cheaply;
-
create or update an
agent_work_packetwith input refs and acceptance criteria; -
let the agent coordinator choose claim timing, runtime, skills, and budget;
-
require deliverables to be durable SciDEX refs before marking work complete.
This keeps substrate as the fabric and agents as the evolving scientific loop.