baukit-core 0.2.1

Dependency-light shared vocabulary for Baukit services.
Documentation

baukit-core

baukit-core holds the handful of types that more than one Baukit crate needs to agree on: deployment environment, log format, process kind, service identity, and build info. It depends on serde and thiserror and nothing else.

Why this crate exists at all

Configuration and telemetry both need to name the environment a process runs in. Left alone, each would define its own Environment enum, and the moment a value crossed between them somebody would write a conversion function that silently mapped an unknown string to a default.

Putting the type in one dependency-light crate solves that without the alternative cost. Telemetry could have owned the vocabulary, but then every configuration-only consumer would inherit the OpenTelemetry exporter stack to learn what production means. baukit-config and baukit-telemetry re-export these types from their own APIs, so products import from the crate they were already using and still get one type.

Environment and log format

DeploymentEnvironment parses and displays as local, testing, staging, or production. An unrecognized name is a ParseEnvironmentError, never a fallback to local.

LogFormat::Auto resolves against the environment: pretty output locally, newline-delimited JSON everywhere else. Pick Json or Pretty explicitly to override.

use baukit_core::{DeploymentEnvironment, LogFormat};

assert_eq!(
    LogFormat::Auto.resolve(DeploymentEnvironment::Production),
    LogFormat::Json,
);

Service identity

ServiceIdentity pairs a product name with a ProcessKind and produces the canonical service name as <product>-<process>:

use baukit_core::{DeploymentEnvironment, ProcessKind, ServiceIdentity};

let identity = ServiceIdentity::new(
    "orders",
    ProcessKind::Api,
    "1.2.3",
    "abc123",
    DeploymentEnvironment::Production,
);

assert_eq!(identity.service_name(), "orders-api");

The API and worker processes of one product are separate services in logs, metrics, and traces, and deriving the name from a shared type is what keeps them from disagreeing. ProcessKind covers Api, Worker, Migrate, and Seed. BuildInfo carries version, commit, and the Rust version used to compile the process; baukit-runtime's build_info! macro fills it from the binary crate's own Cargo metadata.

Scope

No exporters, no async runtime, no HTTP framework, no operational routing. A type earns a place here only when two crates would otherwise define it twice. Everything else belongs in the crate that owns the behavior.