Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Bind delivery requests to the selected Pod
Carry the verified Pod identity in the strict request contract and require hostname matching so a reassigned Pod IP cannot silently accept work for another runtime.
  • Loading branch information
MFS-code committed Aug 6, 2026
commit e7a43a1c19f37c73bc7fa102300e3b944d9ca2a7
14 changes: 13 additions & 1 deletion SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ runtime listens on that port on the Pod network interface and exposes:

```text
POST /kontext.dev/v1alpha1/agent-runs
Host: <standing Pod name>
Content-Type: application/json
Accept: application/json
```
Expand All @@ -369,6 +370,10 @@ The request is one strict JSON object:
"namespace": "default",
"uid": "6d291c0e-3a2d-4b33-956e-8d4ec30f1ac3"
},
"target": {
"name": "owner-1-pod",
"uid": "481b6787-bc93-4eae-9d23-e8253c99d481"
},
"goal": "the fully resolved invocation goal"
}
```
Expand All @@ -381,9 +386,16 @@ network failures or Service Pod replacement. Runtimes performing non-idempotent
external effects must persist whatever stronger deduplication their workload
requires.

`target` identifies the verified standing Service Pod selected for this
attempt. The controller also sets the HTTP `Host` header to that Pod name. A
runtime must reject a request whose Host does not match its own Kubernetes
hostname before accepting the delivery. The controller verifies the target Pod
name, UID, IP, readiness, and owner chain again after the HTTP exchange and
discards the response if that identity changed.

The request contains the resolved goal, not template parameters. Parameter
rendering and execution-field snapshotting have already completed in
admission. Unknown fields, a missing identity or goal, an unsupported
admission. Unknown fields, a missing run or target identity or goal, an unsupported
`apiVersion`, and trailing JSON are invalid requests.

The runtime returns HTTP `200 OK` only with one terminal
Expand Down
18 changes: 16 additions & 2 deletions pkg/delivery/v1alpha1/types.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Package v1alpha1 defines the warm-delivery request contract shared by
// Service runtimes and the control plane.
//
// Delivery requests are strict records. Unknown top-level or run identity
// fields require a new contract version instead of being silently ignored.
// Delivery requests are strict records. Unknown top-level, run identity, or
// target identity fields require a new contract version instead of being
// silently ignored.
package v1alpha1

import (
Expand All @@ -27,6 +28,7 @@ const (
type Request struct {
APIVersion string `json:"apiVersion"`
Run RunIdentity `json:"run"`
Target PodIdentity `json:"target"`
Goal string `json:"goal"`
}

Expand All @@ -37,6 +39,12 @@ type RunIdentity struct {
UID string `json:"uid"`
}

// PodIdentity binds a delivery attempt to the verified standing Service Pod.
type PodIdentity struct {
Name string `json:"name"`
UID string `json:"uid"`
}

// Validate rejects requests that cannot be tied to one persisted AgentRun.
func (request Request) Validate() error {
if request.APIVersion != APIVersion {
Expand All @@ -51,6 +59,12 @@ func (request Request) Validate() error {
if request.Run.UID == "" {
return errors.New("delivery run uid is required")
}
if request.Target.Name == "" {
return errors.New("delivery target pod name is required")
}
if request.Target.UID == "" {
return errors.New("delivery target pod uid is required")
}
if request.Goal == "" {
return errors.New("delivery goal is required")
}
Expand Down
23 changes: 18 additions & 5 deletions pkg/delivery/v1alpha1/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func TestParseDeliveryRequest(t *testing.T) {
request, err := deliveryv1alpha1.Parse([]byte(`{
"apiVersion":"kontext.dev/delivery/v1alpha1",
"run":{"name":"review-1","namespace":"default","uid":"run-uid"},
"target":{"name":"owner-1-pod","uid":"pod-uid"},
"goal":"Review the change."
}`))
if err != nil {
Expand All @@ -36,6 +37,8 @@ func TestParseDeliveryRequest(t *testing.T) {
if request.Run.Name != "review-1" ||
request.Run.Namespace != "default" ||
request.Run.UID != "run-uid" ||
request.Target.Name != "owner-1-pod" ||
request.Target.UID != "pod-uid" ||
request.Goal != "Review the change." {
t.Fatalf("decoded request = %#v", request)
}
Expand All @@ -54,27 +57,37 @@ func TestParseDeliveryRequestRejectsInvalidRecords(t *testing.T) {
},
{
name: "missing identity",
body: `{"apiVersion":"kontext.dev/delivery/v1alpha1","run":{},"goal":"work"}`,
body: `{"apiVersion":"kontext.dev/delivery/v1alpha1","run":{},"target":{"name":"pod","uid":"pod-uid"},"goal":"work"}`,
want: "delivery run name is required",
},
{
name: "missing target identity",
body: `{"apiVersion":"kontext.dev/delivery/v1alpha1","run":{"name":"run","namespace":"default","uid":"uid"},"target":{},"goal":"work"}`,
want: "delivery target pod name is required",
},
{
name: "missing goal",
body: `{"apiVersion":"kontext.dev/delivery/v1alpha1","run":{"name":"run","namespace":"default","uid":"uid"}}`,
body: `{"apiVersion":"kontext.dev/delivery/v1alpha1","run":{"name":"run","namespace":"default","uid":"uid"},"target":{"name":"pod","uid":"pod-uid"}}`,
want: "delivery goal is required",
},
{
name: "unknown field",
body: `{"apiVersion":"kontext.dev/delivery/v1alpha1","run":{"name":"run","namespace":"default","uid":"uid"},"goal":"work","extra":true}`,
body: `{"apiVersion":"kontext.dev/delivery/v1alpha1","run":{"name":"run","namespace":"default","uid":"uid"},"target":{"name":"pod","uid":"pod-uid"},"goal":"work","extra":true}`,
want: "unknown field",
},
{
name: "unknown identity field",
body: `{"apiVersion":"kontext.dev/delivery/v1alpha1","run":{"name":"run","namespace":"default","uid":"uid","extra":true},"goal":"work"}`,
body: `{"apiVersion":"kontext.dev/delivery/v1alpha1","run":{"name":"run","namespace":"default","uid":"uid","extra":true},"target":{"name":"pod","uid":"pod-uid"},"goal":"work"}`,
want: "unknown field",
},
{
name: "unknown target field",
body: `{"apiVersion":"kontext.dev/delivery/v1alpha1","run":{"name":"run","namespace":"default","uid":"uid"},"target":{"name":"pod","uid":"pod-uid","extra":true},"goal":"work"}`,
want: "unknown field",
},
{
name: "trailing JSON",
body: `{"apiVersion":"kontext.dev/delivery/v1alpha1","run":{"name":"run","namespace":"default","uid":"uid"},"goal":"work"} {}`,
body: `{"apiVersion":"kontext.dev/delivery/v1alpha1","run":{"name":"run","namespace":"default","uid":"uid"},"target":{"name":"pod","uid":"pod-uid"},"goal":"work"} {}`,
want: "trailing JSON value",
},
}
Expand Down
Loading