Consolidate Synth Index SDK, MCP, Swarms, and Intern - #387
Draft
JoshuaPurtell wants to merge 40 commits into
Draft
JoshuaPurtell wants to merge 40 commits into
JoshuaPurtell wants to merge 40 commits into
Conversation
…; 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.
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.
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:
Intentional supersessions:
Current head: af06418.
Verification:
Final local-slot, staging and production evidence must be regenerated against the final backend and SDK heads before release.