# Changelog — einherjar/core All notable changes to this module are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). This module adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). --- ## [1.0.0] — 2026-05-28 ### Added #### `launcher` - `Launcher` interface — `Append`, `BeforeStart`, `Run`, `Shutdown` - `New(logger logging.Logger, opts ...Options) Launcher` — constructs the lifecycle orchestrator; takes `contracts/logging.Logger` (not the concrete `logz` type) - `Hook` type (`func() error`) — assembly-phase callback registered via `BeforeStart` - `Config` struct — `ComponentStopTimeout time.Duration` with `env:"EINHERJAR_COMPONENT_STOP_TIMEOUT" envDefault:"15s"` (`caarlos0/env` syntax) - Startup banner — printed to stdout before any slog output; disabled via `EINHERJAR_BANNER=off` or `EINHERJAR_BANNER=false` - Components accepted as `lifecycle.Component` from `contracts` — not a locally defined interface; any type that satisfies `contracts/lifecycle.Component` is directly compatible #### `logz` - `Config` struct — `Level slog.Level`, `JSON bool`, `StaticArgs []any`, `Writer io.Writer` - `Level` and `JSON` carry `env` and `envDefault` tags (`caarlos0/env` syntax); `StaticArgs` and `Writer` are programmatic-only fields without tags - Env vars: `EINHERJAR_LOG_LEVEL` (default `INFO`), `EINHERJAR_LOG_JSON` (default `false`) - `New(cfg Config) logging.Logger` — returns `contracts/logging.Logger`; the concrete `slogLogger` struct is unexported - Error enrichment — when the error passed to `Logger.Error` satisfies `errs.CodedError` or `errs.ContextualError` (from `contracts/errs`), the corresponding `error_code` field and context key-value pairs are automatically appended to the log record; this replaces the private duck-typed bridge used in micro-lib's `logz` - Context helpers — `WithRequestID`, `GetRequestID`, `WithField`, `WithFields` - `Logger.WithContext(ctx)` — extracts `request_id` and extra fields from context and attaches them to every subsequent log record #### `xerrors` - `Code` type (stable string wire values, gRPC-aligned) - **16 error code constants** — complete gRPC canonical set plus `ErrGone` (HTTP 410) - New over micro-lib: `ErrOutOfRange` (gRPC OUT_OF_RANGE, HTTP 400), `ErrAborted` (gRPC ABORTED, HTTP 409), `ErrDataLoss` (gRPC DATA_LOSS, HTTP 500) - `Code.Description()` — human-readable description for each code - `Err` struct — `code`, `message`, `err` (cause), `fields` (context), `platformCode` - Base constructors: `New(code, message)`, `Wrap(code, message, err)` - **16 convenience constructors** (one per code): `InvalidInput`, `OutOfRange`, `Unauthorized`, `PermissionDenied`, `NotFound`, `AlreadyExists`, `Aborted`, `Gone`, `PreconditionFailed`, `RateLimited`, `Cancelled`, `Internal`, `DataLoss`, `NotImplemented`, `Unavailable`, `DeadlineExceeded` - Builder methods: `WithContext`, `WithError`, `WithPlatformCode` - Accessors: `Code()`, `Message()`, `Fields()`, `PlatformCode()`, `Detailed()` - Standard interfaces: `error`, `Unwrap`, `json.Marshaler` - Compile-time assertions: `var _ errs.CodedError = (*Err)(nil)` and `var _ errs.ContextualError = (*Err)(nil)` — formalises the duck-type bridge from micro-lib into an explicit, verifiable contract #### `valid` - `Validator` interface — `Struct(v any) error` - `New(opts ...Option) Validator` — constructs a validator backed by `go-playground/validator/v10` (backend is hidden; never exposed in the public API) - `MessageProvider` interface — `Message(field, tag, param string) string` - `DefaultMessages` — built-in English message provider - `SpanishMessages` — opt-in Spanish message provider - `Option` type and `WithMessageProvider(mp MessageProvider) Option` - `FieldLevel` interface — passed to custom validator functions; exposes `Field() reflect.Value`, `Param() string`, `FieldName() string`; go-playground backend never visible - `WithCustomValidator(tag string, fn func(FieldLevel) bool) Option` — registers a custom validation tag at construction time; panics on empty or conflicting tag - `OverrideProvider(handlers map[string]func(field, param string) string, base MessageProvider) MessageProvider` — composes a tag→message handler map with a fallback; use for custom tag messages without re-implementing built-ins - **Full built-in tag coverage** in `DefaultMessages` and `SpanishMessages` — all go-playground/validator tags have specific messages (fields, network, strings, format, comparisons, other; ~150 tags total) - Field names in error context prefer the json struct tag, falling back to the Go field name - Error codes: `ErrInvalidInput` for constraint failures, `ErrInternal` for non-struct arguments — both returned as `*xerrors.Err` ### Design Notes 1. **Contracts as the source of truth.** `launcher` accepts `lifecycle.Component` and `logging.Logger` from `contracts`. It does not define its own lifecycle interface. Any type that satisfies the contracts interface is directly compatible — no adapters needed. 2. **Duck typing replaced by explicit interfaces.** micro-lib's `logz` detected enrichable errors via private `errorWithCode`/`errorWithContext` interfaces. `core/logz` detects them via `contracts/errs.CodedError` and `contracts/errs.ContextualError`. The decoupling (logz does not import xerrors) is preserved; the contract is now visible. See [ADR-002](docs/adr/ADR-002-logz-contracts-errs.md). 3. **Complete gRPC error code set.** micro-lib's `xerrors` had 13 codes. `core/xerrors` adds the three missing gRPC codes (`OUT_OF_RANGE`, `ABORTED`, `DATA_LOSS`) and provides a named convenience constructor for every code — `New()` and `Wrap()` are reserved for edge cases. 4. **One module, four sub-packages.** The consolidation eliminates four-way version coordination for a set of packages that always ship and upgrade together. See [ADR-001](docs/adr/ADR-001-core-module-composition.md). 5. **Startup banner.** The launcher prints an ASCII art banner to stdout before any structured log output. It is disabled via `EINHERJAR_BANNER=off`, not via code changes, so production deployments can suppress it without modifying the service. --- [1.0.0]: https://code.nochebuena.dev/einherjar/core/releases/tag/v1.0.0