Skip to content

feat: add shared Connect/gRPC contract for the playground - #1

Merged
0xmhha merged 6 commits into
mainfrom
feat/connect-contract-v0.3.0
Oct 28, 2026
Merged

0xmhha merged 6 commits into
mainfrom
feat/connect-contract-v0.3.0

Conversation

@0xmhha

@0xmhha 0xmhha commented Oct 28, 2026

Copy link
Copy Markdown
Member

Summary

Adds the shared protobuf contract for the KingSejong Playground. Until now the frontend and the backend each kept their own copy of the .proto files (the copies had already drifted), and the gateway exposed every internal RPC to browsers through an unauthenticated gRPC-Web proxy. This repository becomes the single source of the API, with generated Go and TypeScript code and documented security rules.

Design

  • Two packages. playground.api.v1 is the browser-facing API (Language, Execution, Share, Settings, Auth). playground.svc.v1 is what the gateway calls over mTLS. Nothing in svc is ever mounted on the public listener.
  • No identity in public messages. Public requests carry no user id, request id, tier or limit-raising field. The gateway derives identity from cookies and passes a CallContext and an ExecutionPolicy to the services. API keys can only be created for the caller.
  • Bounded input. protovalidate rules limit files (1 to 16, unique paths, safe alphabet, no ./.. segments, 64 KiB each), stdin (64 KiB), arguments (16 × 256 B), wall time and id formats. The total-size limit, which CEL cannot express, lives in go/limits, and the TS package mirrors it.
  • One way to run code. ExecutionService.Run is a server stream of typed events (accepted, queued, started, output, diagnostic, truncated, heartbeat, finished) with a sequence number. Closing the stream cancels the run.
  • Runtime specs. Commands are argv arrays (no shell) and images must be pinned by digest.
  • Package name. The service package is svc, not internal, because Go refuses imports of generated code under an internal/ path from another module.
  • Generated code is committed. Consumers need no buf toolchain. CI fails if regeneration changes anything.
  • License. Apache-2.0, compatible with both the Apache-2.0 frontend and the GPL-3.0 backend.

Docs: docs/SECURITY_PROTOCOL.md (threat model, request checks in order, sandbox contract, acceptance tests), docs/RPC_DESIGN.md (old endpoint → new RPC map, stream semantics, versioning) and docs/ROADMAP.md (open work).

Testing

  • buf lint and buf format --diff --exit-code: clean.
  • go vet ./... and go test ./...: go/limits and go/validationtest pass. The 18 validation cases include path traversal, absolute paths, duplicate paths, 17 files, 65537-byte stdin, bad execution ids and an invalid email.
  • ts: npm run build and npm test (vitest, 7 tests) pass; npm pack contains only dist/.
  • The backend and the frontend were built against this contract locally (Go workspace and npm tarball).

Not verified

  • The release workflow runs only when a tag is pushed, so it has not run yet; v0.3.0 will be its first run.

Add the Playground contract as two protobuf packages:

- playground.api.v1: browser-facing Language, Execution, Share,
  Settings and Auth services. Messages carry no user ids, request ids
  or limit-raising fields; identity comes from the session at the
  gateway. Every input is bounded with protovalidate rules (file count,
  path alphabet without dot segments, per-file and stdin size, argument
  count, id formats).
- playground.svc.v1: services the gateway calls over mTLS. Requests
  carry a gateway-built CallContext (principal, request id, client IP)
  and execution requests carry an ExecutionPolicy enforced by the
  sandbox. Runtime commands are argv arrays, images are pinned by digest.

The service package is named svc rather than internal because Go does
not allow importing generated code under an internal/ path from another
module.
Generated with protoc-gen-go, protoc-gen-connect-go (connect v2) and
protoc-gen-go-grpc (service package only). go/limits holds limits that
protovalidate cannot express, such as the total source size, plus the
edge read limits. go/validationtest checks that the declared rules
reject path traversal, duplicate paths, oversized input and malformed
ids.
@kingsejong-lang/playground-proto exports the generated schemas and
service descriptors for connect-es v2 and a limits module mirroring the
Go helpers. Only playground.api.v1 is generated for the browser. The
package ships dist/ only and has no install scripts. Tests run the same
validation rules as the Go suite.
SECURITY_PROTOCOL.md records the defects found in the previous gateway,
the threat model, the layered request checks (body size, origin,
session, rate and concurrency limits, validation, admission, owner
checks) and the sandbox rules. RPC_DESIGN.md maps every old REST,
WebSocket, SSE and gRPC-Web call to the new RPCs and defines the Run
stream. ROADMAP.md lists the remaining work.
CI runs buf lint and format checks, breaking-change detection against
the base branch, verifies that generated code is up to date, and runs
the Go and TypeScript tests. Pushing a vX.Y.Z tag attaches the npm
package tarball to a GitHub release.
CI generates TypeScript code with the generator installed by npm ci; without it buf generate fails with 'protoc-gen-es not found'.
@0xmhha
0xmhha merged commit f1b3d5f into main Oct 28, 2026
2 checks passed
@0xmhha
0xmhha deleted the feat/connect-contract-v0.3.0 branch October 28, 2026 21:36
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