Skip to content

Consolidate Synth Index SDK, MCP, Swarms, and Intern - #387

Draft
JoshuaPurtell wants to merge 40 commits into
mainfrom
codex/swarms-intern-index-consolidated-20260914
Draft

JoshuaPurtell wants to merge 40 commits into
mainfrom
codex/swarms-intern-index-consolidated-20260914

Conversation

@JoshuaPurtell

@JoshuaPurtell JoshuaPurtell commented Sep 14, 2026

Copy link
Copy Markdown
Collaborator

Combines the Synth Index SDK and MCP contract with Workshop v0.11, OpenRouter, Async/Sync Intern, Swarms, and the final backend Research OpenAPI.

Included remote lines:

  • Synth Index public/private clients and MCP upload/search surfaces;
  • current Async Intern phases, stop/resume vocabulary, memory, handoff, presence and approvals;
  • Workshop v0.11 and Dock/OpenRouter model contracts;
  • the reviewed typed Container Pools SDK, Harbor/arbitrary build-context packaging, phase-log follow-up, and current project-bound deployment mutation/reconciliation routes shared by Workshop, Intern, swarms and direct callers.

Intentional supersessions:

  • the older standalone project_files module is replaced by the current session/files and bound Project files surfaces;
  • legacy Intern sessions remain retired;
  • public helpers do not hard-code an internal compute provider.

Current head: af06418.

Verification:

  • full SDK suite: 213 passed;
  • central backend/SDK contract slice at the exact pins: 436 passed, 6 skipped;
  • ruff and ty pass;
  • hosted README, docs, lint, tests and type checks passed on the preceding head and are rerunning for this head.

Final local-slot, staging and production evidence must be regenerated against the final backend and SDK heads before release.

JoshuaPurtell and others added 30 commits September 11, 2026 10:45
…; add Intern contract lockstep

Grok 4.3 is removed from the actor-policy enums, agent-model constants and
swarm contracts; the Standard and Heavy presets now name
openrouter/openai/gpt-5.6-luna. This is a breaking enum change for callers that
pinned x-ai/grok-4.3.

openapi/research-v1.json is re-exported from backend rc1 (resource
settlement fields). The Intern contract lockstep test is ported from the
async-24-7 branch so SDK mirrors fail loudly when the backend contract drifts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvS6DjNGSe3a3BrHRxhK5K
…or SDK-only acceptance

- UsageAPI.get_run_resource_settlement / client.get_run_resource_settlement:
  fresh settlement read, strict mirror of RunResourceSettlementResponse.
- UsageAPI.get_intern_sync_session_usage / get_intern_async_assignment_usage:
  typed Intern usage receipt (billing state, launched run ids).
- ManagedResearchRun carries origin_runtime_kind/origin_runtime_id;
  list_runs accepts both as a filter.
- openapi/research-v1.json re-exported from backend rc1.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvS6DjNGSe3a3BrHRxhK5K
…and session usage

The E01 journey no longer needs the advanced session:
- client.research.swarms.list(project, origin_runtime_kind=, origin_runtime_id=)
  lists the swarms one Intern runtime launched; Swarm carries the origin.
- client.research.swarms.resource_settlement(swarm_id) reads settlement fresh.
- client.research.intern.sync_.usage(session_id) returns the typed usage receipt
  and refuses a receipt for another session.
The three new operations are registered in RESEARCH_OPERATIONS.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvS6DjNGSe3a3BrHRxhK5K
…nched

Typed SwarmRollout mirror of the backend SwarmRolloutPage; refuses a page for
another swarm or a rollout whose budget parent drifted. list_swarm_rollouts is
registered and openapi/research-v1.json is re-exported from backend 7372b6f3e.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvS6DjNGSe3a3BrHRxhK5K
Found live on slot3 (rc1): retrieve_swarm_evidence raised
"fields drifted: extra=['tool_calls']" because the backend's
SmrSwarmEvidenceResponse now carries durable run-scoped MCP invocation
outcomes. SwarmEvidence.tool_calls is a typed tuple of SwarmToolCallEvidence
(arguments as a digest only), parsed with the same exact-field drift check.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvS6DjNGSe3a3BrHRxhK5K
SmrSwarmEvidenceFreshnessResponse carries tool_call_count (default 0), and
the SDK's exact-field freshness parser refused it ("swarm evidence
freshness fields drifted: extra=['tool_call_count']"), so
research.swarms.evidence() raised for every swarm. Found live on slot3,
rc1 E01 attempt 8. The count is accepted when present and defaults to 0
when an older backend omits it; any other freshness drift is still
refused. The tool_calls test no longer skips on a freshness mismatch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvS6DjNGSe3a3BrHRxhK5K
…essions

Since 2026-07-26 SmrSwarmTokenUsageResponse carries unattributed_sessions
(non-negative int, default 0, never null, at most sessions_seen), and the
SDK's exact-field token-usage parser refused it ("swarm token usage fields
drifted: extra=['unattributed_sessions']"), so research.swarms.usage()
raised for every swarm. The count is typed on TokenUsage, accepted when
present, defaults to 0 when an older backend omits it, and round-trips
through to_wire; any other token-usage drift is still refused.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvS6DjNGSe3a3BrHRxhK5K
Owner decision (2026-09-12): the backend no longer carries an xAI provider,
x-ai/grok-build, or cursor/grok-4.5. Drop them from SmrAgentModel,
ActorModel/DeprecatedActorModel, the ResourceProvider / credential /
inference provider enums, the public provider selection (SDK + MCP schema),
the actor model policy data, and schemas/public_models.json. Re-vendor
openapi/research-v1.json from the backend export.

Breaking enum change, accepted for Grok removal.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvS6DjNGSe3a3BrHRxhK5K
Mirrors backend packages/intern/resource_inventory.py for both transports:
retained disposition, cleanup_owner, epoch, creator_set, profile,
disposition_complete and per-epoch stop effects. from_wire rejects a
cleanup-complete report on incomplete coverage. Vendored research-v1.json
is the backend export (byte-identical); inventory mirrors now have their
own lockstep test against it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvS6DjNGSe3a3BrHRxhK5K
… artifacts

SwarmRollout now carries logical_intent (explicit/derived, scope,
accepted_submissions), execution (executor launch record with an always-stated
lease plus lease_disposition, executed image/source digests, image_attestation,
Harbor launches) and rollout artifacts. Legacy rows decode as unknown (None).
Malformed or inconsistent provenance is refused. AsyncSwarmsAPI gains
rollouts() so both transports read the chain. Vendored research-v1.json is
byte-identical to backend research_openapi.json, regenerated by
scripts/validate_smr_openapi.py --write.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvS6DjNGSe3a3BrHRxhK5K
Swarm rollouts whose logical intent is scoped to an Intern delegation (shared
across every swarm the Intern triggered for one evaluation) now decode.
Vendored research-v1.json regenerated from backend; byte-identical.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvS6DjNGSe3a3BrHRxhK5K
InternResourceStopEffect.effect adds stopped, already_terminal,
stop_accepted and stop_failed, the recorded outcome of the backend's
service-authority stop of runs fenced by work cancellation. Vendored
research-v1.json is the byte-identical backend export.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvS6DjNGSe3a3BrHRxhK5K
InternRuntimeResourceEpoch.cleanup_settled_at is null while the backend
re-drive pass is still converging the epoch and set once its scope and
every fenced run stop settled. Vendored research-v1.json is the
byte-identical backend export.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvS6DjNGSe3a3BrHRxhK5K
Lockstep with backend claude/workshop-v011-swarmfix: TranscriptReplayMode
and TranscriptProjectionAuthority gain durable_replay
(smr_transcript_events.durable_replay.v1). The backend now replays durable
transcript rows for terminal runs and for live runs whose Redis stream was
trimmed, instead of serving an empty live tail. Vendored
openapi/research-v1.json regenerated from backend research_openapi.json.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvS6DjNGSe3a3BrHRxhK5K
Lockstep with backend claude/workshop-v011-swarmfix: accepted worker
completion claims are projected into the durable transcript as
task.completion_claimed (payload schema smr.task-completion-claimed.v1).
TaskCompletionClaimedEvent.from_transcript_event gives verifiers the
participant_id (worker actor key), claim text, claim_id, task_key and the
durable event/turn ids. Vendored research-v1.json regenerated.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvS6DjNGSe3a3BrHRxhK5K
Local slots route Luna through OpenRouter (openrouter/openai/gpt-5.6-luna), the
model the backend runbook presets and launch capabilities already select. The
SDK's closed model enums rejected it, so a Dock swarm could not bind its roles
to the local route. Adds the value to SmrAgentModel and ActiveActorModel only;
no other behaviour changes. The same two pre-existing
test_intern_usage_reads failures occur on 9016707.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvS6DjNGSe3a3BrHRxhK5K
0.18 removed `sdk.pools` with no successor, so there has been no typed way to
deploy a container to a pool. `evals/containers/nonsensitive/common/pool_runner.py`
still imports the deleted client, and `codex_harbor_runner.py` carries a
hand-rolled module loader specifically to avoid pulling it in.

