Help us shape the future of Go! Take the 2026 Go Developer Survey

capgw

package
v0.2.50 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 22, 2026 License: MPL-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package capgw is the capability inlet: `POST /v1/cap/<name>` on the web head, where dispatched work — a run on a NODE, a chassis of its own that this chassis dispatched a run to — asks this chassis to do something on its behalf: call a model, note a card, finish the run. The request carries the run's grant as a token (Txco-Run-Grant) and the call's input as JSON; the grant gateway decides it (chassis/server/grantgw.Invoke) and, when it is allowed, the stack that DECLARES the capability runs it as an ordinary pipeline run (`@src == "cap"`, the call at `@cap.*`), entered at the stack's start — or at the scope its declaration names (CAPS/<name>.yaml, chassis/capdecl) — and answers at the top-level `_cap.output` — or `_cap.error {code, message}`. A name no active stack declares still runs the tenant's `_cap` stack from its first scope: the router a tenant wrote before declarations existed.

The inlet owns the transport and the identity; the stacks own the policy (`_grant`) and the work (the declaring stack). The chassis does not know what a capability does.

Answers, always JSON. The decision is answered with its status:

401 {"ok":false,"error":{"code":"unauthorized"}}   no token, or not a live grant's
403 {"ok":false,"error":{"code":"denied"}}         refused: allowlist, standing grant, budget, a rule
409 {"ok":false,"error":{"code":"held"}}           a rule held it for a person
404 {"ok":false,"error":{"code":"no_capability"}}  not a capability name
503 {"ok":false,"error":{"code":"unavailable"}}    the chassis could not decide

An ALLOWED call answers 200 at once — headers sent and flushed before the capability's run starts — and the body when the run ends. A model call can take a minute; a proxy on the way (the fleet's edge allows 20 s for response headers) must see headers, and then bytes: until the body, the inlet writes one space every keepalive interval. So what the run came to is in the body, with the status it would otherwise have carried:

200 {"ok":true,"output":…}
200 {"ok":false,"error":{"code":"no_capability","status":404}}        no rule answered
200 {"ok":false,"error":{"code":…,"message":…,"status":422}}         the stack's own error
200 {"ok":false,"error":{"code":"timeout","status":504}}             the run passed its ceiling
200 {"ok":false,"error":{"code":"unavailable","status":503}}         the run failed, or the tenant could not be routed

A refusal says only that it was refused: the trace of the `_grant` run has the reason. A client reads `error.status` as the status (the node's cap:// does); the leading whitespace is JSON's own.

Index

Constants

View Source
const (

	// Header is where the token travels. The node's web head reads the same
	// header off the dispatching request and keeps it out of its envelope.
	Header = processor.RunGrantHeader
	// CallerRIDHeader names the run that is calling, on the node: stamped
	// as `@cap.caller.rid` so a run can be followed across the two chassis.
	CallerRIDHeader = "Txco-Caller-Rid"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Decls

type Decls interface {
	Lookup(ctx context.Context, tenant, name string) (stack string, d *capdecl.Decl, err error)
}

Decls is where the inlet finds who answers a capability: the tenant's active stack that declares the name, and the declaration. It answers capdecl.ErrNotDeclared for a name no active stack declares.

type Gateway

type Gateway struct {
	// contains filtered or unexported fields
}

Gateway is the inlet.

func New

func New(ctx context.Context, pu *processor.Unit, grants *grantgw.Gateway, decls Decls) *Gateway

New builds the inlet over the grant gateway, the capability declarations and the processor's bus. A nil decls routes every call to `_cap`.

func (*Gateway) Handle

func (g *Gateway) Handle(w http.ResponseWriter, r *http.Request)

Handle serves POST /v1/cap/{name}. Registered ahead of the web catch-all: no BasicAuth (the token is the whole authorization), no opstack render path.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL