Version: 2.0.0
Date: December 10, 2025
SPDX-License-Identifier: BSD-3-Clause
License File: See the LICENSE file in the project root
Copyright: Β© 2025 Michael Gardner, A Bit of Help, Inc.
Status: Released
Hybrid_Lib_Ada is a professional Ada 2022 library demonstrating hybrid DDD/Clean/Hexagonal architecture with functional error handling.
Key Capabilities:
- 4-layer hexagonal architecture (Domain, Application, Infrastructure, API)
- Functional error handling via Result monad (no exceptions)
- Three-package API pattern for flexible dependency injection
- Generic I/O plugin pattern for platform portability
- Embedded-safe design (no heap allocation, bounded types)
- SPARK-compatible for formal verification
- Cross-platform: Linux, macOS, Windows, Embedded
| Status | |
| Scope | API.Operations generic package (SPARK_Mode On) |
| Mode | gnatprove --mode=prove --level=2 |
| Results | See CHANGELOG for current proof statistics |
make spark-check # Run SPARK legality verification
make spark-prove # Run full SPARK proof verification- β 4-layer hexagonal architecture
- β Result monad error handling (no exceptions across boundaries)
- β Static dependency injection via generics (zero runtime overhead)
- β Three-package API pattern (Operations + Desktop + facade)
- β Generic I/O plugin pattern for platform portability
- β Embedded safety restrictions (no heap allocation)
- β SPARK-compatible design (see SPARK section above)
- β Comprehensive documentation with UML diagrams
- β Test framework (see CHANGELOG)
- β Example programs (basic_greeting, error_handling)
- β Windows CI with GitHub Actions
- β 6 build profiles (standard, concurrent, embedded, baremetal, STM32)
Consumer Application
β
βββββββββββββββββββββββββββββββββββββββββββββββββ
β API LAYER (Public Facade) β
β βββββββββββββββββββ¬βββββββββββββββββββββββββ β
β β API + Operationsβ API.Desktop β β
β β (facade) β (composition root) β β
β β β Wires Infrastructure β β
β β Depends on: β Depends on: β β
β β App + Domain β ALL layers β β
β βββββββββββββββββββ΄βββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββΌββββββββββββββββββββββββ
β INFRASTRUCTURE LAYER β
β Adapters: Console_Writer β
β Depends on: Application + Domain β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββ
β
βββββββββββββββββββββββββΌββββββββββββββββββββββββ
β APPLICATION LAYER β
β Use Cases: Greet | Commands | Ports β
β Depends on: Domain only β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββ
β
βββββββββββββββββββββββββΌββββββββββββββββββββββββ
β DOMAIN LAYER β
β Value Objects: Person | Error: Result monad β
β Depends on: NOTHING (zero dependencies) β
βββββββββββββββββββββββββββββββββββββββββββββββββ
Design Principles:
- Dependencies flow inward (toward Domain)
- Domain layer has zero external dependencies
- Infrastructure implements ports defined in Application
- API facade depends on Application + Domain ONLY (no Infrastructure)
- API.Desktop is a composition root that wires Infrastructure
- Generic I/O plugin pattern enables platform portability
- Static dispatch via generics (zero runtime overhead)
Hybrid_Lib_Ada/
βββ src/
β βββ api/ # Public Interface
β β βββ hybrid_lib_ada-api.ads # Facade: re-exports + Greet operation
β β βββ operations/ # Generic operations (DI pattern)
β β βββ desktop/ # Desktop composition root
β β
β βββ application/ # Use Cases & Ports
β β βββ command/ # Input DTOs (Greet_Command)
β β βββ port/ # Port interfaces (in/out)
β β βββ usecase/ # Use case orchestration (Greet)
β β
β βββ infrastructure/ # Adapters
β β βββ adapter/ # Console_Writer implementation
β β
β βββ domain/ # Pure Business Logic
β β βββ error/ # Error types & Result monad
β β βββ value_object/ # Person value object
β β
β βββ hybrid_lib_ada.ads # Root package
β
βββ examples/ # Example Programs
β βββ basic_greeting.adb # Simple greeting example
β βββ error_handling.adb # Result monad error handling
β
βββ test/ # Test Suite
β βββ unit/ # 99 unit tests
β βββ integration/ # 10 integration tests
β
βββ docs/ # Documentation (submodule)
β βββ formal/ # SRS, SDS, STG
β βββ guides/ # Developer guides
β βββ diagrams/ # UML diagrams
β
βββ config/profiles/ # Build profiles
β βββ standard/ # Desktop/server (default)
β βββ concurrent/ # Multi-threaded server
β βββ embedded/ # Ravenscar embedded
β βββ baremetal/ # Zero footprint (ZFP)
β βββ stm32h7s78/ # STM32H7S78-DK
β βββ stm32mp135_linux/ # STM32MP135F-DK (Linux MPU)
β
βββ hybrid_lib_ada.gpr # Main library project
βββ hybrid_lib_ada_internal.gpr # Internal project (tests + examples)
βββ alire.toml # Alire manifest
βββ Makefile # Build automation
-- 1. API.Operations - Generic operations (SPARK-safe, no Infrastructure)
generic
with function Writer (Message : String) return Unit_Result.Result;
package Hybrid_Lib_Ada.API.Operations is
function Greet (Cmd : Greet_Command) return Unit_Result.Result;
end Hybrid_Lib_Ada.API.Operations;
-- 2. API.Desktop - Desktop composition root (wires Console_Writer)
package Hybrid_Lib_Ada.API.Desktop is
function Greet (Cmd : Greet_Command) return Unit_Result.Result;
end Hybrid_Lib_Ada.API.Desktop;
-- 3. API - Public facade (convenience wrapper)
package Hybrid_Lib_Ada.API is
function Greet (Cmd : Greet_Command) return Unit_Result.Result;
-- Delegates to API.Desktop.Greet
end Hybrid_Lib_Ada.API;Benefits:
- Library users get simple API facade by default
- Advanced users can inject custom I/O adapters via API.Operations
- Zero runtime overhead (compile-time polymorphism)
- SPARK-compatible (API.Operations has SPARK_Mode On)
| Platform | Status | Notes |
|---|---|---|
| Linux | β Full | Fully supported |
| macOS | β Full | Primary development platform |
| BSD | β Full | Fully supported |
| Windows | β Full | Windows 11+ (CI tested) |
| Embedded | π§ Stub | Custom adapter required |
# Add to your project
alr with hybrid_lib_ada
# Or get standalone
alr get hybrid_lib_ada
cd hybrid_lib_ada_*
alr buildgit clone --recurse-submodules https://github.com/abitofhelp/hybrid_lib_ada.git
cd hybrid_lib_ada
alr build- Alire 2.0+ (Ada package manager)
- GNAT 13+ (via Alire toolchain)
- Make (for convenience targets)
with Ada.Text_IO;
with Hybrid_Lib_Ada.API;
procedure My_First_Greeting is
use Ada.Text_IO;
use Hybrid_Lib_Ada.API;
Cmd : constant Greet_Command := Create_Greet_Command ("Alice");
Result : constant Unit_Result.Result := Greet (Cmd);
begin
if Unit_Result.Is_Ok (Result) then
Put_Line ("Greeting succeeded!");
else
declare
Err : constant Error_Type := Unit_Result.Error_Info (Result);
begin
Put_Line ("Error: " & Error_Strings.To_String (Err.Message));
end;
end if;
end My_First_Greeting;Output:
Hello, Alice!
Greeting succeeded!
with Hybrid_Lib_Ada.API;
procedure Error_Example is
use Hybrid_Lib_Ada.API;
-- Empty name triggers validation error
Result : constant Unit_Result.Result :=
Greet (Create_Greet_Command (""));
begin
if Unit_Result.Is_Error (Result) then
declare
Err : constant Error_Type := Unit_Result.Error_Info (Result);
begin
-- Err.Kind = Validation_Error
-- Err.Message = "Name cannot be empty"
end;
end if;
end Error_Example;with Hybrid_Lib_Ada.API.Operations;
with My_Custom_Writer;
procedure Custom_Output is
package My_Ops is new Hybrid_Lib_Ada.API.Operations
(Writer => My_Custom_Writer.Write);
use Hybrid_Lib_Ada.API;
Cmd : constant Greet_Command := Create_Greet_Command ("Bob");
Result : Unit_Result.Result;
begin
Result := My_Ops.Greet (Cmd);
end Custom_Output;| Test Type | Count | Location | Purpose |
|---|---|---|---|
| Unit | 99 | test/unit/ |
Domain & Application logic |
| Integration | 10 | test/integration/ |
Cross-layer interactions |
| Total | 109 | 100% passing |
# Run all tests
make test-all
# Run specific test level
make test-unit
make test-integration
# Code quality
make check-arch # Validate architecture boundaries# Build examples
alr exec -- gprbuild -P examples/examples.gpr
# Run basic greeting
./examples/bin/basic_greeting
# Run error handling demonstration
./examples/bin/error_handling| Profile | Target Platform | RAM | String Limits | Contracts | Debug |
|---|---|---|---|---|---|
standard |
Desktop/Server | 1+ GB | 128/256/512 | Yes | Yes |
concurrent |
Multi-threaded Server | 1+ GB | 128/256/512 | Yes | Yes |
stm32mp135_linux |
STM32MP135F-DK (Linux MPU) | 512 MB | 128/256/512 | Yes | Yes |
embedded |
Ravenscar Embedded | 512KB-1MB | 64/128/256 | Yes | No |
stm32h7s78 |
STM32H7S78-DK | 620KB+32MB | 64/128/256 | Yes | Yes |
baremetal |
Zero Footprint (ZFP) | 128KB-256KB | 32/64/128 | No | No |
# Build with specific profile
alr build -- -XHYBRID_LIB_PROFILE=embedded- π Documentation Index - Complete documentation overview
- π Quick Start Guide - Get started in minutes
- π Software Requirements Specification
- ποΈ Software Design Specification
- π§ͺ Software Test Guide
- π CHANGELOG - Release history
docs/diagrams/library_architecture.svg- 4-layer architecture overviewdocs/diagrams/ada/api_reexport_pattern_ada.svg- Three-package API patterndocs/diagrams/ada/package_structure_ada.svg- Package structuredocs/diagrams/ada/error_handling_flow_ada.svg- Error propagationdocs/diagrams/ada/static_dispatch_ada.svg- Static DI with genericsdocs/diagrams/ada/three_package_api_ada.svg- API composition pattern
| Dependency | Version | Purpose |
|---|---|---|
| functional | ^3.0.0 | Result monad and Option types |
This project uses git submodules for shared tooling:
docs- Shared documentation templates and guidesscripts/python- Build, release, and architecture scriptstest/python- Shared test fixtures and configuration
# After fresh clone
make submodule-init
# Pull latest from submodule repos
make submodule-update
# Check current submodule commits
make submodule-statusThis project follows:
- Ada Agent (
~/.claude/agents/ada.md) - Ada 2022 standards - Architecture Agent (
~/.claude/agents/architecture.md) - DDD/Clean/Hexagonal - Functional Agent (
~/.claude/agents/functional.md) - Result/Option patterns - SPARK Agent (
~/.claude/agents/spark.md) - Formal verification patterns
This project is not open to external contributions at this time.
This project β including its source code, tests, documentation, and other deliverables β is designed, implemented, and maintained by human developers, with Michael Gardner as the Principal Software Engineer and project lead.
We use AI coding assistants (such as OpenAI GPT models and Anthropic Claude Code) as part of the development workflow to help with:
- drafting and refactoring code and tests,
- exploring design and implementation alternatives,
- generating or refining documentation and examples,
- and performing tedious and error-prone chores.
AI systems are treated as tools, not authors. All changes are reviewed, adapted, and integrated by the human maintainers, who remain fully responsible for the architecture, correctness, and licensing of this project.
Copyright Β© 2025 Michael Gardner, A Bit of Help, Inc.
Licensed under the BSD-3-Clause License. See LICENSE for details.
Michael Gardner A Bit of Help, Inc. https://github.com/abitofhelp