The Forge Approach

Forge treats configuration as ordinary Python code:

  • Human-readable diffs: Configuration is expressed as Python data models and exported to compact JSON files. Changes are small, reviewable, and meaningful.

  • Full automation: Configuration scripts are plain Python programs. They can be parameterized, composed, and executed in any CI/CD pipeline without special tooling.

  • Reuse through code: Shared settings are extracted into functions, classes, or libraries and imported like any other Python module.

  • Early, strict validation: The Pydantic-based data models enforce types and constraints at assignment time, before any file is written. Additional domain-specific validation rules run as ordinary Python in CI.

  • Clean version control: The Python files are diff-friendly. Merges are straightforward and conflicts are rare.

Core Concepts

Configuration Levels

Forge supports two configuration levels that can be used independently or together:

Level Form Typical use

Low-level (Basic Workflow)

Declarative JSON files validated against JSON Schema

Manually producing configuration without a Python environment

High-level (Comfort Workflow)

Imperative Python code using Pydantic models and facades

Generating, transforming, and validating configuration programmatically

Configuration Domains and Configurable Units

Configuration is organized into configuration domains (for example, Communication or Diagnostics). Each domain groups one or more Configurable Units. A Configurable Unit represents one piece of VES that needs to be configured, such as the ComDaemon or the client libraries inside a user application.

Configurable Units map onto the embedded product design as follows:

  • Configuration Domain → a functional area (e.g. Communication)

    • Integration Component → the top-level deliverable item (e.g. ves-aracom)

      • Subcomponent → combines BSW (Basic Software) libraries (e.g. ComDaemon)

        • Configurable Unit → a subcomponent that is independently configurable (e.g. ComDaemon)

Each Configurable Unit maps to exactly one subcomponent, but not every subcomponent is a Configurable Unit.

A domain is an abstract grouping by functional area, so a single domain can span multiple Integration Components. Because the Integration Component is the deliverable unit, Forge is distributed as one Python package per Integration Component (for example, ves-socom or ves-aracom), rather than one package per domain. Domains are fully independent and carry no cross-domain data model dependencies.

The Three Pillars

Every Configurable Unit’s configuration is split into three pillars based on when the configuration takes effect and what it controls:

  • API: Affects the generated embedded code APIs. Changing API configuration may require rebuilding user code.

  • Implementation: Affects generated implementation details. Changes require a rebuild.

  • Runtime: Controls behavior at runtime without recompilation.

Each pillar is backed by one or more configuration schema classes. When exported, each schema produces one JSON file.

Data Models

A data model (ConfigUnitDataModel) bundles all three pillars for one Configurable Unit. It is the Python representation of the configuration structure (as a Pydantic model). It is also available as a JSON schema for supporting low-level configuration.

Facades

A facade (ConfigUnitFacade) wraps a Configurable Unit data model and provides a higher-level API for configuration tasks: constructing a Configurable Unit with sensible defaults, applying opinionated settings, and exporting the result to JSON. Facades are the primary entry point for users who configure VES programmatically.

Validation

Domain packages register validation rules as plain Python functions. Rules run against the in-memory data model and return findings with a severity level (error or warning). This makes validation portable: it runs in a script, in a test, or in a CI step, without requiring a specialized GUI tool to be installed.

Workflow Overview

For a typical Forge configuration workflow see Workflow overview.