Reached as `SynthClient().research.container_pools`. Deliberately nested under
research rather than restored at the top level: 0.18's stance is that
SynthClient is a Research SDK, and nesting also disambiguates it from the
existing `client.image_releases`, which is the SMR actor runtime surface at
`/smr/v1/image-releases` -- a different object from a pool's runtime image
release.

Three things this surface makes explicit, because each one fails late:

- The deployment primitive is the runtime image release, not the pool. A pool
  holds tasks; binding a release to a task builds and attaches the snapshot.
  Several tasks may bind one release, which is what makes a taskset cost one
  build.
- `create_harbor_release` packages a bundle and refuses to upload one that
  cannot deploy: a Dockerfile reaching outside its own directory (the pool
  build context is the Dockerfile's directory, not the bundle root), or a
  credential-shaped file that would ship into an image and into S3.
- `wait_for_rollout` raises rather than returning a non-terminal rollout, so a
  timeout is never mistaken for a failed run.

Operations live in their own registry, not RESEARCH_OPERATIONS: the drift gate
in testing/scripts/check_research_openapi_contract.py requires that registry to
exactly equal openapi/research-v1.json, and pools are a different API. The
backend does not yet publish a curated pools contract to vendor, so this
registry is currently ungated -- noted rather than hidden.

Async peers are not included; sync is what the eval lane needs first.
…y contexts

Three gaps found while packaging the two real containers we deploy.

ARG expansion. The context check compared raw COPY sources, so
`COPY vendor/tasks/${GAMEBENCH_TASK} ...` was reported as unresolvable even
though the path exists. Build args are not plumbed through the pool build path
-- `do_build` takes a Dockerfile and a context, nothing else -- so a
Dockerfile's ARG *defaults* are exactly what the image is built with, and
substituting them validates the paths the build really resolves. A source
referencing a variable with no default is skipped rather than guessed at.

.dockerignore. The backend never sees one: the archive the client uploads IS
the context. For the Craftax gold service that is the difference between
fitting the archive cap and not -- its context is 169 MB with `target/` and
2.56 MiB without, and the ignore file that excludes it lives next to the
Dockerfile where only the client can read it. Matching follows BuildKit's
preference for `<dockerfile>.dockerignore` over a context-root `.dockerignore`,
and is deliberately conservative: a pattern this does not understand means a
file is included, so the failure mode is a larger archive, never a missing file.

build_docker_context_archive. Harbor bundles are not the only thing we deploy.
An arbitrary container -- the Craftax gold service -- serves the Synth HTTP
contract and has no task.toml, instruction, or tests, so it could not be
packaged at all. It shares the exclusion, ignore, and credential rules.

Verified against both: the DEO bundle packages to 4.43 MiB / 579 files, and the
Craftax context to 2.56 MiB with 1776 files excluded.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant