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.