Disciplines · Reference

API Contracts in the Oshun Monorepo

Oshun employs a hybrid API contract strategy that uses three complementary layers:

9sections9 minread

On this page

This guide documents how API contracts are defined, generated, validated, and consumed across the Oshun platform. Oshun uses a contract-first approach where API interfaces are defined declaratively before implementation, enabling type-safe communication between services, clients, and external partners.

For the architectural rationale behind the hybrid approach, see ADR-0005: API Contract Approach.


Table of Contents#


Overview#

Oshun employs a hybrid API contract strategy that uses three complementary layers:

Layer Package Purpose Format
TypeScript Contracts @oshun/contracts Shared schemas, event definitions, runtime validation Zod schemas + TypeScript
OpenAPI Specifications @oshun/openapi REST API definitions for external clients OpenAPI 3.1 YAML
Protocol Buffers @oshun/proto gRPC service definitions for internal communication Proto3 + buf tooling

The boundary rules are:

  • OpenAPI / REST -- Public APIs, client SDKs, partner integrations, web browser access.
  • Proto / gRPC -- Internal service-to-service communication, GPU worker communication, real-time streaming between services.
  • TypeScript Contracts -- Cross-domain event schemas and common types shared by both REST and gRPC layers within the TypeScript codebase.
text
                ┌─────────────────────────────────────────┐
                │            External Clients              │
                │  (Browsers, Mobile Apps, Partners)       │
                └─────────────────┬───────────────────────┘
                                  │
                       REST/HTTP (OpenAPI)
                                  │
                ┌─────────────────▼───────────────────────┐
                │           API Gateway / BFF              │
                │         (REST → gRPC Translation)        │
                └─────────────────┬───────────────────────┘
                                  │
                        gRPC (Protocol Buffers)
                                  │
     ┌────────────────────────────┼────────────────────────┐
     │                            │                        │
┌────▼────┐                 ┌─────▼─────┐            ┌─────▼─────┐
│  Isis   │                 │  Sophia   │            │  Hathor   │
│ Service │◄───gRPC────────►│  Service  │◄───gRPC───►│  Service  │
└─────────┘                 └───────────┘            └───────────┘

Contract Layers#

TypeScript Contracts (@oshun/contracts)#

Package: libs/contracts/ (@oshun/contracts)

This is the foundational contract layer. It defines Zod schemas for common types, domain events, and validation utilities. All TypeScript services in the monorepo depend on this package for shared type definitions.

Exports:

typescript
import {
  UUIDSchema,
  UserSchema,
  PaginationRequestSchema,
} from '@oshun/contracts';
import { EventEnvelopeSchema, validateEvent } from '@oshun/contracts/events';
import {
  UserProfileSchema,
  CreateUserRequestSchema,
} from '@oshun/contracts/common';

Common schemas (libs/contracts/src/common/):

Module Contents
primitives.ts UUID, Slug, Timestamp, Pagination, Cursor Pagination, Errors, Response Wrappers
user.ts UserSchema, UserProfileSchema, UserPreferencesSchema, CreateUserRequest, etc.
asset.ts AssetSchema, AssetMetadata, CreateAssetRequest
project.ts ProjectSchema, ProjectMember, CreateProjectRequest
audit.ts AuditLogSchema, AuditEntry

Event schemas (libs/contracts/src/events/):

Module Contents
envelope.ts EventEnvelopeSchema, EventMetadataSchema, createEventSchema factory
validation.ts EventSchemaRegistry, validateEvent, validatePayload, validation middleware
isis.ts 9 event types (job lifecycle, asset generated, workflow, model loaded)
sophia.ts 9 event types (document lifecycle, index, search, entity, relation)
hathor.ts 7 event types (world lifecycle, element, narrative, simulation)
bellona.ts 8 event types (session, build lifecycle, export, asset sync)
yemaya.ts 12 event types (project lifecycle, member, asset lifecycle, comments)
lilith.ts 10 event types (meditation, journal, session, progress, teacher, content)
aphrodite.ts 25+ event types (stream, transaction, user, device, chat, moderation)
nyx.ts 20+ event types (catalog, compute, render, realtime)
psyche.ts 20+ event types (session, avatar, voice, memory, persona, conferencing)
veritas.ts 20+ event types (article, claim, story cluster, feed, media, NLP)

The event envelope provides a standardized structure for all domain events:

typescript
// Every event follows this envelope structure
const event: EventEnvelope = {
  id: '550e8400-e29b-41d4-a716-446655440000',
  type: 'isis.job.completed',
  source: 'isis',
  timestamp: '2026-01-15T10:30:00.000Z',
  version: '1.0.0',
  priority: 'normal',
  payload: {
    /* domain-specific */
  },
  metadata: {
    correlationId: 'abc-123',
    traceId: 'trace-456',
    userId: '...',
  },
};

OpenAPI Specifications (@oshun/openapi)#

Package: libs/openapi/ (@oshun/openapi)

This package contains OpenAPI 3.1 YAML specifications for all REST APIs exposed by the platform. Each domain has its own spec file, and the package provides utilities for loading, validating, and querying specifications.

Spec files (libs/openapi/src/specs/):

Domain Spec File Description
Main main.yaml Core platform API (consolidated)
Lilith lilith/lilith-api.yaml Consciousness experience APIs
Yemaya yemaya/yemaya-api.yaml Creative studio APIs
Isis isis/isis-api.yaml Generative factory APIs
Sophia sophia/sophia-api.yaml Knowledge engine APIs
Hathor hathor/hathor-api.yaml Worldbuilding APIs
Bellona bellona/bellona-api.yaml Engine bridge APIs
Nyx nyx/nyx-api.yaml Astronomy APIs

Generated TypeScript types (libs/openapi/src/generated/):

Each spec produces a generated TypeScript file with fully typed paths, operations, and components types:

typescript
// Import generated types for a specific domain
import type { paths as BellonaPaths } from '@oshun/openapi/generated/bellona';
import type { paths as IsisPaths } from '@oshun/openapi/generated/isis';

// Use with openapi-fetch or similar typed HTTP clients
type StartBuildResponse =
  BellonaPaths['/v1/builds']['post']['responses']['201'];

Runtime utilities:

typescript
import {
  loadSpec,
  listSpecs,
  mergeSpecs,
  getSpecsByDomain,
  extractEndpoints,
  extractSchemas,
  SPEC_REGISTRY,
} from '@oshun/openapi';

// Load a spec at runtime
const bellonaSpec = await loadSpec('bellona/bellona-api.yaml');

// List all endpoints in a spec
const endpoints = extractEndpoints(bellonaSpec);

// Get all specs for a domain
const nyxSpecs = getSpecsByDomain('nyx');

Protocol Buffers (@oshun/proto)#

Package: libs/proto/ (@oshun/proto)

This package contains Protocol Buffer definitions for gRPC inter-service communication. It provides .proto files, a type-safe loader, and service metadata.

Proto definitions (libs/proto/src/):

Category Proto Files Services
Common common/types.proto Shared types: UUID, Pagination, Error, RequestContext, Health
Core Services ai/, agent/, asset/, auth/, collaboration/, etc. AIService, AgentService, AssetService, AuthService, etc.
Isis Domain isis/isis.proto IsisJobService, IsisWorkflowService, IsisOutputService, IsisModelService
Sophia Domain sophia/sophia.proto SophiaSearchService, SophiaDocumentService, SophiaCitationService, etc.
Shared Substrates shared/evidence.proto, shared/memory.proto, shared/persona_policy.proto, shared/generation_control.proto OshunEvidenceService, OshunMemoryService, OshunPersonaPolicyService, OshunGenerationControlService
Hathor Domain hathor/hathor.proto HathorWorldService, HathorFactionService, HathorCharacterService, etc.
Rendering & 3D generation3d/, rendering/, splatting/, procedural/ Generation3DService, RenderingService, GaussianSplattingService
Engine Bridges bridge/blender.proto, bridge/godot.proto, bridge/unreal.proto BlenderBridgeService, GodotBridgeService, UnrealBridgeService
Infrastructure health/, loadbalancing/, reflection/, pipeline/ HealthService, LoadBalancingService, ReflectionService

Buf configuration:

  • libs/proto/buf.work.yaml -- Workspace root for the proto module rooted at libs/proto/src/.
  • libs/proto/src/buf.yaml -- Lint rules (DEFAULT + COMMENTS) and breaking change detection (FILE-level). Depends on buf.build/googleapis/googleapis for well-known types.
  • libs/proto/buf.gen.yaml -- Code generation plugins for TypeScript (ts-proto), Go (protoc-gen-go + grpc-go), and JSON Schema.

Loading protos at runtime:

typescript
import {
  loadProto,
  loadAllProtos,
  PROTO_PATHS,
  SERVICE_NAMES,
} from '@oshun/proto';

// Load a specific proto
const isisProto = await loadProto(PROTO_PATHS.isis);

// Load all protos
const allProtos = await loadAllProtos();

// Get service metadata
import { getServiceMetadata } from '@oshun/proto';
const meta = getServiceMetadata(SERVICE_NAMES.IsisJob);
// => { name: 'oshun.isis.IsisJobService', protoPath: 'isis/isis.proto', methods: [...] }

Per-Domain Contract Packages#

Some domains have dedicated contract packages that extend the base @oshun/contracts with domain-specific schemas:

Package Location Description
@psyche/contracts libs/contracts/psyche/ Psyche domain schemas (AI virtual assistant)
@iris/contracts libs/contracts/iris/ Iris domain schemas (voice AI, conversations, memory, agents)

These packages follow the same Zod-based schema pattern but are scoped to their domain:

typescript
import {
  ConversationSchema,
  MessageSchema,
  CreateMessageRequestSchema,
  type Conversation,
  type Message,
} from '@iris/contracts';

// Validate incoming request
const result = CreateMessageRequestSchema.safeParse(req.body);
if (!result.success) {
  throw new ValidationError(result.error.message);
}

Code Generation Workflow#

OpenAPI to TypeScript#

The @oshun/openapi package generates deterministic TypeScript types from YAML specs using the openapi-typescript toolchain. The shared generator also covers the unified Oshun BFF OpenAPI contract at apps/oshun/bff/openapi/oshun-bff.openapi.yaml.

To regenerate types:

bash
# Generate all tracked OpenAPI artifacts
pnpm codegen:openapi

# Verify generated files are current
pnpm codegen:openapi:check

This reads the tracked spec set and produces corresponding TypeScript files in libs/openapi/src/generated/. The generated index.ts re-exports all domain types with namespace aliases:

typescript
// Auto-generated - libs/openapi/src/generated/index.ts
export * as lilith from './lilith.js';
export * as yemaya from './yemaya.js';
export * as isis from './isis.js';
export * as sophia from './sophia.js';
export * as hathor from './hathor.js';
export * as bellona from './bellona.js';
export * as nyx from './nyx.js';
export * as calliope from './calliope.js';
export * as oshunBff from './oshun-bff.js';

Validation:

bash
# Lint OpenAPI specs with Redocly
pnpm nx openapi:validate @oshun/openapi

# Or via package script
cd libs/openapi && pnpm validate

Proto to TypeScript, Go, Python#

The @oshun/proto package uses buf for code generation from .proto files.

To regenerate code and tracked proto artifacts:

bash
# Generate the tracked Buf image snapshot used for drift detection
pnpm codegen:proto

# Generate language-specific outputs from buf.gen.yaml
pnpm proto:generate

# Verify the tracked Buf image snapshot is current
pnpm codegen:proto:check

The tracked proto artifact is libs/proto/generated/buf-image.json, a deterministic Buf image snapshot used to detect contract drift in review and CI. The separate buf.gen.yaml configuration still produces language-specific code in three families:

Plugin Output Directory Language Options
stephenh-ts-proto gen/ts/ TypeScript ES module interop, grpc-js services, string enums
protocolbuffers/go gen/go/ Go Source-relative paths
grpc/go gen/go/ Go gRPC Source-relative paths
chrusty-protoc-gen-jsonschema gen/jsonschema/ JSON Schema All fields required, no additional properties

JSON Schema from Proto#

The buf generation pipeline also produces JSON Schema files from proto definitions. These can be used for validation in non-TypeScript contexts (Python services, API gateways, configuration validators):

bash
# Generated alongside TypeScript and Go output
buf generate  # produces gen/jsonschema/*.schema.json

Prisma Schema Snapshots#

Tracked Prisma datamodels also emit generated SQL snapshots so schema changes cannot land without updating their derived contract artifact.

bash
# Generate all tracked Prisma schema snapshots
pnpm codegen:schema

# Verify the snapshots are current
pnpm codegen:schema:check

Each tracked schema writes an adjacent snapshot at libs/<domain>/database/prisma/generated/schema.sql.

Unified Drift Check#

For CI or pre-merge verification, run the combined contract drift gate:

bash
# Regenerate every tracked contract artifact
pnpm contracts:generate

# Fail if any OpenAPI, proto, or schema artifact drifted
pnpm contracts:check

How to Add a New Contract#

Adding a New Event Contract#

  1. Create the event schema in the appropriate domain file under libs/contracts/src/events/. For example, to add a new Isis event:

    typescript
    // libs/contracts/src/events/isis.ts
    
    // Add the new event payload schema
    export const IsisModelUnloadedPayloadSchema = z.object({
      modelId: UUIDSchema,
      workerId: z.string(),
      reason: z.enum(['manual', 'timeout', 'error', 'preemption']),
      durationMs: z.number().int().nonnegative(),
    });
    
    // Create the typed event schema
    export const IsisModelUnloadedEventSchema = createEventSchema(
      'isis.model.unloaded',
      'isis',
      IsisModelUnloadedPayloadSchema
    );
    
  2. Add the event type constant to the IsisEventTypes object and to the AllEventTypes.isis object in libs/contracts/src/events/index.ts.

  3. Register in the validation registry by adding an entry to EventSchemaRegistry in libs/contracts/src/events/validation.ts:

    typescript
    ['isis.model.unloaded', {
      type: 'isis.model.unloaded',
      source: 'isis',
      schema: IsisModelUnloadedEventSchema,
      payloadSchema: IsisModelUnloadedEventSchema.shape.payload,
      description: 'Model unloaded from worker',
    }],
    
  4. Build and test:

    bash
    pnpm nx test @oshun/contracts
    pnpm nx build @oshun/contracts
    

Adding a New OpenAPI Spec#

  1. Create a YAML spec following OpenAPI 3.1.0 format in the appropriate domain directory:

    yaml
    # libs/openapi/src/specs/mydomain/mydomain-api.yaml
    openapi: 3.1.0
    info:
      title: My Domain API
      version: 1.0.0
      description: Description of the API
    servers:
      - url: https://api.oshun.io/mydomain
        description: Production
      - url: http://localhost:3000
        description: Local Development
    paths:
      /v1/resources:
        get:
          summary: List resources
          operationId: listResources
          # ...
    components:
      schemas:
        Resource:
          type: object
          # ...
      securitySchemes:
        bearerAuth:
          type: http
          scheme: bearer
          bearerFormat: JWT
    
  2. Register in the spec registry (libs/openapi/src/utils/registry.ts):

    typescript
    export const SPEC_PATHS = {
      // ... existing paths
      mydomain: {
        api: 'mydomain/mydomain-api.yaml',
      },
    };
    
    export const SPEC_REGISTRY: Record<string, SpecMetadata> = {
      // ... existing entries
      mydomain: {
        name: 'My Domain API',
        version: '1.0.0',
        description: 'Description of the API',
        specPath: SPEC_PATHS.mydomain.api,
        domain: 'mydomain' as ApiDomain,
        tags: ['mydomain'],
        basePath: '/v1',
      },
    };
    
  3. Add the domain to ApiDomain if it is a new domain.

  4. Regenerate TypeScript types:

    bash
    pnpm nx openapi:gen @oshun/openapi
    
  5. Validate the spec:

    bash
    pnpm nx openapi:validate @oshun/openapi
    

Adding a New Proto Service#

  1. Create a .proto file in the appropriate domain directory:

    protobuf
    // libs/proto/src/mydomain/mydomain.proto
    syntax = "proto3";
    
    package oshun.mydomain;
    
    option go_package = "github.com/oshun/proto/gen/go/mydomain";
    
    import "common/types.proto";
    
    // Service definition
    service MyDomainService {
      // Create a new resource
      rpc CreateResource(CreateResourceRequest) returns (CreateResourceResponse);
      // Get a resource by ID
      rpc GetResource(GetResourceRequest) returns (GetResourceResponse);
      // Stream updates
      rpc StreamUpdates(StreamUpdatesRequest) returns (stream UpdateEvent);
    }
    
    message CreateResourceRequest {
      oshun.common.RequestContext context = 1;
      string name = 2;
      string description = 3;
    }
    
    // ... other messages
    
  2. Register in the loader (libs/proto/src/loader.ts):

    typescript
    export const PROTO_PATHS = {
      // ... existing paths
      mydomain: 'mydomain/mydomain.proto',
    };
    
  3. Register in service metadata (libs/proto/src/services.ts):

    typescript
    export const SERVICE_NAMES = {
      // ... existing names
      MyDomain: 'oshun.mydomain.MyDomainService',
    };
    
  4. Lint and generate:

    bash
    # Lint proto files
    pnpm nx proto:lint @oshun/proto
    
    # Generate code
    pnpm nx proto:gen @oshun/proto
    

Consuming Contracts in Services#

Importing TypeScript Schemas#

All TypeScript services can import schemas directly from @oshun/contracts:

typescript
import {
  // Common types
  UUIDSchema,
  type UUID,
  PaginationRequestSchema,
  type PaginationRequest,
  ErrorCodes,

  // Domain events
  AllEventTypes,

  // Response helpers
  createDataResponseSchema,
  createPaginatedSchema,
} from '@oshun/contracts';

// Validate a request
const paginationResult = PaginationRequestSchema.safeParse(req.query);
if (!paginationResult.success) {
  return res.status(400).json({
    success: false,
    error: {
      code: ErrorCodes.VALIDATION_ERROR,
      message: 'Invalid pagination parameters',
      details: paginationResult.error.issues,
    },
  });
}

// Create a typed paginated response schema
const PaginatedWidgetsSchema = createPaginatedSchema(WidgetSchema);
type PaginatedWidgets = z.infer<typeof PaginatedWidgetsSchema>;

Using Generated OpenAPI Types#

Services that implement REST endpoints can import generated types from @oshun/openapi to ensure their implementations match the spec:

typescript
import type { paths as BellonaPaths } from '@oshun/openapi/generated/bellona';

// Extract request/response types from the OpenAPI spec
type StartBuildRequest =
  BellonaPaths['/v1/builds']['post']['requestBody']['content']['application/json'];
type StartBuildResponse =
  BellonaPaths['/v1/builds']['post']['responses']['201']['content']['application/json'];

// Use in route handlers
app.post(
  '/v1/builds',
  async (
    req: Request<{}, {}, StartBuildRequest>,
    res: Response<StartBuildResponse>
  ) => {
    // Implementation...
  }
);

Using gRPC Clients from Proto#

Internal services use @oshun/proto to create gRPC clients:

typescript
import {
  loadProto,
  PROTO_PATHS,
  SERVICE_NAMES,
  createCredentials,
  DEFAULT_CHANNEL_OPTIONS,
} from '@oshun/proto';

// Load the Isis proto definitions
const isisProto = await loadProto(PROTO_PATHS.isis);

// Create a gRPC client
const credentials = createCredentials(false); // insecure for local dev
const isisJobClient = new isisProto.oshun.isis.IsisJobService(
  'localhost:50051',
  credentials,
  DEFAULT_CHANNEL_OPTIONS
);

// Make an RPC call
isisJobClient.SubmitJob(request, (error, response) => {
  if (error) {
    console.error('gRPC error:', error);
    return;
  }
  console.log('Job submitted:', response);
});

Event Validation#

The contracts package provides a complete event validation system:

typescript
import {
  validateEvent,
  validatePayload,
  validateEventOrThrow,
  isEventTypeRegistered,
  getEventTypesByDomain,
  createValidationMiddleware,
  createPublishValidator,
} from '@oshun/contracts';

// Validate a full event envelope
const result = validateEvent(incomingEvent);
if (!result.success) {
  console.error('Invalid event:', result.errors);
}

// Validate just the payload for a known event type
const payloadResult = validatePayload('isis.job.completed', payload);

// Throw on invalid (for strict mode)
validateEventOrThrow(incomingEvent);

// Create middleware for event processing pipelines
const middleware = createValidationMiddleware({
  strict: true,
  onError: (error, event) => {
    logger.error('Event validation failed', { error, event });
  },
});

// Create a pre-publish validator for event bus
const validator = createPublishValidator({ strict: true, warnOnUnknown: true });
const validatedPayload = validator('isis.job.completed', payload);

Validation and Testing#

Zod Runtime Validation#

All @oshun/contracts schemas use Zod for runtime validation. This means every schema can be used both as a TypeScript type (via z.infer) and as a runtime validator:

typescript
import { UserSchema, type User } from '@oshun/contracts';

// Compile-time type
const user: User = {
  /* ... */
};

// Runtime validation
const result = UserSchema.safeParse(untrustedInput);
if (result.success) {
  // result.data is typed as User
  processUser(result.data);
} else {
  // result.error contains detailed validation issues
  console.error(result.error.issues);
}

OpenAPI Spec Validation#

OpenAPI specs are validated using Redocly CLI:

bash
# Validate all specs
pnpm nx openapi:validate @oshun/openapi

# Validate specific domain specs only
cd libs/openapi && pnpm validate

# Validate all specs including the consolidated main spec
cd libs/openapi && pnpm validate:all

You can also check for breaking changes between spec versions:

bash
# Diff specs against the last committed version
cd libs/openapi && pnpm diff

# Check for breaking changes (exits non-zero if breaking changes found)
cd libs/openapi && pnpm diff:check

Proto Linting and Breaking Change Detection#

Proto files are linted and checked for breaking changes using buf:

bash
# Lint all proto files
pnpm nx proto:lint @oshun/proto

# Or directly via buf
cd libs/proto && buf lint

# Check for breaking changes against the last committed version
cd libs/proto && buf breaking --against '.git#branch=main'

The buf lint configuration enforces:

  • DEFAULT rules (standard protobuf best practices)
  • COMMENTS (all public elements must have comments)
  • enum_zero_value_suffix: _UNSPECIFIED (enum zero values end in _UNSPECIFIED)
  • No same request/response types for different RPCs
  • Google protobuf empty requests/responses are allowed

The breaking change detection uses FILE-level granularity, meaning it detects field renumbering, type changes, and removal of fields or services.

Contract Tests#

The @oshun/contracts package includes a test suite that validates all schemas are well-formed and that the event registry is consistent:

bash
pnpm nx test @oshun/contracts

The test file at libs/contracts/src/contracts.spec.ts covers:

  • All primitive schemas accept valid inputs and reject invalid inputs
  • Event schemas match their registry entries
  • The AllEventTypes constant is consistent with registered schemas
  • Validation functions return correct results for valid and invalid events
  • Middleware and validator factories work correctly

Directory Structure Reference#

text
libs/
├── contracts/                      # @oshun/contracts - TypeScript schemas
│   ├── package.json
│   ├── project.json
│   ├── src/
│   │   ├── index.ts                # Root export (common + events)
│   │   ├── contracts.spec.ts       # Contract tests
│   │   ├── common/
│   │   │   ├── index.ts            # Common schema exports
│   │   │   ├── primitives.ts       # UUID, Slug, Timestamp, Pagination, Errors
│   │   │   ├── user.ts             # User schemas
│   │   │   ├── asset.ts            # Asset schemas
│   │   │   ├── project.ts          # Project schemas
│   │   │   └── audit.ts            # Audit log schemas
│   │   └── events/
│   │       ├── index.ts            # Event export barrel + AllEventTypes
│   │       ├── envelope.ts         # EventEnvelope, EventMetadata, createEventSchema
│   │       ├── validation.ts       # EventSchemaRegistry, validateEvent, middleware
│   │       ├── isis.ts             # Isis domain events
│   │       ├── sophia.ts           # Sophia domain events
│   │       ├── hathor.ts           # Hathor domain events
│   │       ├── bellona.ts          # Bellona domain events
│   │       ├── yemaya.ts           # Yemaya domain events
│   │       ├── lilith.ts           # Lilith domain events
│   │       ├── aphrodite.ts        # Aphrodite domain events
│   │       ├── nyx.ts              # Nyx domain events
│   │       ├── psyche.ts           # Psyche domain events
│   │       └── veritas.ts          # Veritas domain events
│   ├── iris/                       # @iris/contracts - Per-domain package
│   │   ├── package.json
│   │   ├── project.json
│   │   └── src/
│   │       ├── index.ts
│   │       ├── common/
│   │       ├── conversation/
│   │       ├── memory/
│   │       └── agent/
│   ├── psyche/                     # @psyche/contracts - Per-domain package
│   │   ├── package.json
│   │   ├── project.json
│   │   └── src/
│   │       ├── index.ts
│   │       └── common/
│   └── veritas/                    # Veritas contracts (placeholder)
│       └── .gitkeep
│
├── openapi/                        # @oshun/openapi - OpenAPI specifications
│   ├── package.json
│   ├── project.json
│   └── src/
│       ├── index.ts                # Loader + registry exports
│       ├── openapi.spec.ts         # Spec validation tests
│       ├── utils/
│       │   ├── loader.ts           # loadSpec, loadSpecSync, listSpecs, mergeSpecs
│       │   └── registry.ts         # SPEC_PATHS, SPEC_REGISTRY, helper functions
│       ├── specs/                   # OpenAPI 3.1 YAML specifications
│       │   ├── main.yaml
│       │   ├── lilith/lilith-api.yaml
│       │   ├── yemaya/yemaya-api.yaml
│       │   ├── isis/isis-api.yaml
│       │   ├── sophia/sophia-api.yaml
│       │   ├── hathor/hathor-api.yaml
│       │   ├── bellona/bellona-api.yaml
│       │   └── nyx/nyx-api.yaml
│       └── generated/              # Auto-generated TypeScript types
│           ├── index.ts
│           ├── lilith.ts
│           ├── yemaya.ts
│           ├── isis.ts
│           ├── sophia.ts
│           ├── hathor.ts
│           ├── bellona.ts
│           ├── nyx.ts
│           ├── calliope.ts
│           └── oshun-bff.ts
│
└── proto/                          # @oshun/proto - Protocol Buffer definitions
    ├── package.json
    ├── project.json
    ├── buf.work.yaml               # Buf workspace root for src/
    ├── buf.gen.yaml                # Code generation plugins
    ├── generated/
    │   └── buf-image.json          # Deterministic Buf image snapshot
    └── src/
        ├── buf.yaml                # Buf module config + breaking change rules
        ├── index.ts                # Proto loader + service exports
        ├── proto.spec.ts           # Proto loading tests
        ├── loader.ts               # loadProto, loadAllProtos, PROTO_PATHS
        ├── services.ts             # SERVICE_NAMES, getServiceMetadata
        ├── common/types.proto      # Shared types (UUID, Pagination, Error, Health)
        ├── shared/common.proto     # Shared substrate enums + version descriptors
        ├── shared/evidence.proto   # OSHUN grounded evidence substrate
        ├── shared/memory.proto     # OSHUN memory and continuity substrate
        ├── shared/persona_policy.proto
        ├── shared/generation_control.proto
        ├── ai/ai.proto             # AI generation services
        ├── agent/agent.proto       # Agent management
        ├── asset/asset.proto       # Asset management
        ├── auth/auth.proto         # Authentication
        ├── collaboration/collaboration.proto
        ├── project/project.proto
        ├── user/user.proto
        ├── isis/isis.proto         # Isis domain (4 services)
        ├── sophia/sophia.proto     # Sophia domain (5 services)
        ├── hathor/hathor.proto     # Hathor domain (7 services)
        ├── generation3d/generation3d.proto
        ├── rendering/rendering.proto
        ├── splatting/gaussian_splatting.proto
        ├── procedural/procedural.proto
        ├── bridge/blender.proto
        ├── bridge/godot.proto
        ├── bridge/unreal.proto
        ├── health/health.proto
        ├── loadbalancing/loadbalancing.proto
        ├── reflection/reflection.proto
        └── pipeline/autonomous_pipeline.proto

libs/<domain>/database/prisma/
└── generated/
    └── schema.sql                  # Deterministic Prisma schema snapshot

  • ADR-0005: API Contract Approach -- Architectural decision record explaining the hybrid approach
  • ADR-0004: Eventing Strategy -- Event bus and eventing patterns (complements the event contract layer)
  • Cross-Domain Integration -- How domains communicate using contracts
  • OSHUN V1 Subsystem Ownership Matrix (program governance doc, maintained outside this repo) -- Authoritative OSHUN V1 ownership reference
  • OSHUN Metis Subsystem Ownership Matrix (program governance doc, maintained outside this repo) -- Canonical Metis-to-substrate ownership and signoff reference
  • When To Call Which Subsystem Guide (program governance doc, maintained outside this repo) -- Operational call-routing guide for OSHUN V1 subsystem composition
  • OSHUN V1 Program Charter (program governance doc, maintained outside this repo) -- Current OSHUN V1 shell and subsystem ownership boundaries
  • OSHUN Unified Consumer, Admin, and Core Systems PRD (program governance doc, maintained outside this repo) -- Current end-state OSHUN V1 ownership and adapter requirements
  • Data Ownership Matrix (legacy pre-V1 snapshot, no longer tracked in this repo) -- Legacy pre-V1 service/domain ownership snapshot
  • API Authentication -- Authentication flows for REST and gRPC