Skip to content

Feat: Sync SDK with v2 Platform API + route-drift guard#1

Merged
jlsajfj merged 5 commits into
mainfrom
feat/v2-api-sync
Jun 22, 2026
Merged

Feat: Sync SDK with v2 Platform API + route-drift guard#1
jlsajfj merged 5 commits into
mainfrom
feat/v2-api-sync

Conversation

@jlsajfj

@jlsajfj jlsajfj commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Why

The SDK had drifted from the backend /v2 surface (compute/pkg/platform/v2/routes.go, 26 routes). Most urgently, the backend renamed the sandbox path /v2/sandboxes → /v2/sandcastles with no alias, so every sandbox.* call was 404ing. This PR restores 26/26 coverage and adds a guard so this can't silently recur.

Grounded against the live backend handlers (routes.go, connector.go, sandbox.go), not guessed.

Changes

P0 — sandbox path fix (was actively broken)

  • All 6 sandbox calls now hit /v2/sandcastles. Verified live against staging.textql.com (full start→status→execute→query→stop lifecycle passes).

P1 — sandbox additions

  • list(status, limit, cursor), executions(sandbox_id, limit, cursor) (cursor-paginated).
  • Optional sandbox_id on start (restart a specific sandbox).
  • query gains tql_path (run a saved library .tql), params, max_rows; enforces exactly-one-of query/tql_path client-side.

P1 — connector write APIs

  • types, create, test, update, delete. config is passed through as proto-JSON (the backend body is a polymorphic, strict-unmarshaled proto; connectors.types() is self-describing for per-type fields). connectors.test returning 200 {success:false} is not raised as an error.

P2 — release hygiene

  • 2.0.0 → 2.1.0; CHANGELOG entry plus a backfilled 2.0.0 entry (the changelog had skipped it).

Drift prevention (SDK half of Tier 1)

  • # v2:covers METHOD /path comment on all 26 methods (mirrors the backend's own // v2:covers idiom).
  • tests/test_route_coverage.py asserts SDK coverage == vendored tests/routes.manifest.json, which is byte-identical to the canonical manifest produced by the backend's TestRouteManifest golden test.
  • .github/workflows/route-sync.yml (scheduled) opens a PR when the backend manifest drifts → that PR fails coverage until the new method + # v2:covers is added.

Companion backend PR

The canonical routes.manifest.json + its TestRouteManifest golden test land in demo2 (compute/pkg/platform/v2/). Together they close the loop: backend route change → manifest diff → SDK sync PR.

Follow-up (not blocking)

After the backend PR merges, set repo var BACKEND_MANIFEST_URL (raw URL of the canonical manifest) + secret BACKEND_REPO_TOKEN if private. Until then route-sync no-ops safely.

Verification

  • ruff check / ruff format --check: clean
  • pyright (strict): 0 errors
  • pytest (incl. live staging): 35 passed
  • Drift guard negative-tested: catches both missing (backend adds a route) and stale (SDK keeps a removed route) directions.

🤖 Generated with Claude Code

jlsajfj and others added 4 commits June 18, 2026 15:53
Brings the SDK back in line with compute/pkg/platform/v2/routes.go (26 routes):

- Fix sandbox resource path /v2/sandboxes -> /v2/sandcastles (the backend
  renamed it with no alias; every sandbox call was 404ing). Verified live
  against staging.
- Sandbox: add list/executions (cursor-paginated), optional sandbox_id on
  start, and tql_path/params/max_rows on query (exactly-one-of guard).
- Connectors: add types/create/test/update/delete (config passed through as
  proto-JSON; types() is self-describing).
- Bump 2.0.0 -> 2.1.0; CHANGELOG entry + backfilled 2.0.0 entry.

Drift prevention (SDK half of Tier 1):
- # v2:covers comment on all 26 methods + tests/test_route_coverage.py asserting
  SDK coverage == vendored tests/routes.manifest.json (byte-identical to the
  canonical manifest generated by the backend's TestRouteManifest golden test).
- Scheduled route-sync workflow opens a PR when the backend manifest drifts.
- respx unit tests for sandbox + connectors; live-staging coverage for the new
  read endpoints.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
raw.githubusercontent.com + a PAT bearer header is unreliable for private
repos. Use `gh api .../contents/...` with Accept: application/vnd.github.raw,
which authenticates with BACKEND_REPO_TOKEN. Repo/path/ref are overridable via
repo vars (default TextQLLabs/demo2). Copy the canonical file verbatim instead
of re-serializing, so the vendored copy stays byte-identical.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A single App credential covers both halves: read the private backend manifest
and open a PR here that actually triggers CI (default GITHUB_TOKEN PRs don't run
checks, so the drift guard would never go red). Mint the installation token
in-workflow via actions/create-github-app-token scoped to both repos; job
no-ops until SYNC_APP_ID + SYNC_APP_PRIVATE_KEY are set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cross-repo credentials must be minted in the UI (gh can't create an App or a
PAT), so support the lighter option too: resolve the token from a GitHub App
(SYNC_APP_ID) when present, else fall back to a fine-grained PAT secret
(BACKEND_REPO_TOKEN). Either triggers CI on the auto-PR; job no-ops with
neither. Token is masked before use.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jlsajfj jlsajfj marked this pull request as draft June 18, 2026 20:29
demo2 main builds to staging; prod is the `release` branch. The SDK defaults to
app.textql.com (prod), so syncing against main would advertise routes before
prod serves them — the lead/lag break this guard exists to prevent. Default
MANIFEST_REF to `release` and soft-skip when the manifest isn't on that ref yet
(bootstrap), failing loudly only on real fetch errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jlsajfj jlsajfj marked this pull request as ready for review June 22, 2026 15:45
@jlsajfj jlsajfj merged commit 38a62fc into main Jun 22, 2026
11 checks passed
@jlsajfj jlsajfj deleted the feat/v2-api-sync branch June 22, 2026 15:46
jlsajfj added a commit that referenced this pull request Jun 22, 2026
…#2)

* Feat: Add models + sandbox file/exec/library routes (33/33 with prod)

Bundle the 7 routes prod gained after PR #1 so 2.1.0 ships in full sync:
- Models resource: list (GET /v2/models)
- Sandbox: exec (bash/python), list_files, download_file (raw bytes),
  delete_file, library_diff, create_library_patch
- _client.request gains raw= for binary downloads
- Vendored manifest bumped to 33; respx + live-staging coverage added

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Fix: ruff format (newer version) + pin ruff to 0.15.18

CI's ruff collapsed download_file's call to one line; pin ruff exactly so local
and CI formatting never diverge (even patch releases change formatting).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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