Cordis StandardSchemaV1 Validation Integration: Complete Implementation Guide

Cordis automatically validates plugin configurations against StandardSchemaV1 schemas at registration time, rejecting invalid configs before the apply hook executes.

Cordis is a meta-framework that enables spatiotemporal composability through a lightweight plugin system, with Cordis StandardSchemaV1 validation integration serving as the foundation for type-safe configuration management. This architecture leverages the @standard-schema/spec package to enforce configuration contracts at the boundary between the framework and plugin code.

How StandardSchemaV1 Validation Works in Cordis

The validation pipeline operates synchronously during plugin registration, ensuring that only type-safe configurations reach plugin instances.

The Validation Pipeline

When ctx.plugin() is invoked, Cordis executes a six-step validation sequence:

  1. Schema Detection – RegistryService inspects the static Config property on the plugin definition (typed as StandardSchemaV1<any, T>)
  2. Config Extraction – The supplied configuration object is extracted from the plugin call arguments
  3. Schema Validation – The schemastery validator (aliased as z) validates the config against the schema
  4. Type Narrowing – Validated data is cast to the TypeScript type parameter T
  5. Fiber Instantiation – A Fiber instance is created with the guaranteed-valid configuration
  6. Error Propagation – Validation failures reject the registration promise with descriptive path-based error messages

Because validation occurs inside RegistryService.plugin() before Fiber construction, the framework guarantees that the apply hook receives only sanitized input.

Core Components

RegistryService (packages/core/src/registry.ts) orchestrates the validation flow. It reads the optional Config field from plugin definitions and delegates validation to the schema engine before creating fiber instances.

Fiber (packages/core/src/fiber.ts) represents the plugin execution context. Its constructor receives the already-validated configuration object, eliminating the need for defensive programming inside plugin logic.

Context (packages/core/src/context.ts) exposes the public plugin() and inject() methods that trigger the validation pipeline in RegistryService.

schemastery (packages/logger-console/src/shared.ts) provides the actual validation implementation, wrapping StandardSchemaV1 methods to perform runtime type checking and coercion.

Implementing Schema Validation in Plugins

Plugin developers define configuration contracts through the static Config property using StandardSchemaV1 builders.

Defining a Plugin Config Schema

Create a schema object that describes required fields, defaults, and formats:

// src/plugins/api-client.ts
import { Context } from 'cordis';
import { StandardSchemaV1 } from '@standard-schema/spec';

export const ApiClientPlugin = {
  Config: StandardSchemaV1.object({
    endpoint: StandardSchemaV1.string()
      .description('Base URL for API requests')
      .format('uri')
      .required(),
    timeout: StandardSchemaV1.number()
      .default(5000)
      .minimum(100)
      .description('Request timeout in milliseconds'),
    retries: StandardSchemaV1.number()
      .integer()
      .default(3),
  }),

  async apply(ctx: Context, config: { endpoint: string; timeout: number; retries: number }) {
    ctx.logger.info(`Connecting to ${config.endpoint}`);
    // Config is guaranteed to match the schema shape
  },
};

export default ApiClientPlugin;

Registering and Validating Plugins

Registration triggers immediate validation. Valid configs proceed to instantiation; invalid configs throw before any side effects occur:

// src/index.ts
import { createApp } from '@cordis/create';
import ApiClientPlugin from './plugins/api-client';

const app = createApp({});

// Validation happens here, before apply() runs
await app.plugin(ApiClientPlugin, {
  endpoint: 'https://api.example.com',
  timeout: 10000,
  retries: 5,
});

await app.start();

Error Handling and Type Safety

When validation fails, RegistryService rejects with a detailed error message specifying the path and constraint violation:


Schema validation error:
 - /endpoint: required string (uri) missing
 - /timeout: number must be >= 100

The TypeScript type system narrows the configuration parameter in the apply method to match the schema's output type, providing IntelliSense and compile-time checking alongside runtime validation.

Core Source Files and Implementation Details

Understanding the source architecture helps debug validation behavior and extend the framework:

Summary

  • Early Validation – Cordis StandardSchemaV1 validation integration catches configuration errors during plugin registration, preventing invalid states from reaching runtime.
  • Type Safety – The Config static property bridges runtime validation with TypeScript's static type system, narrowing config types in the apply method.
  • Centralized Logic – RegistryService in packages/core/src/registry.ts manages all validation orchestration, keeping plugin code free from defensive checks.
  • Standard Schema Compliance – Cordis implements the @standard-schema/spec protocol, ensuring interoperability with ecosystem tools that understand StandardSchemaV1.

Frequently Asked Questions

What is StandardSchemaV1 in the Cordis framework?

StandardSchemaV1 is the validation specification from @standard-schema/spec that Cordis uses to define type-safe configuration schemas for plugins. It provides a fluent API for building validation rules (object shapes, string formats, number ranges) that are enforced at plugin registration time.

How does Cordis handle validation errors?

When a configuration fails validation, RegistryService rejects the promise returned by ctx.plugin() with a Schema validation error message that includes the exact path (e.g., /timeout) and the constraint violation. This prevents the Fiber from being created and stops invalid plugins from starting.

Where is the validation logic implemented in Cordis source code?

The validation orchestration lives in packages/core/src/registry.ts inside the RegistryService class, while the actual schema checking is performed by schemastery wrappers shown in packages/logger-console/src/shared.ts. The Fiber class in packages/core/src/fiber.ts receives the validated output.

Can I compose or reuse schemas across multiple plugins?

Yes. Because StandardSchemaV1 supports schema composition, you can extract common configuration shapes into reusable variables and spread them into plugin Config definitions. The validation engine in Cordis treats composed schemas identically to inline definitions, maintaining full type inference.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →