Skip to content

CI rehearsal only (do not merge) - #17

Closed
michael-moffett wants to merge 20 commits into
mainfrom
pay-kit-89-m1-kotlin-runner-a1-next
Closed

michael-moffett wants to merge 20 commits into
mainfrom
pay-kit-89-m1-kotlin-runner-a1-next

Conversation

@michael-moffett

Copy link
Copy Markdown
Member

Fork CI only. Do not merge.

michael-moffett and others added 16 commits October 3, 2026 06:46
…matrix

A Gradle stdin/stdout runner over the Kotlin SDK's protocol functions, plus `harness/protocol-runners/kotlin.json`, so the spawned-runner block drives Kotlin.

No protocol-layer vector reaches Kotlin today. Milestone 1 of our harness proposal puts Kotlin in the divergence matrix.
…-run steps in the kotlin harness job, and asserted Kotlin divergences in the spawned-runner matrix
…cratch (--rerun-tasks); 5/5 MainTest cases pass, the vitest suite is still unrun
…l as a must-pass case (TS reference re-parses Kotlin's header) and lists receipt.format as a known unsupported divergence
…lDist test) and Main.kt gains its 3-line header comment
…ned-runner block, with Kotlin's SDK gaps asserted by exact response
…elds after whole-object serialization (Go omitempty), with its unit test asserting the omission
…d digest; an empty request now returns parse_error, with a MainTest case for it
@greptile-apps

greptile-apps Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 3/5

[High risk] Adds Kotlin test harness to CI pipeline.

The PR is not ready to merge because the Kotlin runner still misclassifies valid opaque values and empty challenge IDs.

Findings

  1. P1 Valid opaque values rejected ▶
  2. P1 Empty challenge IDs accepted ▶

Summary

The PR adds a Kotlin protocol runner and a CI step to build and exercise it against conformance vectors.

  • Expands Kotlin test coverage to every implemented parse and format vector.
  • Records known Kotlin divergences as exact runner responses.

Reviews (3) · Last reviewed commit: "greptile.json: review on request only"

val fields = Json.encodeToJsonElement(PaymentChallenge.serializer(), challenge).jsonObject
return JsonObject(
fields.filter { (name, value) -> name !in setOf("expires", "digest") || value != JsonPrimitive("") }.mapValues { (name, value) ->
if (name == "request" || name == "opaque") decodeJson(value.jsonPrimitive.content) else value

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Valid opaque values rejected A challenge can contain a plain-text opaque value. The SDK parses it as a string, but this runner tries to base64url-decode and JSON-parse it, returning parse_error for a valid challenge. Only request should be decoded this way.

Suggested change
if (name == "request" || name == "opaque") decodeJson(value.jsonPrimitive.content) else value
if (name == "request") decodeJson(value.jsonPrimitive.content) else value

}

private fun parseChallenge(input: JsonElement): JsonObject {
val challenge = MppHeaders.parseWWWAuthenticate(input.jsonObject.getValue("header").jsonPrimitive.content)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Empty challenge IDs accepted When a challenge has id="", the SDK parser checks that the field exists but does not reject its empty value. This runner returns a successful parse, although the canonical vector requires parse_error, so it reports an invalid challenge as valid.

Suggested change
val challenge = MppHeaders.parseWWWAuthenticate(input.jsonObject.getValue("header").jsonPrimitive.content)
val challenge = MppHeaders.parseWWWAuthenticate(input.jsonObject.getValue("header").jsonPrimitive.content)
require(challenge.id.isNotEmpty()) { "challenge id must not be empty" }

Comment thread harness/test/protocol-conformance.test.ts
michael-moffett and others added 4 commits October 5, 2026 13:15
…ed as a known divergence with its exact response; the opaque and vector-coverage findings are answered with the earlier rulings
…d credential.format case through the runner; the other seven SDKs keep their smoke cases
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