Skip to content

feat: strict-proto contracts for ws.server, step.ws_send, step.ws_close, websocket trigger#6

Merged
intel352 merged 2 commits into
mainfrom
feat/issue-5-strict-contracts
May 14, 2026
Merged

feat: strict-proto contracts for ws.server, step.ws_send, step.ws_close, websocket trigger#6
intel352 merged 2 commits into
mainfrom
feat/issue-5-strict-contracts

Conversation

@intel352
Copy link
Copy Markdown
Contributor

Summary

Closes #5. Adds strict-proto contract support to workflow-plugin-websocket so the workflow engine can validate plugin messages at the gRPC boundary using typed protobuf messages.

  • proto/websocket/v1/websocket.proto — typed messages for all 4 plugin surfaces:
    • WSServerConfig (ws.server module config: path, max_connections, ping_interval, pong_wait, max_message_size, auth_required)
    • WSSendConfig/Input/Output (step.ws_send: connection_id + message config; bool sent + string error output)
    • WSCloseConfig/Input/Output (step.ws_close: connection_id config; bool closed + string error output)
    • WebSocketTriggerConfig (websocket trigger: no required fields, attached automatically)
  • gen/websocket.pb.go — generated via protoc-gen-go v1.36.11 / protoc v7.34.1
  • internal/contracts.goContractRegistry() wired to wsPlugin, compile-time ContractProvider assertion
  • plugin.contracts.json — static manifest read by wfctl plugin validate --strict-contracts

Follows the same pattern as workflow-plugin-tournament PR #7 and workflow-plugin-salesforce PR #6 + #7.

Test plan

  • CI: go test -race ./... passes (all 15 internal tests)
  • CI: go vet ./... passes
  • CI: wfctl plugin validate --file plugin.json --strict-contracts passes via strict-contracts job
  • Build: go build ./... succeeds cross-platform (verified locally)

🤖 Generated with Claude Code

…_close, websocket trigger

Closes #5. Adds typed protobuf contract support so the workflow engine can
validate plugin messages at the gRPC boundary instead of using map[string]any.

- proto/websocket/v1/websocket.proto: source-of-truth typed messages for all
  4 plugin surfaces (WSServerConfig, WSSendConfig/Input/Output,
  WSCloseConfig/Input/Output, WebSocketTriggerConfig)
- gen/websocket.pb.go: generated via protoc-gen-go v1.36.11
- internal/contracts.go: ContractRegistry wired to wsPlugin, compile-time
  ContractProvider assertion
- plugin.contracts.json: static manifest read by wfctl --strict-contracts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds strict-proto contract metadata to workflow-plugin-websocket so the workflow engine can validate module/step/trigger messages at the gRPC boundary using protobuf descriptors and a static plugin.contracts.json manifest.

Changes:

  • Introduces protobuf definitions for ws.server, step.ws_send, step.ws_close, and websocket trigger config/input/output shapes.
  • Adds a ContractRegistry() implementation on wsPlugin that returns STRICT_PROTO contract descriptors + a descriptor set (including struct.proto).
  • Adds a plugin.contracts.json manifest and a design doc describing the strict-contracts approach.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
proto/websocket/v1/websocket.proto Defines strict-proto message shapes for module/steps/trigger.
gen/websocket.pb.go Generated Go bindings for the new proto definitions.
internal/contracts.go Exposes a contract registry with STRICT_PROTO descriptors and bundled file descriptors.
plugin.contracts.json Declares strict-proto contracts for wfctl/engine validation.
docs/plans/2026-05-13-strict-contracts-design.md Documents the intended strict-contracts design and mapping decisions.
Files not reviewed (1)
  • gen/websocket.pb.go: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// sent is true when the message was delivered to the connection.
bool sent = 1;
// error is populated when the send failed (ws.server not initialized, missing connectionId).
string error = 2;
// closed is true when the connection was found and closed.
bool closed = 1;
// error is populated when the close failed (ws.server not initialized).
string error = 2;
Comment on lines +15 to +20
| Kind | Type | Message(s) |
|---------|---------------|-------------------------------------------|
| module | ws.server | WSServerConfig |
| step | step.ws_send | WSSendConfig / WSSendInput / WSSendOutput |
| step | step.ws_close | WSCloseConfig / WSCloseInput / WSCloseOutput |
| trigger | websocket | WebSocketTriggerConfig |
Comment on lines +55 to +57

No runtime behavior changed. The `plugin.contracts.json` and `internal/contracts.go`
are additive. To roll back: revert the commit and rebuild. The engine falls back to
Comment thread internal/contracts.go
Comment on lines +11 to +16
// ContractRegistry returns the typed contract descriptors for all websocket
// module, step, and trigger types. The workflow engine calls this via the
// sdk.ContractProvider interface for strict validation.
func (p *wsPlugin) ContractRegistry() *pb.ContractRegistry {
return websocketContractRegistry
}
…riptors

Addresses Copilot review: verifies ContractRegistry() returns 4 descriptors
(1 module + 2 steps + 1 trigger) all in STRICT_PROTO mode, and that the
FileDescriptorSet includes both websocket.proto and google/protobuf/struct.proto.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@intel352 intel352 merged commit 04b29bc into main May 14, 2026
2 checks passed
intel352 added a commit that referenced this pull request May 14, 2026
Records what worked, what didn't, and deferred items from the websocket
plugin strict-contracts adoption (PR #6, merged at 04b29bc).

Co-authored-by: Claude Sonnet 4.6 <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.

chore: adopt strict-contracts (plugin.contracts.json + proto definitions)

2 participants