Shared Platform · Shared Libraries

Shared Libraries (libs/shared)

The shared tree is the most code-complete surface in the repository because the dependency on it is load-bearing, not aspirational.

9sections15 minread1diagrams

On this page

libs/shared/ is the domain-agnostic floor of the platform: the @oshun/* infrastructure packages that every product (V1–V9), every capability domain, and every BFF imports rather than re-implements. The tree holds 49 distinct @oshun/* packages (50 package.json manifests, one of which is the generated libs/shared/types/dist/ copy of @oshun/types) — @oshun/logging, @oshun/errors, @oshun/database, @oshun/event-bus, @oshun/identity, @oshun/crypto, and the rest. What makes them shared is a property the build enforces and a grep can verify: nothing under libs/shared/ imports a domain. A search for @oshun/domain-*, memory-iris, evidence-sophia, or any libs/oshun/ path across the tree returns no production hits. These packages carry no Oshun-specific knowledge of rituals, lessons, or evidence packs; you could lift @oshun/event-bus into an unrelated product and it would still work. That absence of domain knowledge is exactly what makes them safe for every domain to depend on without creating a cycle.

Each package is a real workspace package wired into tsconfig.base.json with a path mapping that points at live source — "@oshun/crypto": ["libs/shared/crypto/src/index.ts"] (tsconfig.base.json:1406), "@oshun/event-bus": ["libs/shared/event-bus/src/index.ts"] (:1496), and so on for all nineteen packages this page covers — so an importer type-checks against the actual implementation, not a stale dist. This page maps the foundation by layer: types/errors/config at the bottom, observability and data above them, eventing and the HTTP/gateway tier, and the security/identity packages that thread through every request. It is one slab of the stack described in the platform overview; the database and cache internals are taken further in Persistence & Data, and the unified identity model in Auth & Identity.

What ships, honestly#

The shared tree is the most code-complete surface in the repository because the dependency on it is load-bearing, not aspirational. The packages in scope here are implemented over real backends, not scaffolds: @oshun/logging is Pino (libs/shared/logging/src/logger.ts:7,146), @oshun/metrics is prom-client (libs/shared/metrics/src/registry.ts:7), @oshun/tracing is OpenTelemetry with an OTLP exporter (libs/shared/tracing/src/tracer.ts:16-31), @oshun/database opens a real pg Pool (libs/shared/database/src/postgres-client.ts:7,40), @oshun/event-bus runs on Redis pub/sub, and @oshun/crypto delegates every primitive to the audited @noble/* libraries (libs/shared/crypto/src/index.ts:30-49). Most packages ship a Vitest suite next to their source (*.spec.ts / *.test.ts); the lone exception is @oshun/errors, which has no test suite today.

Two honesty notes, in the spirit of the repository's no-stub culture and the docs center's implemented / spec-only / provider-gated convention:

  • @oshun/content-security is a plan-and-validate layer, not the media executor. Its watermarking and provenance modules are real, deterministic builders and validators — they emit typed embedding commands, C2PA/SynthID plans, and run genuine provenance-graph integrity checks — but the package is versioned 0.1.0 and the actual pixel/audio embedding runs downstream of the command it produces (libs/shared/content-security/src/watermarking.ts, provenance.ts). It is labeled as such below rather than implied to stamp bytes itself.
  • The "zero dependency" claim is strongest at the bottom. @oshun/types has no external dependencies at all; most packages depend only on a backend driver. Two privacy packages — @oshun/data-residency and @oshun/deletion-fanout — additionally import the @oshun/contracts rule tables (libs/shared/data-residency/src/dsr-routing.ts:1). They remain domain-agnostic (a residency zone is not a domain), but they are not zero-dependency the way @oshun/types is.

Foundation: types, errors, config#

These three packages sit at the very bottom; everything above imports them and they import almost nothing.

@oshun/types is the "ZERO external dependencies" types package (libs/shared/types/src/index.ts:6). Its load-bearing exports are a branded-ID pattern — type ID<T extends string = string> = string & { readonly __brand: T } (base.ts:21) specialized into UserID, ProjectID, AssetID, SessionID, CorrelationID, and friends — and a Result union, type Result<T, E = Error> = Success<T> | Failure<E> (base.ts:112), so a function can return failure as data rather than throwing. Branding means a raw string will not type-check where a UserID is required, which catches an entire class of "passed the project id where the user id goes" bugs at compile time. The package also carries the base entity mixins (BaseEntity, SoftDeletable, Versioned, Auditable) and a creative/ sub-barrel (Script, Character, Storyboard) imported via @oshun/types/creative.

@oshun/errors standardizes failure. Every error descends from OshunError (libs/shared/errors/src/base.ts:57), which extends the native Error with a machine-readable code, an HTTP statusCode, structured details, a timestamp, an isOperational flag (expected/recoverable vs. programmer bug), and an expose flag that decides whether details reach the client — defaulting true for 4xx and false for 5xx, so a server fault never leaks internals. On top of the base sit a full HTTP ladder (BadRequestErrorGatewayTimeoutError, http.ts:17-214) and the domain classes that map to it: ValidationError, AuthenticationError, TokenExpiredError, AuthorizationError, ResourceNotFoundError, DuplicateError, VersionConflictError, RateLimitError, ExternalServiceError, DatabaseError (domain.ts). Error codes are grouped into closed sets — AUTH_ERRORS, AUTHZ_ERRORS, RESOURCE_ERRORS, EXTERNAL_ERRORS (codes.ts) — and utilities like wrapError, isOperationalError, and createSafeErrorResponse (utils.ts) give every service one consistent way to wrap, classify, and serialize a failure. AppError is exported as a Lilith-compatibility alias for the same base class.

ts
import {
  ValidationError,
  wrapError,
  createSafeErrorResponse,
} from '@oshun/errors';

throw new ValidationError('Invalid email format', {
  fields: { email: ['Invalid format'] },
});
// later, at the boundary: createSafeErrorResponse(err) → { code, message, statusCode, details? }
// 5xx details are withheld; 4xx details are exposed.

@oshun/config turns environment variables into validated, typed config via Zod. schemas.ts defines a schema per concern (serverConfigSchema, databaseConfigSchema, redisConfigSchema, storageConfigSchema, authConfigSchema, loggingConfigSchema, tracingConfigSchema, aiConfigSchema, rateLimitConfigSchema), and loader.ts exposes typed loaders (loadServiceConfig, loadDatabaseConfig, loadRedisConfig, loadAuthConfig) plus env helpers (getEnvNumber, getEnvBool, isProduction). A misconfigured service fails loudly at boot — a bad PORT or a missing DATABASE_URL is a parse error, not a NaN surfacing three hops later. The package also ships experiment guardrails (experiment-guardrails.ts, for V1 §28.7): a schema-validated model where each feature-flag experiment carries guardrail metrics with a closed comparison op set (lte | lt | gte | gt | between), and evaluateGuardrails decides whether a ramp must auto-hold.

Observability: logging, metrics, tracing, health#

The four observability packages are emitted at every hop of the request trace in the overview; they share the philosophy of real backends with sane defaults.

@oshun/logging wraps Pino (logger.ts:7) with structured, leveled logging and — importantly — PII redaction on by default. DEFAULT_REDACT_PATHS (logger.ts:105) strips password, token, secret, apiKey, authorization, cookie, creditCard, ssn, and their nested forms before a line is written, so a careless logger.info('login', { body }) cannot spill credentials. It ships five transports (console, file, http, elasticsearch, tcp under transports/), sampling strategies for high-volume paths (sampling/), and request-logger middleware for Express/Fastify/Koa (middleware/). Child loggers carry context (logger.child({ requestId })) so a correlation id rides every line of a request.

@oshun/metrics is Prometheus via prom-client. OshunMetricsRegistry wraps the registry; createHistogram/createCounter/createGauge and the global convenience functions emit metrics, and server.ts exposes the /metrics scrape endpoint. Crucially it ships standard metric-name vocabulariesHTTP_METRICS, DB_METRICS, CACHE_METRICS, AI_METRICS, QUEUE_METRICS (types.ts) — plus HISTOGRAM_BUCKETS and SUMMARY_PERCENTILES presets, so two services do not name the same latency histogram differently and break a dashboard.

@oshun/tracing is OpenTelemetry: a NodeTracerProvider, the OTLP HTTP exporter, and an AsyncLocalStorageContextManager (tracer.ts:16-31) that propagates span context across await boundaries without manual threading. withSpan('name', async (span) => …) is the ergonomic entry point; propagation.ts and TRACE_CONTEXT_HEADERS handle W3C traceparent/baggage and B3 propagation across service hops, with Hono middleware and an X-Ray adapter alongside.

@oshun/health standardizes the healthy | degraded | unhealthy status model. HealthManager aggregates registered checks; ProbeManager (probes.ts) emits the Kubernetes liveness/readiness/startup probe handlers; and DependencyAggregator with createDatabaseCheck/createRedisCheck (dependencies.ts) rolls a service's downstream dependencies into one report. The distinction between degraded and unhealthy matters: a service that lost a cache but can still serve from the database reports degraded, and the orchestrator keeps it in rotation instead of killing it.

Data: database and cache#

These two are summarized here and taken further in Persistence & Data.

@oshun/database is the unified data-access surface. postgres-client.ts opens a real pooled pg Pool (:7,40) with DEFAULT_POSTGRES_CONFIG; redis-client.ts covers Redis; transaction.ts exposes the TransactionIsolationLevel ladder; query-builder.ts provides typed WhereCondition/OrderByClause/PaginationOptions builders; and health.ts, metrics.ts, migration.ts, and connection-string.ts round out pooling, observability, and migration. It also retains a legacy-pool.ts / legacy-migrations.ts compatibility surface for older callers.

@oshun/cache is more than a Redis wrapper — it is a small reliability toolkit. Beyond CacheClient and the with-cache.ts getOrFetch read-through helper, it ships an OshunCircuitBreaker (circuit-breaker.ts:39, with a CircuitOpenError) so a flapping cache fails fast instead of piling up timeouts, and an OshunLockManager distributed lock (distributed-lock.ts:193) built on atomic SET NX PX with Lua-scripted release/extend that only acts if the caller still owns the lock (:104,143) and a clock-drift safety margin (:82). A LockExpiredError is raised if a held lock lapses mid-critical-section, and an auto-renew timer can extend a lock under a long job. pubsub.ts, invalidation.ts, memory-cache.ts, and key-builder.ts (with the TTL / DOMAIN_TTL presets) complete the package.

Eventing: the cross-domain event bus#

@oshun/event-bus is how domains talk without importing each other. It is a Redis pub/sub bus with a typed envelope (event-bus/src/types.ts:24):

ts
interface EventEnvelope<T = unknown> {
  id: string;
  type: string; // e.g. 'isis.asset.generated'
  source: DomainScope; // owning domain
  targets?: DomainScope[]; // empty = broadcast
  correlationId?: string; // request trace
  causationId?: string; // parent event
  payload: T;
  timestamp: number;
  version: string; // schema version
  metadata?: Record<string, unknown>;
}

The source/targets use a closed DomainScope union — yemaya | lilith | isis | sophia | hathor | bellona | aphrodite | asase | oshun (types.ts:10-19), the monorepo-wide engine domains, with oshun reserved for shared infrastructure. Handlers receive an EventContext with explicit lifecycle control — ack(), nack(delay?), deadLetter(reason), reply(), and publish() (types.ts:58) — so at-least-once delivery is the caller's choice, not an accident. RetryConfig supports exponential | linear | fixed backoff (types.ts:90-101) and DeadLetterConfig bounds retention and entry count. A versioned topic registry (topic-registry.ts) pins each topic to an owner domain and payload name — EventTypes.ISIS_ASSET_GENERATED is owned by isis (topic-registry.ts:189), OshunV1EventTopics enumerates the job-lifecycle topics — and a registry-enforcement mode rejects an unregistered topic at publish time rather than letting a typo become a silent dead channel. outbound-delivery.ts adds Ed25519-signed webhook delivery (signOutboundEvent/ verifyOutboundSignature, with computed backoff) for events that leave the platform, and webhook-simulator.ts lets a consumer test its endpoint offline.

flowchart TB subgraph sec["security / identity"] ID["@oshun/identity · @oshun/auth · @oshun/auth-primitives"] CR["@oshun/crypto"] PRIV["@oshun/data-residency · @oshun/deletion-fanout · @oshun/content-security"] end subgraph hg["http / gateway"] HC["@oshun/http-client (SSRF guard, retries)"] GW["@oshun/traefik-config (Traefik gen)"] end EB["@oshun/event-bus"] subgraph data["data"] DB["@oshun/database (pg Pool)"] CA["@oshun/cache (locks, breaker)"] end subgraph obs["observability"] LOG["@oshun/logging"]; MET["@oshun/metrics"]; TR["@oshun/tracing"]; HE["@oshun/health"] end subgraph fnd["foundation"] TY["@oshun/types"]; ERR["@oshun/errors"]; CFG["@oshun/config"] end sec --> obs; hg --> obs; EB --> obs; data --> obs sec --> fnd; hg --> fnd; EB --> fnd; data --> fnd; obs --> fnd PRIV -. "@oshun/contracts rule tables" .-> EB

HTTP and gateway: http-client and gateway#

@oshun/http-client is the resilient outbound HTTP surface, and its most security-load-bearing module is the SSRF / egress guard (http-client/src/ssrf-guard.ts). It is deliberately two-phase to defeat DNS-rebinding (time-of-check vs. time-of-use): assertUrlAllowed checks scheme, port, host shape, and bare-IP literals before DNS, and assertResolvedAddressAllowed re-checks the resolved address after DNS but before the socket connects (ssrf-guard.ts:9-14). The default policy refuses non-http(s) schemes, private/loopback/link-local/multicast IPs (with classifyIpv4/classifyIpv6 covering 10/8, 127/8, 169.254/16, 172.16–31, 192.168/16, CGNAT 100.64/10, IPv6 fe80::/10, fc00::/7, ::1, and IPv4-mapped forms), embedded credentials, and ports outside an allow-list of 80/443. Cloud metadata endpoints — 169.254.169.254 (AWS IMDS) and metadata.google.internal — are in the always-blocked list (:72-78). Callers configure an explicit allowedHosts list for trusted webhook targets. Around that, the client layers retries (retry.ts), a circuit breaker (circuit-breaker.ts), interceptors, timeouts, idempotency keys (idempotency.ts), tenant-context propagation (tenant-context.ts), and tracing; createResilientHttpClient wires the resilient defaults in one call.

@oshun/traefik-config generates the edge configuration rather than running a gateway itself. It models services and routes through fluent builders (ServiceBuilder, RouteBuilder, GatewayConfigBuilder, config.ts), carries per-domain service/route tables (YEMAYA_SERVICES, ISIS_ROUTES, SOPHIA_SERVICES, LILITH_ROUTES, SHARED_ROUTESdomains.ts), and emits Traefik static and dynamic configuration via generateStaticConfig/ generateDynamicConfig/generateTraefikConfigs (traefik.ts), with a cli.ts to render the files. This is the source of truth for which upstream a public route reaches; the runtime backend-for-frontend tier that sits behind it is documented in BFF & Gateway.

Security and identity#

These packages thread through every layer — the BFF authenticates with them, the domain libs authorize with them, the data layer enforces residency with them. This section is the substrate-level view; the unified session/consent/RBAC model is in Auth & Identity.

@oshun/identity is the JWT and authorization core. JwtService (identity/src/jwt.ts:41) mints access/refresh/API-key/service tokens with iss/aud/exp/nbf set, and verifyToken checks expiry, not-before, issuer, and audience explicitly (:222-255) rather than trusting the library default. Authorization is a concrete RBAC model: an eight-rung UserRole hierarchy (guest → user → creator → pro → team → enterprise → admin → super-admin, types.ts:10-31), a PERMISSIONS table of namespaced grants (projects:create, assets:read, generate:image, worlds:publish, knowledge:ingest, admin:users …, types.ts:219), and ROLE_PERMISSIONS mapping each role to its permission set. hasRole, hasPermissions, hasAnyPermission, and getPermissionsForRole (middleware.ts) are the checks; authenticate returns a 403 when a required permission is missing. It also ships mTLS identity (mtls.tsparsePeerCertificate, verifyForwardedClientCert) for service-to-service trust and node:http helpers.

@oshun/auth-primitives is the lower-level credential toolbox @oshun/auth composes: JWT sign/verify with a JWKS model, API keys, OAuth client and token revocation, password hashing/validation with a configurable policy, sessions with device info, refresh-token rotation, tenant isolation, token audit, and TOTP plus backup codes for MFA (auth-primitives/src/totp.ts, password.ts, oauth-revoke.ts, session.ts). @oshun/auth assembles these into an AuthService (auth/src/service.ts) handling registration, login, and refresh — including an AccountLockoutManager (lockout.ts) — over injected repository ports (IUserRepository, ITokenRepository, IAuditRepository). The logic is real; persistence is the caller's to bind, which is what keeps the package domain-agnostic.

@oshun/crypto is the single cryptographic surface, by design: "the only entrypoint internal Oshun code should use" with "zero in-house crypto" (crypto/src/index.ts:5-17). Every primitive delegates to the audited @noble/* libraries — sha256/sha512/keccak256/blake3, secp256k1 sign/verify/recover (with Ethereum-address recovery), ed25519, AES-GCM, ChaCha20-Poly1305, HMAC, the KDF family hkdf/pbkdf2/scrypt/argon2id, ECDH over secp256k1 and x25519, and randomBytes. The single-import discipline means a security audit greps one surface instead of chasing per-domain re-derivations. It also ships pluggable keystore/ (local, AWS KMS, GCP KMS, Azure Key Vault) and secrets/ (local, AWS/GCP/Azure secrets managers) backends behind common interfaces.

@oshun/data-residency decides whether a proposed cross-zone data transfer is allowed. ResidencyEnforcementService (enforcer.ts:144) is an intentionally I/O-light, stateless evaluator: it reads the OSHUN_DATA_RESIDENCY_RULES table from @oshun/contracts (zones eu | uk | us | ca | latam | apac | global, libs/contracts/src/common/data-residency-rules.ts:86), evaluates a transfer against the rule plus any acknowledged mechanism (SCC, IDTA, DPF, explicit consent), and emits a canonical audit event through an injected publisher. enforce() throws ResidencyEnforcementError when outcome.block is true; evaluate() returns the outcome for callers that want to branch. Storage routing (which shard, which pool) lives upstream — the enforcer only renders the verdict. It also ships DSR routing, home-zone resolution from a claim, traffic-shaping, and the residency request headers.

@oshun/deletion-fanout is the shared account-deletion core, scope:shared so any domain can run its own deletion consumer against the bus rather than routing everything through the BFF (deletion-fanout/src/index.ts). It defines the per-service DeletionServiceEraser port over a closed set of erasable scopes (memory_scope, voice_profile, avatar_pack, generated_artifact, personalization_vector, conversation_history, deletion-fanout.ts:23), and — critically — produces an Ed25519-signed DeletionAttestation per service. canonicaliseDeletionAttestation builds unambiguous bytes prefixed oshun.deletion.attestation.v1 (:81-96), the signer signs them with @noble/curves/ed25519, and verifyDeletionAttestation re-derives the canonical bytes and checks the signature. The fan-out is fail-closed: an overall complete is only reported when every service attests, so a partially-completed erasure cannot masquerade as a finished right-to-be-forgotten request. An event-driven orchestrator, a Redis transport, the domain consumer registration, an env-resolved signer, and a runner composition root complete the package.

@oshun/content-security models content provenance and forensic watermarking. As flagged above it is a plan-and-validate layer (v0.1.0): watermarking.ts emits typed WatermarkEmbeddingCommands and robustness test suites for video/audio/image/document; provenance.ts builds C2PA content-credential plans and SynthID watermark plans and tracks a provenance chain. The genuinely computational piece is validateProvenanceChainIntegrity (provenance.ts), which verifies a provenance graph by checking for missing node references, orphan nodes, cycles (detectCycle), and a recomputed integrityDigest over the canonicalized chain — a real graph-integrity validator, not a stubbed true. The byte-level embedding the commands describe is performed by an executor outside this package.

How the foundation connects to everything else#

The shared tree is the bottom of the dependency direction the build enforces, and the connections out of it are deliberate:

  • Up into domain orchestrationlibs/oshun/ composes these packages into product behavior: a domain service logs through @oshun/logging, persists through @oshun/database, emits and consumes through @oshun/event-bus, and authorizes through @oshun/identity. See Domain Orchestration.
  • Sideways into contracts — most shared packages depend on nothing domain-shaped, but @oshun/data-residency and @oshun/deletion-fanout import the @oshun/contracts rule/zone tables, the one allowed reach from infrastructure into the shared vocabulary. See Contracts.
  • Down into persistence@oshun/database and @oshun/cache are the only packages that hold real connections to Postgres/Redis; the residency and deletion machinery layered on top is the subject of Persistence & Data.
  • Through every request@oshun/identity/@oshun/auth at the front, @oshun/http-client's SSRF guard on every outbound call, the observability trio on every hop, and @oshun/crypto wherever a signature or hash is needed.

The nineteen packages above are the layered core. The remaining libs/shared/ packages — @oshun/storage, @oshun/queue, @oshun/websocket, @oshun/rate-limit, @oshun/service-discovery, @oshun/ai/@oshun/ai-advanced, @oshun/ml, @oshun/ocr, @oshun/encoding, @oshun/audit-platform, and others — extend the same floor with the same discipline: real backends, injected boundaries, no domain knowledge, one canonical home. Because they are written once and imported everywhere, a change to how the platform logs, traces, authorizes, or signs is a single edit every product inherits at once — which is the entire point of having a shared foundation rather than nine of them.

  • The Shared Platform — the platform framing and layered model this page fills in.
  • Domain Orchestrationlibs/oshun, the service layer that composes these packages into product capability.
  • Contracts — the Zod vocabulary the privacy packages read and every boundary validates against.
  • BFF & Gateway — the runtime tier behind the gateway config @oshun/traefik-config generates.
  • Persistence & Data@oshun/database/@oshun/cache and the residency, migration, and deletion machinery in depth.
  • Auth & Identity — the unified identity, session, consent, and authorization model @oshun/identity/@oshun/auth underpin.