capability

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 7, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package capability defines GoCell capability providers: assembly-level shared infrastructure resources (postgres pool, redis client, ...) provisioned once by the composition root and injected into every consuming cell module.

Why assembly-level (not per-cell)

A capability is a fx.Supply-shaped shared value, not a per-cell constructor. The composition root provisions one postgres pool / one redis client and hands the same handle to every module that needs it. Per-cell construction would open one pool per cell, breaking the single-pool + LIFO-shutdown invariant and contradicting the one-outbox-table / one-relay model. See ADR docs/architecture/202605251500-adr-capability-provider-interface.md.

Layering: runtime/capability never imports adapters/

runtime/ may depend only on kernel/ + pkg/ (CLAUDE.md). So the provider interfaces are expressed over kernel types (persistence.TxRunner, outbox.Writer) plus a deliberate `any` typed-erasure seam (DB() / Client()) for the raw adapter handle. The `any` is type-asserted exactly once, in the consumer site inside cmd/* (which may import adapters/).

Sealed construction (AI-robust: upstream Hard)

PGProvider / RedisProvider carry an unexported marker method, so they can only be implemented inside this package. The concrete impls (pgProvider / redisProvider) are private; NewPGProvider / NewRedisProvider are the sole construction paths. A cell module cannot fabricate a bypass provider — it must consume the injected one. This is the upstream-Hard half of the funnel: Go's type system makes a forged provider unrepresentable outside this package.

Funnel closure (downstream Medium)

The downstream half is archtest CAPABILITY-PROVIDER-FUNNEL-01 (tools/archtest/capability_provider_funnel_test.go): a type-aware caller allowlist that bans the shared-infrastructure constructors (adapters/postgres.NewPool / NewTxManager / NewOutboxWriter, adapters/redis.NewClient) anywhere except the single provisioning site cmd/corebundle/cap_wiring.go. Per-cell / per-role derivations that take an already-acquired handle (NewSessionStore / NewLedgerStore / NewOutboxStore / NewCache / NewRedisDriver / …) are intentionally NOT banned.

Rating: upstream Hard (sealed) + downstream Medium (archtest caller-allowlist, not compile-time) — an allowed transition form per ai-robust.md §"Funnel 双向锁评级". The downstream→Hard upgrade is tracked at gh issue #988. The blind-spot inventory lives in that archtest's package godoc, not duplicated here.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Kind

type Kind string

Kind names an assembly-level shared infrastructure capability. Cells declare what they consume via cell.yaml `requires`; the assembly's provisioned set is the derived union of its cells' requires (Design Y, #855 — see kernel/assembly.GenerateModulesGen). The closed value set below is mirrored by the cell.schema.json `requires` enum (kept in lockstep by kernel/metadata/schemas TestSchemaConstantsMatchSchemaLiterals). Unknown or duplicate values are rejected by `gocell validate` governance rule FMT-36 at validation time — not at parse time: ParseFS stays lenient, matching Kubernetes admission-layer enum validation rather than parse-time rejection.

const (
	// Postgres is the shared postgres pool (TxManager + OutboxWriter + DB).
	Postgres Kind = "postgres"
	// Redis is the shared redis client.
	Redis Kind = "redis"
	// RabbitMQ is recognized by the enum but has NO provider / provisioning path
	// yet: there is no RabbitMQProvider and cap_wiring's provisionCapabilities has
	// no rabbitmq case, so declaring `requires: [rabbitmq]` in a cell.yaml passes
	// FMT-36 + codegen but fails fast at provisionCapabilities' default branch. It stays in
	// the enum as recognized forward vocabulary; a real AMQP-shared-connection
	// assembly must land the RabbitMQProvider + provisioning atomically.
	RabbitMQ Kind = "rabbitmq"
)

type PGProvider

type PGProvider interface {
	// TxManager returns the shared transactional runner bound to the pool.
	TxManager() persistence.TxRunner
	// OutboxWriter returns the transactional outbox writer.
	OutboxWriter() outbox.Writer
	// DB returns the raw pool handle (*adapterpg.Pool.DB()) as any. The single
	// type-assertion lives in the cmd/* consumer; runtime/capability stays adapter-free.
	DB() any
	// contains filtered or unexported methods
}

PGProvider is the sealed handle to the assembly's single postgres pool. It is implementable only inside package capability (unexported marker isPGProvider); the sole construction path is NewPGProvider. Consumers receive an injected PGProvider and must not construct adapter primitives themselves (CAPABILITY-PROVIDER-FUNNEL-01).

func NewPGProvider

func NewPGProvider(tx persistence.TxRunner, writer outbox.Writer, db any) PGProvider

NewPGProvider wraps the composition-root-constructed postgres primitives into the sealed PGProvider. tx and writer are kernel-typed; db is the raw *adapterpg.Pool.DB() handle passed as any so this package never imports adapters/. Called only from the assembly wiring site (cmd/<id>/cap_wiring.go).

type RedisProvider

type RedisProvider interface {
	// Client returns the raw redis client (*adapterredis.Client) as any. The
	// single type-assertion lives in the cmd/* consumer.
	Client() any
	// contains filtered or unexported methods
}

RedisProvider is the sealed handle to the assembly's shared redis client. Implementable only inside package capability; sole construction path NewRedisProvider.

func NewRedisProvider

func NewRedisProvider(client any) RedisProvider

NewRedisProvider wraps the composition-root-constructed redis client into the sealed RedisProvider. client is the raw *adapterredis.Client passed as any.

Jump to

Keyboard shortcuts

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