contractspec

package
v0.1.0-develop.2026060... Latest Latest
Warning

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

Go to latest
Published: Jun 9, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package contractspec defines the runtime descriptor type for one contract endpoint, shared by the layers that bind contracts to wire protocols.

ContractSpec is consumed by:

  • kernel/cell.Registrar.Subscribe (event subscription)
  • kernel/wrapper.WrapConsumer / WrapSubscriber / HTTPHandler (decorators)
  • runtime/auth.Mount (HTTP route binding)
  • runtime/eventrouter (subscription routing + tracing)
  • runtime/http/router (route attribution + cell label)

Extracted from kernel/wrapper to break the cell→wrapper reverse edge. After the extraction kernel/wrapper sits at the top tier and depends only on outbox + leaves (ctxkeys, contractspec). contractspec imports kernel/cellvocab for the ContractKind type and InternalPathPrefix constant (single source of truth, no lockstep duplication).

Cells MUST NOT construct ContractSpec literals directly. The valid construction sites are:

  1. generated/contracts/**/spec_gen.go (private `var spec`) — business contracts produced by contractgen codegen; subscription/route mounting goes through the generated NewSubscription / NewHandler adapters.
  2. runtime/internal/contractbuild.NewFrameworkHTTP — runtime-owned HTTP infrastructure endpoints (health probes, devtools catalog, etc.); the only legitimate construction path for framework ContractSpec values in runtime/ HTTP infra code. Content invariant Hard (frameworkHTTPIDPrefix A-class panic); upstream Hard — the runtime/internal/ placement makes the Go compiler refuse imports from outside the runtime/ subtree, so business code (cells/, examples/, cmd/, adapters/) cannot call it.
  3. runtime/internal/contractbuild.NewEventDerivation — tracing/observability projection of a validated outbox.Subscription; returns (ContractSpec, error) with sub.Validate() + ContractSpec.Validate() embedded inside the funnel (shape-Hard, NOT provenance-Hard). Upstream caller-set Hard via the runtime/internal/ placement; the typed Subscription parameter forces shape but does NOT type-enforce value provenance (outbox.Subscription has exported fields — a runtime/ caller can fabricate one), so provenance is a runtime data-flow property (eventrouter), Hard-ifiable only by a sealed Subscription constructor (gh #1532). See contractbuild/doc.go grading.
  4. runtime/internal/contractbuild.NewWebhookDispatch — derivation of the event-kind subscription spec from a validated webhook.DispatchSpec; returns (ContractSpec, error) with spec.Validate() + ContractSpec.Validate() embedded inside the funnel (shape-Hard, NOT provenance-Hard). Upstream caller-set Hard via runtime/internal/ placement (compiler refuses imports from outside runtime/); the typed webhook.DispatchSpec parameter forces shape but does NOT type-enforce value provenance (exported fields), so provenance is a runtime data-flow property (cellgen→RegistrySnapshot), Hard-ifiable only by a sealed DispatchSpec constructor (gh #1532). See contractbuild/doc.go grading.

Three archtest gates enforce this invariant:

  • CELLS-NO-CONTRACTSPEC-IMPORT-01
  • NO-MANUAL-CONTRACTSPEC-LITERAL-01
  • EVENT-SUBSCRIPTION-CONTRACTGEN-COVERAGE-01

ref: k8s.io/apimachinery — lightweight value types shared across layers without runtime parsing dependencies.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ContractSpec

type ContractSpec struct {
	// ID is the contract identifier, e.g. "http.auth.login.v1" or
	// "event.session.revoked.v1". It MUST match the id field in the
	// contract.yaml file identified by Kind + path.
	ID string

	// Kind is one of ContractHTTP | ContractEvent | ContractCommand |
	// ContractProjection | ContractWebhook | ContractGRPC | ContractSaga.
	Kind cellvocab.ContractKind

	// Transport names the wire protocol the binding uses: "http" for Kind=="http",
	// "grpc" for Kind=="grpc", "amqp" / "mqtt" / "internal" for event/command/
	// projection. It is the PRIMARY transport — codegen derives it as the first
	// element of the contract's `transports:` set (transports[0]); a
	// multi-transport contract (e.g. event over [amqp, mqtt]) exposes the full
	// sanctioned set via the generated package's `Transports()` accessor (which
	// returns a copy so the truth source cannot be aliased), while this field
	// carries the primary the production binding routes over. Membership in
	// cellvocab.AllTransports() is governed at the declaration layer (FMT-39 +
	// schema enum), not at runtime — see Validate.
	Transport string

	// HTTP-specific fields; required when Kind == "http", rejected otherwise.
	Method string // upper-case HTTP verb
	Path   string // path template, e.g. "/api/v1/auth/login"

	// Event-specific fields; required when Kind == "event", rejected
	// otherwise. Topic is the broker destination name.
	Topic string

	// Clients is the allowlist of caller cell IDs for internal HTTP endpoints.
	// Required when Kind=="http" and Path has prefix "/internal/v1/"; must be
	// empty for non-internal paths. The list is mirrored in contract.yaml
	// endpoints.clients and enforced at runtime by auth.RequireCallerCell.
	Clients []string

	// GRPC carries the grpc transport details; required (non-nil) when
	// Kind == "grpc", rejected otherwise.
	GRPC *GRPCEndpointSpec
}

ContractSpec is the runtime descriptor for one contract endpoint. It is consumed by:

  • runtime/auth.Mount (HTTP route binding)
  • runtime/eventbus / kernel/cell.Registrar.Subscribe (event subscription)
  • tracing span attributes (gocell.contract.id / kind / transport)

The zero value is invalid — callers must populate ID / Kind / Transport and the kind-specific fields, then rely on auth.Mount / wrapper.HTTPHandler to Validate() before registration.

Construction-site catalog and archtest enforcement gates are documented in this package's doc.go (single source). Composite literal under cells/, examples/*/cells/, and runtime/ is forbidden by archtest NO-MANUAL-CONTRACTSPEC-LITERAL-01.

ref: k8s.io/apimachinery — lightweight value types shared across layers without runtime parsing dependencies.

func (ContractSpec) GRPCInfo

func (s ContractSpec) GRPCInfo() *GRPCEndpointSpec

GRPCInfo returns the grpc transport descriptor for a grpc-kind spec, or nil for any other kind. Callers use it to read service/method without a type switch on Kind.

func (ContractSpec) Validate

func (s ContractSpec) Validate() error

Validate returns an error if the spec is malformed. Validation is separate from construction so test fixtures can assert negative cases without the cost of a full wrapper.HTTPHandler call.

type GRPCEndpointSpec

type GRPCEndpointSpec struct {
	Service string // proto FQ service name, e.g. "device.command.v1.DeviceCommandService"
	Proto   string // contracts-relative .proto path
	// ProtoPackage is the proto `package` declaration (e.g. "device.command.v1").
	// The contractgen ProtoRegistry resolves it from the .proto starting PR 6;
	// runtime ContractSpec population lands PR 8 (first real grpc contract
	// registration). Empty until then; must not be relied upon.
	ProtoPackage string
}

GRPCEndpointSpec is the grpc-kind transport descriptor carried by ContractSpec.GRPC. It mirrors metadata.GRPCTransportMeta but is the runtime value type (kernel/contractspec is dependency-free of metadata parsing at the registration boundary). A single contract owns a whole proto service (#1655); the .proto file is the single source of truth for the RPC method set. ProtoPackage is the proto file's `package` declaration.

Jump to

Keyboard shortcuts

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