Skip to content

RFC: conformance suite for forge generators - #45

Open
teamchong wants to merge 3 commits into
cloudflare:mainfrom
teamchong:feat/conformance-spec
Open

teamchong wants to merge 3 commits into
cloudflare:mainfrom
teamchong:feat/conformance-spec

Conversation

@teamchong

@teamchong teamchong commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

RFC for a conformance suite any forge target can run.

Question it answers: if I write a new target plugin, how do I know it covers all the cases?

A case is data: one call, the HTTP exchanges the server must see, and the result the caller must get. A target generates a client for the suite API and wraps it in a small program that reads cases and writes results as JSON lines. A standalone runner serves the exchanges and checks the results:

forge-conformance --cases ./cases --client "node ./client.js" --expect-fail ./expected-failures.yaml

The runner builds nothing and knows nothing about the target's language, so targets outside this repo use it the same way.

conformance/RFC.md defines the case schema, the client protocol and the runner's behaviour. The cases and suite API come once the shape is agreed.

@teamchong
teamchong force-pushed the feat/conformance-spec branch from 8f4ad3e to 44c14bb Compare October 15, 2026 02:41
@teamchong teamchong changed the title Conformance suite spec RFC: conformance suite for forge generators Oct 15, 2026
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
@teamchong
teamchong force-pushed the feat/conformance-spec branch from 44c14bb to d1ffe93 Compare October 15, 2026 02:59
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
@teamchong
teamchong force-pushed the feat/conformance-spec branch from d1ffe93 to f7f6e08 Compare October 15, 2026 18:00
@teamchong
teamchong force-pushed the feat/conformance-spec branch from f7f6e08 to ea71832 Compare October 15, 2026 18:11
Comment thread conformance/RFC.md Outdated
Comment on lines +45 to +49
One OpenAPI document, written for the cases. It has few methods, each
covering several patterns, so a client program can call them the way a user
of the SDK would. A new pattern goes into an existing method when it fits;
a method is added only when no existing one can carry it, such as a new
group. Each pattern appears at least once:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think few is still vague, we need to have a fixed set of methods. We can add more if needed but we should really think of a way to reduce that.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

replaced "few methods" with a fixed table of 9 methods in "The suite API" and mapped all patterns onto them

Comment thread conformance/RFC.md
Comment on lines +109 to +113
method: string;
path: string; // escaped, without the base URL
query?: Record<string, string | string[]>; // one key per name; repeated name: array
headers?: Record<string, string | string[]>; // only listed headers are checked
body?: Json;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

But these can be determined by the conformance runner based on call and result, right?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

not without the runner parsing the OpenAPI spec and re-implementing request serialization itself

keeping exchanges explicit keeps the runner spec-agnostic, lets each case pin the exact wire representation (casing, escaping, date/int64 encoding), and covers error payloads, non-JSON text responses, and disconnects that can't be derived from call.

clarified this below schema

Comment thread conformance/RFC.md Outdated
Comment on lines +133 to +139
A generated method takes one request argument holding all of its inputs:
path, query and header parameters, and the body. For a body that is an
object, its fields are members of the request; any other body is the
`body` member. `request` is that argument, in forge field names, not what is
sent: the target builds the argument from it and the generated method puts
each member where the API description says. An SDK variable may be set in
both: the request's value wins, and `variables` is the fallback.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

How does a client differentiate then?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

good catch. split call.request into call.path, call.query, call.headers, and call.body (see "Call inputs") so targets with positional path params or separate param/body structs don't have to guess which keys belong where, and call.path cleanly overrides variables

Comment thread conformance/RFC.md Outdated
Comment thread conformance/RFC.md Outdated
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.

2 participants